diff --git a/.idea/gradle.xml b/.idea/gradle.xml
index 9d0d2a8..940be6c 100644
--- a/.idea/gradle.xml
+++ b/.idea/gradle.xml
@@ -12,6 +12,7 @@
             <option value="$PROJECT_DIR$" />
             <option value="$PROJECT_DIR$/app" />
             <option value="$PROJECT_DIR$/library" />
+            <option value="$PROJECT_DIR$/togaetherLib" />
           </set>
         </option>
         <option name="resolveModulePerSourceSet" value="false" />
diff --git a/.idea/misc.xml b/.idea/misc.xml
index fafeeed..54da72f 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -72,6 +72,9 @@
         <entry key="..\:/Users/Yul2/AndroidStudioProjects/TOGAETHER/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml" value="0.4345" />
         <entry key="..\:/Users/Yul2/AndroidStudioProjects/TOGAETHER/app/src/main/res/xml/custom_item.xml" value="0.3067708333333333" />
         <entry key="..\:/Users/Yul2/AndroidStudioProjects/TOGAETHER/app/src/main/res/xml/network_security_config.xml" value="0.31302083333333336" />
+        <entry key="..\:/Users/Yul2/AndroidStudioProjects/TOGAETHER/togaetherLib/src/main/res/drawable/cir_shadow.xml" value="0.2865" />
+        <entry key="..\:/Users/Yul2/AndroidStudioProjects/TOGAETHER/togaetherLib/src/main/res/layout/activity_sample.xml" value="0.28229166666666666" />
+        <entry key="..\:/Users/Yul2/AndroidStudioProjects/TOGAETHER/togaetherLib/src/main/res/layout/puppy_view.xml" value="0.28229166666666666" />
       </map>
     </option>
   </component>
diff --git a/app/build.gradle b/app/build.gradle
index 578ea12..0a8fde0 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -55,6 +55,7 @@ dependencies {
     implementation 'io.grpc:grpc-netty-shaded:1.46.0'
     implementation 'io.grpc:grpc-okhttp:1.46.0'
     implementation files('D:\\학교\\2022 1학기\\공소\\commons-net-3.6.jar')
+    implementation 'com.github.dcendents:android-maven-gradle-plugin:2.1'
     testImplementation 'junit:junit:4.13.2'
     androidTestImplementation 'androidx.test.ext:junit:1.1.3'
     androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
diff --git a/app/togaether/.gitignore b/app/togaether/.gitignore
new file mode 100644
index 0000000..42afabf
--- /dev/null
+++ b/app/togaether/.gitignore
@@ -0,0 +1 @@
+/build
\ No newline at end of file
diff --git a/app/togaether/build.gradle b/app/togaether/build.gradle
new file mode 100644
index 0000000..7ab730c
--- /dev/null
+++ b/app/togaether/build.gradle
@@ -0,0 +1,35 @@
+plugins {
+    id 'com.android.library'
+}
+
+android {
+    compileSdk 32
+
+    defaultConfig {
+        minSdk 21
+        targetSdk 32
+
+        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
+        consumerProguardFiles "consumer-rules.pro"
+    }
+
+    buildTypes {
+        release {
+            minifyEnabled false
+            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
+        }
+    }
+    compileOptions {
+        sourceCompatibility JavaVersion.VERSION_1_8
+        targetCompatibility JavaVersion.VERSION_1_8
+    }
+}
+
+dependencies {
+
+    implementation 'androidx.appcompat:appcompat:1.4.2'
+    implementation 'com.google.android.material:material:1.6.1'
+    testImplementation 'junit:junit:4.13.2'
+    androidTestImplementation 'androidx.test.ext:junit:1.1.3'
+    androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
+}
\ No newline at end of file
diff --git a/app/togaether/consumer-rules.pro b/app/togaether/consumer-rules.pro
new file mode 100644
index 0000000..e69de29
diff --git a/app/togaether/proguard-rules.pro b/app/togaether/proguard-rules.pro
new file mode 100644
index 0000000..481bb43
--- /dev/null
+++ b/app/togaether/proguard-rules.pro
@@ -0,0 +1,21 @@
+# Add project specific ProGuard rules here.
+# You can control the set of applied configuration files using the
+# proguardFiles setting in build.gradle.
+#
+# For more details, see
+#   http://developer.android.com/guide/developing/tools/proguard.html
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+#   public *;
+#}
+
+# Uncomment this to preserve the line number information for
+# debugging stack traces.
+#-keepattributes SourceFile,LineNumberTable
+
+# If you keep the line number information, uncomment this to
+# hide the original source file name.
+#-renamesourcefileattribute SourceFile
\ No newline at end of file
diff --git a/app/togaether/src/androidTest/java/com/example/togaether/ExampleInstrumentedTest.java b/app/togaether/src/androidTest/java/com/example/togaether/ExampleInstrumentedTest.java
new file mode 100644
index 0000000..1fb6eff
--- /dev/null
+++ b/app/togaether/src/androidTest/java/com/example/togaether/ExampleInstrumentedTest.java
@@ -0,0 +1,26 @@
+package com.example.togaether;
+
+import android.content.Context;
+
+import androidx.test.platform.app.InstrumentationRegistry;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import static org.junit.Assert.*;
+
+/**
+ * Instrumented test, which will execute on an Android device.
+ *
+ * @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
+ */
+@RunWith(AndroidJUnit4.class)
+public class ExampleInstrumentedTest {
+    @Test
+    public void useAppContext() {
+        // Context of the app under test.
+        Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
+        assertEquals("com.example.togaether.test", appContext.getPackageName());
+    }
+}
\ No newline at end of file
diff --git a/app/togaether/src/main/AndroidManifest.xml b/app/togaether/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..02da19c
--- /dev/null
+++ b/app/togaether/src/main/AndroidManifest.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.example.togaether">
+
+</manifest>
\ No newline at end of file
diff --git a/app/togaether/src/test/java/com/example/togaether/ExampleUnitTest.java b/app/togaether/src/test/java/com/example/togaether/ExampleUnitTest.java
new file mode 100644
index 0000000..0d7f5b5
--- /dev/null
+++ b/app/togaether/src/test/java/com/example/togaether/ExampleUnitTest.java
@@ -0,0 +1,17 @@
+package com.example.togaether;
+
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+/**
+ * Example local unit test, which will execute on the development machine (host).
+ *
+ * @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
+ */
+public class ExampleUnitTest {
+    @Test
+    public void addition_isCorrect() {
+        assertEquals(4, 2 + 2);
+    }
+}
\ No newline at end of file
diff --git a/settings.gradle b/settings.gradle
index ffac50d..697e9b1 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -15,3 +15,4 @@ dependencyResolutionManagement {
 rootProject.name = "TOGAETHER"
 include ':app'
 include ':library'
+include ':togaetherLib'
diff --git a/togaetherLib/.gitignore b/togaetherLib/.gitignore
new file mode 100644
index 0000000..42afabf
--- /dev/null
+++ b/togaetherLib/.gitignore
@@ -0,0 +1 @@
+/build
\ No newline at end of file
diff --git a/togaetherLib/build.gradle b/togaetherLib/build.gradle
new file mode 100644
index 0000000..4b0812d
--- /dev/null
+++ b/togaetherLib/build.gradle
@@ -0,0 +1,43 @@
+apply plugin: 'com.github.dcendents.android-maven'
+group='com.github.Yuls2'
+
+plugins {
+    id 'com.android.library'
+}
+
+android {
+    compileSdk 32
+
+    defaultConfig {
+        minSdk 21
+        targetSdk 32
+
+        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
+        consumerProguardFiles "consumer-rules.pro"
+    }
+
+    buildTypes {
+        release {
+            minifyEnabled false
+            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
+        }
+    }
+    compileOptions {
+        sourceCompatibility JavaVersion.VERSION_1_8
+        targetCompatibility JavaVersion.VERSION_1_8
+    }
+}
+
+dependencies {
+
+    implementation 'androidx.appcompat:appcompat:1.4.2'
+    implementation 'com.google.android.material:material:1.6.1'
+    implementation 'com.squareup.retrofit2:retrofit:2.9.0'
+    implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
+    implementation 'com.github.bumptech.glide:glide:4.13.2'
+    implementation 'jp.wasabeef:glide-transformations:4.3.0'
+    implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
+    testImplementation 'junit:junit:4.13.2'
+    androidTestImplementation 'androidx.test.ext:junit:1.1.3'
+    androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
+}
\ No newline at end of file
diff --git a/togaetherLib/consumer-rules.pro b/togaetherLib/consumer-rules.pro
new file mode 100644
index 0000000..e69de29
diff --git a/togaetherLib/proguard-rules.pro b/togaetherLib/proguard-rules.pro
new file mode 100644
index 0000000..481bb43
--- /dev/null
+++ b/togaetherLib/proguard-rules.pro
@@ -0,0 +1,21 @@
+# Add project specific ProGuard rules here.
+# You can control the set of applied configuration files using the
+# proguardFiles setting in build.gradle.
+#
+# For more details, see
+#   http://developer.android.com/guide/developing/tools/proguard.html
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+#   public *;
+#}
+
+# Uncomment this to preserve the line number information for
+# debugging stack traces.
+#-keepattributes SourceFile,LineNumberTable
+
+# If you keep the line number information, uncomment this to
+# hide the original source file name.
+#-renamesourcefileattribute SourceFile
\ No newline at end of file
diff --git a/togaetherLib/src/androidTest/java/com/example/togaetherlib/ExampleInstrumentedTest.java b/togaetherLib/src/androidTest/java/com/example/togaetherlib/ExampleInstrumentedTest.java
new file mode 100644
index 0000000..0433330
--- /dev/null
+++ b/togaetherLib/src/androidTest/java/com/example/togaetherlib/ExampleInstrumentedTest.java
@@ -0,0 +1,26 @@
+package com.example.togaetherlib;
+
+import android.content.Context;
+
+import androidx.test.platform.app.InstrumentationRegistry;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import static org.junit.Assert.*;
+
+/**
+ * Instrumented test, which will execute on an Android device.
+ *
+ * @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
+ */
+@RunWith(AndroidJUnit4.class)
+public class ExampleInstrumentedTest {
+    @Test
+    public void useAppContext() {
+        // Context of the app under test.
+        Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
+        assertEquals("com.example.togaetherlib.test", appContext.getPackageName());
+    }
+}
\ No newline at end of file
diff --git a/togaetherLib/src/main/AndroidManifest.xml b/togaetherLib/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..4809586
--- /dev/null
+++ b/togaetherLib/src/main/AndroidManifest.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.example.togaetherlib">
+
+
+</manifest>
\ No newline at end of file
diff --git a/togaetherLib/src/main/java/com/example/togaetherlib/CustomType.java b/togaetherLib/src/main/java/com/example/togaetherlib/CustomType.java
new file mode 100644
index 0000000..36e6f8d
--- /dev/null
+++ b/togaetherLib/src/main/java/com/example/togaetherlib/CustomType.java
@@ -0,0 +1,6 @@
+package com.example.togaetherlib;
+//FACE2: 입 주변 털 등
+//FACE3: 무늬
+public enum CustomType {
+    EAR_L, EAR_R, EYE_L, EYE_R, EYEBROW_L, EYEBROW_R, FACE1, FACE2, FACE3, MOUTH, NOSE, BODY
+}
diff --git a/togaetherLib/src/main/java/com/example/togaetherlib/MaskTransformation2.java b/togaetherLib/src/main/java/com/example/togaetherlib/MaskTransformation2.java
new file mode 100644
index 0000000..4de98ba
--- /dev/null
+++ b/togaetherLib/src/main/java/com/example/togaetherlib/MaskTransformation2.java
@@ -0,0 +1,66 @@
+package com.example.togaetherlib;
+
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.graphics.PorterDuff;
+import android.graphics.PorterDuffXfermode;
+import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.Drawable;
+
+import androidx.annotation.NonNull;
+
+import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool;
+
+import jp.wasabeef.glide.transformations.MaskTransformation;
+
+public class MaskTransformation2 extends MaskTransformation {
+    private static final Paint paint = new Paint();
+
+    static {
+        paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
+    }
+    Drawable maskD;
+    Bitmap maskB;
+    /**
+     * @param maskId If you change the mask file, please also rename the mask file, or Glide will get
+     *               the cache with the old mask. Because key() return the same values if using the
+     *               same make file name. If you have a good idea please tell us, thanks.
+     */
+    public MaskTransformation2(int maskId) {
+        super(maskId);
+    }
+
+    public MaskTransformation2(Drawable maskD) {
+        super(0);
+        this.maskD = maskD;
+    }
+
+    public MaskTransformation2(Context con, Bitmap maskB) {
+        super(0);
+        this.maskB = maskB;
+        maskD = new BitmapDrawable(con.getResources(), maskB);
+    }
+
+    protected Bitmap transform(@NonNull Context context, @NonNull BitmapPool pool,
+                               @NonNull Bitmap toTransform, int outWidth, int outHeight) {
+        int width = toTransform.getWidth();
+        int height = toTransform.getHeight();
+
+        Bitmap bitmap = pool.get(width, height, Bitmap.Config.ARGB_8888);
+        bitmap.setHasAlpha(true);
+
+        Drawable mask = maskD;
+
+        bitmap.setDensity(toTransform.getDensity());
+
+        Canvas canvas = new Canvas(bitmap);
+        mask.setBounds(0, 0, width, height);
+        mask.draw(canvas);
+        canvas.drawBitmap(toTransform, 0, 0, paint);
+
+        return bitmap;
+    }
+
+}
diff --git a/togaetherLib/src/main/java/com/example/togaetherlib/PuppyInfoItem.java b/togaetherLib/src/main/java/com/example/togaetherlib/PuppyInfoItem.java
new file mode 100644
index 0000000..f22f8a0
--- /dev/null
+++ b/togaetherLib/src/main/java/com/example/togaetherlib/PuppyInfoItem.java
@@ -0,0 +1,162 @@
+package com.example.togaetherlib;
+
+import android.os.Build;
+
+import androidx.annotation.RequiresApi;
+
+import com.google.gson.annotations.SerializedName;
+
+import java.time.LocalDate;
+import java.time.format.DateTimeFormatter;
+
+public class PuppyInfoItem {
+    @SerializedName("pid")
+    private int pid;
+    @SerializedName("uid")
+    private String uid;
+    @SerializedName("pname")
+    private String pname;
+    @SerializedName("psex")
+    private String psex;
+    @SerializedName("pcall")
+    private String pcall;
+    @SerializedName("pbdate")
+    private String pbdate;
+    @SerializedName("pshare")
+    private int pshare;
+    @SerializedName("pcustom")
+    private PuppyItem pcustom;
+    //visit info
+    @SerializedName("visit")
+    private boolean visit;
+    @SerializedName("vpid")
+    private int vpid;
+    @SerializedName("vname")
+    private String vname;
+    //more info
+    @SerializedName("uname")
+    private String uname;
+    @SerializedName("isFriend")
+    private boolean friend;
+
+    public PuppyInfoItem(int pid, String uid, String pname, String psex, String pcall, String pbdate, int pshare, PuppyItem pcustom, boolean visit, int vpid) {
+        this.pid = pid;
+        this.uid = uid;
+        this.pname = pname;
+        this.psex = psex;
+        this.pcall = pcall;
+        this.pbdate = pbdate;
+        this.pshare = pshare;
+        this.pcustom = pcustom;
+        this.visit = visit;
+        this.vpid = vpid;
+    }
+
+    public int getPid() {
+        return pid;
+    }
+
+    public void setPid(int pid) {
+        this.pid = pid;
+    }
+
+    public String getUid() {
+        return uid;
+    }
+
+    public void setUid(String uid) {
+        this.uid = uid;
+    }
+
+    public String getPname() {
+        return pname;
+    }
+
+    public void setPname(String pname) {
+        this.pname = pname;
+    }
+
+    public String getPsex() {
+        return psex;
+    }
+
+    public void setPsex(String psex) {
+        this.psex = psex;
+    }
+
+    public String getPcall() {
+        return pcall;
+    }
+
+    public void setPcall(String pcall) {
+        this.pcall = pcall;
+    }
+
+    @RequiresApi(api = Build.VERSION_CODES.O)
+    public LocalDate getPbdate() {
+        LocalDate bdate = LocalDate.parse(pbdate, DateTimeFormatter.ISO_DATE);
+        return bdate;
+    }
+
+    public void setPbdate(String pbdate) {
+        this.pbdate = pbdate;
+    }
+
+    public int getPshare() {
+        return pshare;
+    }
+
+    public void setPshare(int pshare) {
+        this.pshare = pshare;
+    }
+
+    public PuppyItem getPcustom() {
+        return pcustom;
+    }
+
+    public void setPcustom(PuppyItem pcustom) {
+        this.pcustom = pcustom;
+    }
+
+    // visit info
+
+    public boolean isVisit() {
+        return visit;
+    }
+
+    public void setVisit(boolean visit) {
+        this.visit = visit;
+    }
+
+    public int getVpid() {
+        return vpid;
+    }
+
+    public void setVpid(int vpid) {
+        this.vpid = vpid;
+    }
+
+    public String getVname() {
+        return vname;
+    }
+
+    public void setVname(String vname) {
+        this.vname = vname;
+    }
+
+    public String getUname() {
+        return uname;
+    }
+
+    public void setUname(String uname) {
+        this.uname = uname;
+    }
+
+    public boolean isFriend() {
+        return friend;
+    }
+
+    public void setFriend(boolean friend) {
+        this.friend = friend;
+    }
+}
diff --git a/togaetherLib/src/main/java/com/example/togaetherlib/PuppyItem.java b/togaetherLib/src/main/java/com/example/togaetherlib/PuppyItem.java
new file mode 100644
index 0000000..8fdbfeb
--- /dev/null
+++ b/togaetherLib/src/main/java/com/example/togaetherlib/PuppyItem.java
@@ -0,0 +1,141 @@
+package com.example.togaetherlib;
+
+import com.google.gson.annotations.SerializedName;
+
+public class PuppyItem {
+    @SerializedName("FACE1")
+    private PuppyPartItem face1;
+    @SerializedName("FACE2")
+    private PuppyPartItem face2;
+    @SerializedName("FACE3")
+    private PuppyPartItem face3;
+    @SerializedName("BODY")
+    private PuppyPartItem body;
+    @SerializedName("MOUTH")
+    private PuppyPartItem mouth;
+    @SerializedName("NOSE")
+    private PuppyPartItem nose;
+    @SerializedName("EAR_L")
+    private PuppyPartItem ear_l;
+    @SerializedName("EAR_R")
+    private PuppyPartItem ear_r;
+    @SerializedName("EYE_L")
+    private PuppyPartItem eye_l;
+    @SerializedName("EYE_R")
+    private PuppyPartItem eye_r;
+    @SerializedName("EYEBROW_L")
+    private PuppyPartItem eyebrow_l;
+    @SerializedName("EYEBROW_R")
+    private PuppyPartItem eyebrow_r;
+
+    public PuppyItem(PuppyPartItem face1, PuppyPartItem face2, PuppyPartItem face3, PuppyPartItem body, PuppyPartItem mouth, PuppyPartItem nose, PuppyPartItem ear_l, PuppyPartItem ear_r, PuppyPartItem eye_l, PuppyPartItem eye_r, PuppyPartItem eyebrow_l, PuppyPartItem eyebrow_r) {
+        this.face1 = face1;
+        this.face2 = face2;
+        this.face3 = face3;
+        this.body = body;
+        this.mouth = mouth;
+        this.nose = nose;
+        this.ear_l = ear_l;
+        this.ear_r = ear_r;
+        this.eye_l = eye_l;
+        this.eye_r = eye_r;
+        this.eyebrow_l = eyebrow_l;
+        this.eyebrow_r = eyebrow_r;
+    }
+
+    public PuppyPartItem getBody() {
+        return body;
+    }
+
+    public PuppyPartItem getEar_l() {
+        return ear_l;
+    }
+
+    public PuppyPartItem getEar_r() {
+        return ear_r;
+    }
+
+    public PuppyPartItem getEye_l() {
+        return eye_l;
+    }
+
+    public PuppyPartItem getEye_r() {
+        return eye_r;
+    }
+
+    public PuppyPartItem getEyebrow_l() {
+        return eyebrow_l;
+    }
+
+    public PuppyPartItem getEyebrow_r() {
+        return eyebrow_r;
+    }
+
+    public PuppyPartItem getFace1() {
+        return face1;
+    }
+
+    public PuppyPartItem getFace2() {
+        return face2;
+    }
+
+    public PuppyPartItem getFace3() {
+        return face3;
+    }
+
+    public PuppyPartItem getMouth() {
+        return mouth;
+    }
+
+    public PuppyPartItem getNose() {
+        return nose;
+    }
+
+    public void setBody(PuppyPartItem body) {
+        this.body = body;
+    }
+
+    public void setEar_l(PuppyPartItem ear_l) {
+        this.ear_l = ear_l;
+    }
+
+    public void setEar_r(PuppyPartItem ear_r) {
+        this.ear_r = ear_r;
+    }
+
+    public void setEye_l(PuppyPartItem eye_l) {
+        this.eye_l = eye_l;
+    }
+
+    public void setEye_r(PuppyPartItem eye_r) {
+        this.eye_r = eye_r;
+    }
+
+    public void setEyebrow_l(PuppyPartItem eyebrow_l) {
+        this.eyebrow_l = eyebrow_l;
+    }
+
+    public void setEyebrow_r(PuppyPartItem eyebrow_r) {
+        this.eyebrow_r = eyebrow_r;
+    }
+
+    public void setFace1(PuppyPartItem face1) {
+        this.face1 = face1;
+    }
+
+    public void setFace2(PuppyPartItem face2) {
+        this.face2 = face2;
+    }
+
+    public void setFace3(PuppyPartItem face3) {
+        this.face3 = face3;
+    }
+
+    public void setMouth(PuppyPartItem mouth) {
+        this.mouth = mouth;
+    }
+
+    public void setNose(PuppyPartItem nose) {
+        this.nose = nose;
+    }
+}
diff --git a/togaetherLib/src/main/java/com/example/togaetherlib/PuppyPartItem.java b/togaetherLib/src/main/java/com/example/togaetherlib/PuppyPartItem.java
new file mode 100644
index 0000000..1432165
--- /dev/null
+++ b/togaetherLib/src/main/java/com/example/togaetherlib/PuppyPartItem.java
@@ -0,0 +1,64 @@
+package com.example.togaetherlib;
+
+import com.google.gson.annotations.SerializedName;
+
+public class PuppyPartItem {
+    @SerializedName("source")
+    private String source;
+    @SerializedName("dy")
+    private int dy;
+    @SerializedName("dist")
+    private int dist;
+    @SerializedName("size")
+    private int size;
+    @SerializedName("color")
+    private int color;
+
+    public PuppyPartItem(String source, int dy, int dist, int size, int color) {
+        this.source = source;
+        this.dy = dy;
+        this.dist = dist;
+        this.size = size;
+        this.color = color;
+    }
+
+    public void setColor(int color) {
+        this.color = color;
+    }
+
+    public void setDist(int dist) {
+        this.dist = dist;
+    }
+
+    public void setDy(int dy) {
+        this.dy = dy;
+    }
+
+    public void setSize(int size) {
+        this.size = size;
+    }
+
+    public void setSource(String source) {
+        this.source = source;
+    }
+
+    public int getColor() {
+        return color;
+    }
+
+    public int getDist() {
+        return dist;
+    }
+
+    public int getDy() {
+        return dy;
+    }
+
+    public int getSize() {
+        return size;
+    }
+
+    public String getSource() {
+        return source;
+    }
+}
diff --git a/togaetherLib/src/main/java/com/example/togaetherlib/PuppyView.java b/togaetherLib/src/main/java/com/example/togaetherlib/PuppyView.java
new file mode 100644
index 0000000..0cfd3b0
--- /dev/null
+++ b/togaetherLib/src/main/java/com/example/togaetherlib/PuppyView.java
@@ -0,0 +1,559 @@
+package com.example.togaetherlib;
+
+import static com.bumptech.glide.request.RequestOptions.bitmapTransform;
+
+import android.animation.ValueAnimator;
+import android.content.Context;
+import android.content.Intent;
+import android.graphics.Bitmap;
+import android.graphics.Color;
+import android.graphics.PorterDuff;
+import android.graphics.drawable.Drawable;
+import android.util.Log;
+import android.util.TypedValue;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.ViewTreeObserver;
+import android.widget.ImageView;
+import android.widget.ProgressBar;
+
+import androidx.annotation.Nullable;
+import androidx.appcompat.app.AppCompatActivity;
+
+import com.bumptech.glide.Glide;
+import com.bumptech.glide.load.DataSource;
+import com.bumptech.glide.load.MultiTransformation;
+import com.bumptech.glide.load.engine.DiskCacheStrategy;
+import com.bumptech.glide.load.engine.GlideException;
+import com.bumptech.glide.load.resource.bitmap.CenterCrop;
+import com.bumptech.glide.request.RequestListener;
+import com.bumptech.glide.request.target.Target;
+
+import java.time.LocalDate;
+import java.util.HashMap;
+import java.util.Random;
+
+import retrofit2.Call;
+import retrofit2.Callback;
+import retrofit2.Response;
+import retrofit2.Retrofit;
+import retrofit2.converter.gson.GsonConverterFactory;
+
+public class PuppyView {
+    LayoutInflater layoutInflater;
+    AppCompatActivity act;
+    View puppyView, puppy, vShadow, puppyOnly;
+    ProgressBar pgPuppy;
+
+    HashMap<CustomType, ImageView> imgMap = new HashMap<>();
+    ImageView eyeWL, eyeWR;
+    HashMap<CustomType, PartXY> xyMap = new HashMap<>();
+    HashMap<CustomType, Integer> dyMap = new HashMap<>();
+    HashMap<CustomType, Integer> distMap = new HashMap<>();
+    HashMap<CustomType, Integer> sizeMap = new HashMap<>();
+    HashMap<CustomType, Integer> colorMap = new HashMap<>();
+    HashMap<CustomType, String> sourceMap = new HashMap<>();
+    int w, h;
+    int oriS;
+    ViewGroup lay;
+    boolean isSleep = false;
+
+
+    private String name, callString, sex, uid;
+    private int id;
+    private LocalDate bdate;
+
+    public int getId() {
+        return id;
+    }
+
+    public void setId(int id) {
+        this.id = id;
+    }
+
+    public LocalDate getBdate() {
+        return bdate;
+    }
+    public void setBdate(LocalDate bdate) {
+        this.bdate = bdate;
+    }
+    public String getCallString() {
+        return callString;
+    }
+    public void setCallString(String callString) {
+        this.callString = callString;
+    }
+    public String getSex() {
+        return sex;
+    }
+    public void setSex(String sex) {
+        this.sex = sex;
+    }
+    public String getUid() {
+        return uid;
+    }
+    public void setUid(String uid) {
+        this.uid = uid;
+    }
+    public String getName() {
+        return name;
+    }
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    PuppyView(ViewGroup lay, AppCompatActivity act) {
+        setInit(lay, act, 1);
+        setInitCustom();
+        pgPuppy.setVisibility(View.GONE);
+    }
+
+    PuppyView(ViewGroup lay, AppCompatActivity act, int id) {
+        setInit(lay, act, 1);
+        setId(id);
+        setInitCustom(id);
+    }
+
+    PuppyView(ViewGroup lay, AppCompatActivity act, PuppyItem item, float scale) {
+        setInit(lay, act, scale);
+        setInitCustom(item);
+    }
+
+    PuppyView(ViewGroup lay, AppCompatActivity act, PuppyInfoItem item, float scale) {
+        setInit(lay, act, scale);
+        setName(item.getPname());
+        setCallString(item.getPcall());
+        setSex(item.getPsex());
+        setUid(item.getUid());
+        setBdate(item.getPbdate());
+        setId(item.getPid());
+        setInitCustom(item.getPcustom());
+    }
+
+    PuppyView(ViewGroup lay, AppCompatActivity act, PuppyInfoItem item) {
+        this(lay, act, item, 1);
+    }
+
+    PuppyView(ViewGroup lay, AppCompatActivity act, PuppyItem item) {
+        this(lay, act, item, 1);
+    }
+
+
+    public void setInit(ViewGroup lay, AppCompatActivity act, float scale) {
+        this.lay = lay;
+        this.act = act;
+        layoutInflater = (LayoutInflater) act.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+        puppyView = (View) layoutInflater.inflate(R.layout.puppy_view, lay, false);
+        lay.addView(puppyView);
+        puppy = puppyView.findViewById(R.id.lay_puppy);
+        puppyOnly = puppy.findViewById(R.id.lay_puppy_only);
+        pgPuppy = puppy.findViewById(R.id.pg_puppy);
+
+        puppy.setScaleX(scale);
+        puppy.setScaleY(scale);
+
+        oriS = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 100, act.getResources().getDisplayMetrics());
+
+        imgMap.put(CustomType.FACE1,(ImageView) puppy.findViewById(R.id.img_face1));
+        imgMap.put(CustomType.FACE2,(ImageView) puppy.findViewById(R.id.img_face2));
+        imgMap.put(CustomType.FACE3,(ImageView) puppy.findViewById(R.id.img_face3));
+        imgMap.put(CustomType.BODY,(ImageView) puppy.findViewById(R.id.img_body));
+        imgMap.put(CustomType.MOUTH,(ImageView) puppy.findViewById(R.id.img_mouth));
+        imgMap.put(CustomType.NOSE,(ImageView) puppy.findViewById(R.id.img_nose));
+        imgMap.put(CustomType.EAR_L,(ImageView) puppy.findViewById(R.id.img_ear_left));
+        imgMap.put(CustomType.EAR_R,(ImageView) puppy.findViewById(R.id.img_ear_right));
+        imgMap.put(CustomType.EYE_L,(ImageView) puppy.findViewById(R.id.img_eye_left));
+        imgMap.put(CustomType.EYE_R,(ImageView) puppy.findViewById(R.id.img_eye_right));
+        imgMap.put(CustomType.EYEBROW_L,(ImageView) puppy.findViewById(R.id.img_eyebrow_left));
+        imgMap.put(CustomType.EYEBROW_R,(ImageView) puppy.findViewById(R.id.img_eyebrow_right));
+        vShadow = (View) puppy.findViewById(R.id.v_shadow);
+        eyeWL = (ImageView) puppy.findViewById(R.id.img_eyew_left);
+        eyeWR = (ImageView) puppy.findViewById(R.id.img_eyew_right);
+
+        for(CustomType t: CustomType.values()) {
+            ImageView targetView = imgMap.get(t);
+            xyMap.put(t,new PartXY(targetView.getX(),targetView.getY()));
+        }
+
+        puppy.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
+            @Override
+            public void onGlobalLayout() {
+                w = puppy.getWidth();
+                h = puppy.getHeight();
+                //oriS = imgMap.get(CustomType.FACE1).getWidth();
+                puppy.setTranslationX(puppy.getX() - w/2);
+                puppy.setTranslationY(puppy.getY() - h/2);
+                puppy.setPivotX((float) w/2);
+                puppy.setPivotY((float) h*3/4);
+
+                final ValueAnimator bubbleAnim = ValueAnimator.ofFloat(-0.25f, 0.25f);
+                bubbleAnim.setDuration(1000);
+                bubbleAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
+                    @Override
+                    public void onAnimationUpdate(ValueAnimator animation) {
+                        puppy.setScaleY(puppy.getScaleX()-(float) animation.getAnimatedValue()/20);
+                    }
+                });
+                bubbleAnim.setRepeatCount(-1);
+                bubbleAnim.setRepeatMode(ValueAnimator.REVERSE);
+                bubbleAnim.start();
+
+                puppy.getViewTreeObserver().removeOnGlobalLayoutListener(this);
+            }
+        });
+
+        puppy.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View view) {
+                Random rand = new Random();
+                Float rate = rand.nextFloat()+0.7F;
+                final ValueAnimator anim = ValueAnimator.ofFloat(-puppy.getScaleX()*0.5f, puppy.getScaleX()*0.5f);
+                anim.setDuration((int)(200/rate));
+                anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
+                    @Override
+                    public void onAnimationUpdate(ValueAnimator animation) {
+                        puppy.setScaleY(puppy.getScaleX()-(float) animation.getAnimatedValue()/20);
+                    }
+                });
+                anim.setRepeatCount(2);
+                anim.setRepeatMode(ValueAnimator.REVERSE);
+                anim.start();
+            }
+        });
+    }
+    //커스터마이징 화면에서 초기화
+    public void setInitCustom() {
+        sourceMap.put(CustomType.FACE1,"https://togaether.cafe24.com/images/custom/img_cus_f1_1.png");
+        sourceMap.put(CustomType.FACE2,"https://togaether.cafe24.com/images/custom/img_cus_none.png");
+        sourceMap.put(CustomType.FACE3,"https://togaether.cafe24.com/images/custom/img_cus_none.png");
+        sourceMap.put(CustomType.BODY,"https://togaether.cafe24.com/images/custom/img_cus_body_1.png");
+        sourceMap.put(CustomType.MOUTH,"https://togaether.cafe24.com/images/custom/img_cus_mouth_1.png");
+        sourceMap.put(CustomType.NOSE,"https://togaether.cafe24.com/images/custom/img_cus_nose_1.png");
+        sourceMap.put(CustomType.EAR_L,"https://togaether.cafe24.com/images/custom/img_cus_ear_1.png");
+        sourceMap.put(CustomType.EAR_R,"https://togaether.cafe24.com/images/custom/img_cus_ear_1.png");
+        sourceMap.put(CustomType.EYE_L,"https://togaether.cafe24.com/images/custom/img_cus_eye_1.png");
+        sourceMap.put(CustomType.EYE_R,"https://togaether.cafe24.com/images/custom/img_cus_eye_1.png");
+        sourceMap.put(CustomType.EYEBROW_L,"https://togaether.cafe24.com/images/custom/img_cus_none.png");
+        sourceMap.put(CustomType.EYEBROW_R,"https://togaether.cafe24.com/images/custom/img_cus_none.png");
+
+        Glide.with(lay).load(sourceMap.get(CustomType.FACE3))
+                .diskCacheStrategy(DiskCacheStrategy.NONE)
+                .skipMemoryCache(true)
+                .apply(bitmapTransform(new MultiTransformation<Bitmap>(new CenterCrop(), new MaskTransformation2(imgMap.get(CustomType.FACE1).getDrawable())))).into(imgMap.get(CustomType.FACE3));
+
+        for(CustomType t: CustomType.values()) {
+            ImageView targetView = imgMap.get(t);
+            dyMap.put(t,0);
+            distMap.put(t,0);
+            sizeMap.put(t,100);
+            colorMap.put(t,Color.parseColor("#ffffff"));
+            xyMap.put(t,new PartXY(targetView.getX(),targetView.getY()));
+        }
+        colorMap.put(CustomType.FACE2,Color.parseColor("#e6e6e6"));
+        colorMap.put(CustomType.FACE3,Color.parseColor("#6e6e6e"));
+        colorMap.put(CustomType.EYEBROW_L,Color.parseColor("#6e6e6e"));
+        colorMap.put(CustomType.EYEBROW_R,Color.parseColor("#6e6e6e"));
+        colorMap.put(CustomType.EAR_L,Color.parseColor("#452d00"));
+        colorMap.put(CustomType.EAR_R,Color.parseColor("#452d00"));
+        colorMap.put(CustomType.EYE_L,Color.parseColor("#000000"));
+        colorMap.put(CustomType.EYE_R,Color.parseColor("#000000"));
+
+        //색상 초기화
+        for(CustomType t: CustomType.values()) {
+            setColor(t, colorMap.get(t));
+        }
+    }
+    //id로 가져와서 초기화
+    public void setInitCustom(int id) {
+        Retrofit retrofit = new Retrofit.Builder()
+                .baseUrl("http://togaether.cafe24.com")
+                .addConverterFactory(GsonConverterFactory.create())
+                .build();
+        RetrofitPuppy retrofitAPI = retrofit.create(RetrofitPuppy.class);
+        //HashMap<String, Object> input = new HashMap<>();
+        retrofitAPI.getData(id).enqueue(new Callback<PuppyInfoItem>() {
+            @Override
+            public void onResponse(Call<PuppyInfoItem> call, Response<PuppyInfoItem> response) {
+                if(response.isSuccessful()) {
+                    PuppyInfoItem data = response.body();
+                    if(data.getPid() != -1) {
+                        setName(data.getPname());
+                        setCallString(data.getPcall());
+                        setSex(data.getPsex());
+                        setUid(data.getUid());
+                        setBdate(data.getPbdate());
+                        setId(data.getPid());
+                        setInitCustom(data.getPcustom());
+                    }
+                    else {
+                        //error
+                    }
+                }
+            }
+
+            @Override
+            public void onFailure(Call<PuppyInfoItem> call, Throwable t) {
+                Log.e("=========OMG","here" + t);
+            }
+        });
+    }
+    //PuppyItem 받아서 초기화
+    public void setInitCustom(PuppyItem data) {
+        PuppyPartItem partData[] = {data.getEar_l(), data.getEar_r(), data.getEye_l(), data.getEye_r(), data.getEyebrow_l(), data.getEyebrow_r(), data.getFace1(), data.getFace2(), data.getFace3(), data.getMouth(), data.getNose(), data.getBody()};
+        // EAR_L, EAR_R, EYE_L, EYE_R, EYEBROW_L, EYEBROW_R, FACE1, FACE2, FACE3, MOUTH, NOSE, BODY
+        int i = 0;
+        for(CustomType t: CustomType.values()) {
+            setMap(t, partData[i++]);
+        }
+        i = 0;
+        for(CustomType t: CustomType.values()) {
+            setCustom(t, partData[i++]);
+        }
+    }
+    private void setMap(CustomType t, PuppyPartItem item) {
+        dyMap.put(t,item.getDy());
+        distMap.put(t,-item.getDist());
+        sizeMap.put(t,item.getSize());
+        colorMap.put(t,item.getColor());
+        sourceMap.put(t,item.getSource());
+    }
+
+    private void setCustom(CustomType t, PuppyPartItem item) {
+        if(t!=CustomType.FACE3 || (!isSleep && (t==CustomType.EYE_L || t==CustomType.EYE_R))) {
+            setImgSource(t, item.getSource());
+        }
+        setSize(t, item.getSize());
+        setDy(t, item.getDy());
+        setColor(t, item.getColor());
+        setPartPosition(t);
+        if(t==CustomType.EAR_L || t==CustomType.EYE_L || t==CustomType.EYEBROW_L) {
+            setDist(t, -item.getDist());
+        }
+    }
+
+    public void setPosition(int x, int y) {
+        puppy.setTranslationX((int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, x, act.getResources().getDisplayMetrics()) - w/2); //puppy.findViewById(R.id.lay_puppy).
+        puppy.setTranslationY((int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, y, act.getResources().getDisplayMetrics()) - h/2);
+    }
+    public void setPositionPXX(float x) {
+        float x60 = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 60, act.getResources().getDisplayMetrics());
+        puppy.setTranslationX(x - x60);
+    }
+    public void setPositionPXY(float y) {
+        float y142 = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 142.5f, act.getResources().getDisplayMetrics());
+        puppy.setTranslationY(y - y142);
+    }
+    public float getPositionPXX() {
+        return puppy.getX() + w/2;
+    }
+    public float getPositionPXY() {
+        return puppy.getY();
+    }
+    public void setPositionPX(int x, int y) {
+        puppy.setTranslationX(x - w/2);
+        puppy.setTranslationY(y - h/2);
+    }
+    public void setColor(CustomType type, int color) {
+        imgMap.get(type).setColorFilter(color, PorterDuff.Mode.MULTIPLY);
+        colorMap.put(type,color);
+    }
+    public void setImgSource(CustomType type, String url) {
+        sourceMap.put(type, url);
+        if(type == CustomType.FACE1) {
+            pgPuppy.setVisibility(View.VISIBLE);
+            puppyOnly.setVisibility(View.GONE);
+            Glide.with(lay).load(url)
+                    .listener(new RequestListener<Drawable>() {
+                        @Override
+                        public boolean onLoadFailed(@Nullable GlideException e, Object model, Target<Drawable> target, boolean isFirstResource) {
+                            pgPuppy.setVisibility(View.GONE);
+                            puppyOnly.setVisibility(View.VISIBLE);
+                            return false;
+                        }
+
+                        @Override
+                        public boolean onResourceReady(Drawable resource, Object model, Target<Drawable> target, DataSource dataSource, boolean isFirstResource) {
+                            Glide.with(lay).load(sourceMap.get(CustomType.FACE3))
+                                    .listener(new RequestListener<Drawable>() {
+                                        @Override
+                                        public boolean onLoadFailed(@Nullable GlideException e, Object model, Target<Drawable> target, boolean isFirstResource) {
+                                            pgPuppy.setVisibility(View.GONE);
+                                            puppyOnly.setVisibility(View.VISIBLE);
+                                            return false;
+                                        }
+
+                                        @Override
+                                        public boolean onResourceReady(Drawable resource, Object model, Target<Drawable> target, DataSource dataSource, boolean isFirstResource) {
+                                            pgPuppy.setVisibility(View.GONE);
+                                            puppyOnly.setVisibility(View.VISIBLE);
+                                            return false;
+                                        }
+                                    })
+                                    .diskCacheStrategy(DiskCacheStrategy.NONE)
+                                    .skipMemoryCache(true)
+                                    .apply(bitmapTransform(new MultiTransformation<Bitmap>(new CenterCrop(), new MaskTransformation2(resource)))).into(imgMap.get(CustomType.FACE3));
+                            return false;
+                        }
+                    })
+                    .into(imgMap.get(type));
+        }
+        else if(type == CustomType.FACE3) {
+            Glide.with(lay).load(url)
+                    .diskCacheStrategy(DiskCacheStrategy.NONE)
+                    .skipMemoryCache(true)
+                    .apply(bitmapTransform(new MultiTransformation<Bitmap>(new CenterCrop(), new MaskTransformation2(imgMap.get(CustomType.FACE1).getDrawable())))).into(imgMap.get(CustomType.FACE3));
+        }
+        else {
+            Glide.with(lay).load(url).into(imgMap.get(type));
+            if (type == CustomType.EYE_L)
+                Glide.with(lay).load(url.replace("eye","eyew")).into(eyeWL);
+            if (type == CustomType.EYE_R)
+                Glide.with(lay).load(url.replace("eye","eyew")).into(eyeWR);
+        }
+    }
+    public void setSize(CustomType type, int size) {
+        int s = (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, size, act.getResources().getDisplayMetrics());
+        ImageView targetView = imgMap.get(type);
+        ViewGroup.LayoutParams newSize = targetView.getLayoutParams();
+        newSize.width = s;
+        newSize.height = s;
+        targetView.setLayoutParams(newSize);
+        sizeMap.put(type, size);
+        setPartPosition(type);
+        if (type == CustomType.EYE_L) {
+            eyeWL.setLayoutParams(newSize);
+        }
+        else if (type == CustomType.EYE_R) {
+            eyeWR.setLayoutParams(newSize);
+        }
+    }
+    public void setCSize(CustomType type, int size) {
+        setSize(type, size);
+        if(type == CustomType.FACE1) {
+            setSize(CustomType.FACE3, size);
+            sizeMap.put(CustomType.FACE3, size);
+            setPartPosition(CustomType.FACE3);
+        }
+    }
+    public void setDy(CustomType type, int dy) {
+        dyMap.put(type, dy);
+        setPartPosition(type);
+    }
+    public void setCDy(CustomType type, int dy) {
+        // dDy, preDy는 FACE1 움직일 때 따라 움직이는 애들 용
+        int dDy, preDy = dyMap.get(type);
+        setDy(type, dy);
+        dDy = dy - preDy;
+        if(type == CustomType.FACE1) {
+            CustomType[] ts = {CustomType.FACE2, CustomType.FACE3, CustomType.EAR_L, CustomType.EAR_R, CustomType.NOSE, CustomType.MOUTH, CustomType.EYE_L, CustomType.EYE_R, CustomType.EYEBROW_L, CustomType.EYEBROW_R};
+            for(CustomType t: ts) {
+                dyMap.put(t, dyMap.get(t) + dDy);
+                setPartPosition(t);
+            }
+        }
+    }
+    // 왼쪽 타입에만 적용
+    public void setDist(CustomType type, int dist) {
+        distMap.put(type, -dist);
+        setPartPosition(type);
+        CustomType targetType = CustomType.valueOf(type.name().substring(0, type.name().length() - 1) + "R");
+        distMap.put(targetType, dist);
+        setPartPosition(targetType);
+    }
+    public void setPartPosition(CustomType type) {
+        int size = sizeMap.get(type);
+        int s = (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, size, act.getResources().getDisplayMetrics());
+        float dy = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dyMap.get(type), act.getResources().getDisplayMetrics());
+        float dist = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, distMap.get(type), act.getResources().getDisplayMetrics());
+
+        ImageView targetView = imgMap.get(type);
+        targetView.setTranslationX(xyMap.get(type).getX() + dist - (float)(s - oriS)/2);
+
+        float tempYCenter;
+        if(type == CustomType.BODY) { tempYCenter = (float)(s - oriS)*3/4; }
+        else { tempYCenter = (float)(s - oriS)/2; }
+
+        targetView.setTranslationY(xyMap.get(type).getY() + dy - tempYCenter);
+        if(type == CustomType.EYE_L || type == CustomType.EYE_R) {
+            eyeWL.setTranslationX(imgMap.get(CustomType.EYE_L).getX());
+            eyeWL.setTranslationY(imgMap.get(CustomType.EYE_L).getY());
+
+            eyeWR.setTranslationX(imgMap.get(CustomType.EYE_R).getX());
+            eyeWR.setTranslationY(imgMap.get(CustomType.EYE_R).getY());
+        }
+
+        if(type == CustomType.BODY) {
+            float _dy = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 65, act.getResources().getDisplayMetrics());
+            vShadow.setTranslationY(imgMap.get(CustomType.BODY).getY() + tempYCenter + _dy);
+        }
+    }
+    public String getCustomJSON() {
+        String jString = "{";
+        for(CustomType t: CustomType.values()) {
+            jString += "\"" + t.name() + "\":";
+            jString += "{";
+            jString += "\"source\":" + "\"" + sourceMap.get(t) + "\",";
+            jString += "\"dy\":" + dyMap.get(t) + ",";
+            jString += "\"dist\":" + distMap.get(t) + ",";
+            jString += "\"size\":" + sizeMap.get(t) + ",";
+            jString += "\"color\":" + colorMap.get(t);
+            jString += "}";
+            if(t != CustomType.BODY) { jString += ","; }
+        }
+        jString += "}";
+        return jString;
+    }
+
+    public void setSleep(boolean isSleep){
+        this.isSleep = isSleep;
+        if(isSleep) {
+            setImgSource(CustomType.EYE_L, "http://togaether.cafe24.com/images/custom/img_cus_eye_0_sleep.png");
+            setImgSource(CustomType.EYE_R, "http://togaether.cafe24.com/images/custom/img_cus_eye_0_sleep.png");
+        }
+        else {
+            //setImgSource(CustomType.EYE_L, sourceMap.get(CustomType.EYE_L));
+            //setImgSource(CustomType.EYE_R, sourceMap.get(CustomType.EYE_R));
+        }
+    }
+
+    public float pxToDp(Context context, float px) {
+
+        // 해상도 마다 다른 density 를 반환. xxxhdpi는 density = 4
+        float density = context.getResources().getDisplayMetrics().density;
+
+        if (density == 1.0)      // mpdi  (160dpi) -- xxxhdpi (density = 4)기준으로 density 값을 재설정 한다
+            density *= 4.0;
+        else if (density == 1.5) // hdpi  (240dpi)
+            density *= (8 / 3);
+        else if (density == 2.0) // xhdpi (320dpi)
+            density *= 2.0;
+
+        return px / density;     // dp 값 반환
+    }
+}
+
+class PartXY{
+    private float x, y;
+
+    public PartXY(float x, float y){
+        this.x = x;
+        this.y = y;
+    }
+
+    public float getX() {
+        return x;
+    }
+
+    public float getY() {
+        return y;
+    }
+
+    public void setX(float x) {
+        this.x = x;
+    }
+
+    public void setY(float y) {
+        this.y = y;
+    }
+}
\ No newline at end of file
diff --git a/togaetherLib/src/main/java/com/example/togaetherlib/RetrofitPuppy.java b/togaetherLib/src/main/java/com/example/togaetherlib/RetrofitPuppy.java
new file mode 100644
index 0000000..3a5cfff
--- /dev/null
+++ b/togaetherLib/src/main/java/com/example/togaetherlib/RetrofitPuppy.java
@@ -0,0 +1,48 @@
+package com.example.togaetherlib;
+
+import java.util.HashMap;
+import java.util.List;
+
+import okhttp3.ResponseBody;
+import retrofit2.Call;
+import retrofit2.http.FieldMap;
+import retrofit2.http.FormUrlEncoded;
+import retrofit2.http.POST;
+import retrofit2.http.Query;
+
+public interface RetrofitPuppy {
+    @POST("/puppyListForPid.php")
+    Call<PuppyInfoItem> getData(@Query("pid") int id);
+
+    @FormUrlEncoded
+    @POST("/puppyInfoForPid.php")
+    Call<PuppyInfoItem> getMoreInfo(@FieldMap HashMap<String, Object> param);
+
+    @FormUrlEncoded
+    @POST("/test.json")
+    Call<PuppyItem> postData(@FieldMap HashMap<String, Object> param);
+
+    @FormUrlEncoded
+    @POST("/puppyInsert.php")
+    Call<ResponseBody> insertPuppy(@FieldMap HashMap<String, Object> param);
+
+    @FormUrlEncoded
+    @POST("/puppyListForUid.php")
+    Call<List<PuppyInfoItem>> getPuppyListById(@FieldMap HashMap<String, Object> param);
+
+    @FormUrlEncoded
+    @POST("/puppyFriendList.php")
+    Call<List<PuppyInfoItem>> getPuppyFriendList(@FieldMap HashMap<String, Object> param);
+
+    @FormUrlEncoded
+    @POST("/puppyListForRandom.php")
+    Call<PuppyInfoItem> getVisitPuppy(@FieldMap HashMap<String, Object> param);
+
+    @FormUrlEncoded
+    @POST("/puppySetFriend.php")
+    Call<ResponseBody> setFriend(@FieldMap HashMap<String, Object> param);
+
+    @FormUrlEncoded
+    @POST("/puppyListForAddrPid.php")
+    Call<List<PuppyInfoItem>> getPuppyListByAddrPid(@FieldMap HashMap<String, Object> param);
+}
diff --git a/togaetherLib/src/main/res/drawable/cir_shadow.xml b/togaetherLib/src/main/res/drawable/cir_shadow.xml
new file mode 100644
index 0000000..34f7659
--- /dev/null
+++ b/togaetherLib/src/main/res/drawable/cir_shadow.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval">
+    <solid android:color="#5B000000"/>
+    <size android:width="100dp" android:height="25dp"/>
+</shape>
\ No newline at end of file
diff --git a/togaetherLib/src/main/res/drawable/img_cus_body_1.png b/togaetherLib/src/main/res/drawable/img_cus_body_1.png
new file mode 100644
index 0000000..879d7f0
Binary files /dev/null and b/togaetherLib/src/main/res/drawable/img_cus_body_1.png differ
diff --git a/togaetherLib/src/main/res/drawable/img_cus_ear_1.png b/togaetherLib/src/main/res/drawable/img_cus_ear_1.png
new file mode 100644
index 0000000..6780664
Binary files /dev/null and b/togaetherLib/src/main/res/drawable/img_cus_ear_1.png differ
diff --git a/togaetherLib/src/main/res/drawable/img_cus_eye_1.png b/togaetherLib/src/main/res/drawable/img_cus_eye_1.png
new file mode 100644
index 0000000..5bbf2e6
Binary files /dev/null and b/togaetherLib/src/main/res/drawable/img_cus_eye_1.png differ
diff --git a/togaetherLib/src/main/res/drawable/img_cus_eyebrow_1.png b/togaetherLib/src/main/res/drawable/img_cus_eyebrow_1.png
new file mode 100644
index 0000000..8cd9a6e
Binary files /dev/null and b/togaetherLib/src/main/res/drawable/img_cus_eyebrow_1.png differ
diff --git a/togaetherLib/src/main/res/drawable/img_cus_eyew_1.png b/togaetherLib/src/main/res/drawable/img_cus_eyew_1.png
new file mode 100644
index 0000000..b8c60bf
Binary files /dev/null and b/togaetherLib/src/main/res/drawable/img_cus_eyew_1.png differ
diff --git a/togaetherLib/src/main/res/drawable/img_cus_f1_1.png b/togaetherLib/src/main/res/drawable/img_cus_f1_1.png
new file mode 100644
index 0000000..565c34c
Binary files /dev/null and b/togaetherLib/src/main/res/drawable/img_cus_f1_1.png differ
diff --git a/togaetherLib/src/main/res/drawable/img_cus_f2_1.png b/togaetherLib/src/main/res/drawable/img_cus_f2_1.png
new file mode 100644
index 0000000..40805ff
Binary files /dev/null and b/togaetherLib/src/main/res/drawable/img_cus_f2_1.png differ
diff --git a/togaetherLib/src/main/res/drawable/img_cus_f3_1.png b/togaetherLib/src/main/res/drawable/img_cus_f3_1.png
new file mode 100644
index 0000000..1387e25
Binary files /dev/null and b/togaetherLib/src/main/res/drawable/img_cus_f3_1.png differ
diff --git a/togaetherLib/src/main/res/drawable/img_cus_mouth_1.png b/togaetherLib/src/main/res/drawable/img_cus_mouth_1.png
new file mode 100644
index 0000000..dc512c7
Binary files /dev/null and b/togaetherLib/src/main/res/drawable/img_cus_mouth_1.png differ
diff --git a/togaetherLib/src/main/res/drawable/img_cus_none.png b/togaetherLib/src/main/res/drawable/img_cus_none.png
new file mode 100644
index 0000000..cfad488
Binary files /dev/null and b/togaetherLib/src/main/res/drawable/img_cus_none.png differ
diff --git a/togaetherLib/src/main/res/drawable/img_cus_nose_1.png b/togaetherLib/src/main/res/drawable/img_cus_nose_1.png
new file mode 100644
index 0000000..cfeb5e8
Binary files /dev/null and b/togaetherLib/src/main/res/drawable/img_cus_nose_1.png differ
diff --git a/togaetherLib/src/main/res/layout/puppy_view.xml b/togaetherLib/src/main/res/layout/puppy_view.xml
new file mode 100644
index 0000000..80ceabf
--- /dev/null
+++ b/togaetherLib/src/main/res/layout/puppy_view.xml
@@ -0,0 +1,166 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="120dp"
+    android:layout_height="190dp"
+    android:id="@+id/lay_puppy"
+    tools:ignore="InvalidId">
+    <ProgressBar
+        android:id="@+id/pg_puppy"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"/>
+
+    <androidx.constraintlayout.widget.ConstraintLayout
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:id="@+id/lay_puppy_only">
+
+    <View
+        android:id="@+id/v_shadow"
+        android:layout_width="100dp"
+        android:layout_height="25dp"
+        android:translationY="125dp"
+        android:translationX="10dp"
+        android:background="@drawable/cir_shadow"
+        tools:ignore="MissingConstraints" />
+
+    <ImageView
+        android:id="@+id/img_body"
+        android:layout_width="100dp"
+        android:layout_height="100dp"
+        android:translationY="60dp"
+        android:translationX="10dp"
+        app:srcCompat="@drawable/img_cus_body_1"
+        tools:ignore="MissingConstraints"
+        tools:layout_editor_absoluteX="0dp" />
+
+    <ImageView
+        android:id="@+id/img_face1"
+        android:layout_width="100dp"
+        android:layout_height="100dp"
+        android:translationY="20dp"
+        android:translationX="10dp"
+        app:srcCompat="@drawable/img_cus_f1_1"
+        tools:ignore="MissingConstraints" />
+
+    <ImageView
+        android:id="@+id/img_face3"
+        android:layout_width="100dp"
+        android:layout_height="100dp"
+        android:translationY="20dp"
+        android:translationX="10dp"
+        app:srcCompat="@drawable/img_cus_none"
+        tools:ignore="MissingConstraints" />
+
+    <ImageView
+        android:id="@+id/img_mouth"
+        android:layout_width="100dp"
+        android:layout_height="100dp"
+        android:translationY="40dp"
+        android:translationX="10dp"
+        app:srcCompat="@drawable/img_cus_mouth_1"
+        tools:ignore="MissingConstraints" />
+
+    <ImageView
+        android:id="@+id/img_eye_left"
+        android:layout_width="100dp"
+        android:layout_height="100dp"
+        android:translationX="-5dp"
+        android:translationY="15dp"
+        app:srcCompat="@drawable/img_cus_eye_1"
+        tools:ignore="MissingConstraints"
+        tools:layout_editor_absoluteX="0dp" />
+
+    <ImageView
+        android:id="@+id/img_eye_right"
+        android:layout_width="100dp"
+        android:layout_height="100dp"
+        android:translationX="25dp"
+        android:translationY="15dp"
+        android:scaleX="-1"
+        app:srcCompat="@drawable/img_cus_eye_1"
+        tools:ignore="MissingConstraints"
+        tools:layout_editor_absoluteX="0dp" />
+
+    <ImageView
+        android:id="@+id/img_eyew_left"
+        android:layout_width="100dp"
+        android:layout_height="100dp"
+        android:translationX="-5dp"
+        android:translationY="15dp"
+        app:srcCompat="@drawable/img_cus_eyew_1"
+        tools:ignore="MissingConstraints"
+        tools:layout_editor_absoluteX="0dp" />
+
+    <ImageView
+        android:id="@+id/img_eyew_right"
+        android:layout_width="100dp"
+        android:layout_height="100dp"
+        android:translationX="25dp"
+        android:translationY="15dp"
+        app:srcCompat="@drawable/img_cus_eyew_1"
+        tools:ignore="MissingConstraints"
+        tools:layout_editor_absoluteX="0dp" />
+
+    <ImageView
+        android:id="@+id/img_face2"
+        android:layout_width="100dp"
+        android:layout_height="100dp"
+        android:translationY="35dp"
+        android:translationX="10dp"
+        app:srcCompat="@drawable/img_cus_none"
+        tools:ignore="MissingConstraints" />
+
+    <ImageView
+        android:id="@+id/img_nose"
+        android:layout_width="100dp"
+        android:layout_height="100dp"
+        android:translationY="30dp"
+        android:translationX="10dp"
+        app:srcCompat="@drawable/img_cus_nose_1"
+        tools:ignore="MissingConstraints"
+        tools:layout_editor_absoluteX="0dp" />
+
+    <ImageView
+        android:id="@+id/img_eyebrow_left"
+        android:layout_width="100dp"
+        android:layout_height="100dp"
+        android:translationY="8dp"
+        android:translationX="-10dp"
+        app:srcCompat="@drawable/img_cus_none"
+        tools:ignore="MissingConstraints" />
+
+    <ImageView
+        android:id="@+id/img_eyebrow_right"
+        android:layout_width="100dp"
+        android:layout_height="100dp"
+        android:translationY="8dp"
+        android:translationX="30dp"
+        app:srcCompat="@drawable/img_cus_none"
+        android:scaleX="-1"
+        tools:ignore="MissingConstraints" />
+
+    <ImageView
+        android:id="@+id/img_ear_left"
+        android:layout_width="100dp"
+        android:layout_height="100dp"
+        android:translationX="-15dp"
+        android:translationY="-10dp"
+        app:srcCompat="@drawable/img_cus_ear_1"
+        tools:ignore="MissingConstraints"
+        tools:layout_editor_absoluteX="0dp" />
+
+    <ImageView
+        android:id="@+id/img_ear_right"
+        android:layout_width="100dp"
+        android:layout_height="100dp"
+        android:translationX="35dp"
+        android:translationY="-10dp"
+        android:scaleX="-1"
+        app:srcCompat="@drawable/img_cus_ear_1"
+        tools:ignore="MissingConstraints"
+        tools:layout_editor_absoluteX="0dp" />
+
+    </androidx.constraintlayout.widget.ConstraintLayout>
+</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
diff --git a/togaetherLib/src/main/res/values/strings.xml b/togaetherLib/src/main/res/values/strings.xml
new file mode 100644
index 0000000..73862c4
--- /dev/null
+++ b/togaetherLib/src/main/res/values/strings.xml
@@ -0,0 +1 @@
+<resources></resources>
\ No newline at end of file
diff --git a/togaetherLib/src/test/java/com/example/togaetherlib/ExampleUnitTest.java b/togaetherLib/src/test/java/com/example/togaetherlib/ExampleUnitTest.java
new file mode 100644
index 0000000..1dd1718
--- /dev/null
+++ b/togaetherLib/src/test/java/com/example/togaetherlib/ExampleUnitTest.java
@@ -0,0 +1,17 @@
+package com.example.togaetherlib;
+
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+/**
+ * Example local unit test, which will execute on the development machine (host).
+ *
+ * @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
+ */
+public class ExampleUnitTest {
+    @Test
+    public void addition_isCorrect() {
+        assertEquals(4, 2 + 2);
+    }
+}
\ No newline at end of file