zID(v5dDs`wv0Q?exdCdA>}2J}O%CqYb08YSMEWPBa{`}W9E
z*!p~9XMT6~
zQ;I)#R>tHUr81$cPe=0Ee*5lOg=Dw4tH4{2=SUF9P0%+ZD0NW~N2zH9JYI-9Rg-U~
zr=5OyA3!A&J7}D;2DW+H_DS_J#>%AXr+FekcZi(G;~&89ay2__HwTKFV4BIwiP@V=
zH66>$pop_$p8CKlrh*o9kN@4lB_F?;t$7o&(NHSD<>Y2$R+p|qf;Yb~#MUrzmhK==
zC0wn)ZN_%=u~}$d^5!7RBam*6(e6#V$PP;$%g5JfajDu?aA%t6f_PjA(I>ISS_=5Y1bcqN@IE(IbKf6d)G1Enpuj*l=IG3AO)PXb2;xTuNm7
z-nDz{2R_Rmx#bQeFHzB!xYmhDhfcBeANX`qBl5d14_vb*`_WS?R?bZt>3J{eGN8mj
z!!jdLC9;#pp?e~CFYi|PqpChb*9t3$nc-`Gy#qA1TWQ&Og1E7C$L>drmc~JaDaQb5
z74@mwiB>~VxEqbxNRMz`7R+o_^H)tRY$G&K!+IYZ7PB;7Zd8$DQ1@}|XDxi=MtftZ
z3hSZx33j}%4>YisYS4K+ubdB+?rP1sR`<*TWNw*=x-ftp728wq$r7g3a9Id8ow
zo`+0F&<*=>sA)VE61QK3I8c`bw|gO(EFuzi+aW5dzz_wkL%VZ`D)zl
z|8^-Uxct)j;$JVH&}}5n?1jdyKs@+{MQG&E5GQ@iG;xeSS3-5X)GJ|z
zr6i1}(+S&>Q*l
zySwIo@}4$0+XuN2X)YJI#G>9L>K$>L)<&u7VEUz+SmDB-*(-&Mhh4KKnvi#-J!}!_
z?x}+DKCv@&RGWGmnsj{z7D*pzu@n|c-E@z`ON-2@tRCyfhN
zxo7vR*~i`65R0*jCJikjUw#%5b8tp>`EA>#l>GUHC@iBE>js5$+o){($=Sq)r8AL)
zoXX1@$vBkDd8=}@vot3fHolDbNt36LzODP!xJ4VuBWZk{#ImGt+N_hAnSK4eT=F>_
z{X0vN$1jAsN_WEBi#a?TL!!N)N`yi^q*ZL)#IMEg)7#aZP4HXaX#b#?+=2@*z^jR
z_OGtfe^Y#Ig}qi>Ga~0rxa>pKnfvg#LNQRv`#Sy7XB9138rEn=mU3=gHihc~apAB>
z*_9mHxxrQEJl9D9@wgMpC1TVY)RfclZ$mD}l9WKi~*i=3tm1QNT_y%|;
zK7Xv8VBiOP+?;d_fd&psF&bdSP=)HG`ZopTev-B{;WyIz#_}Az-=J_+b`<71m9x&!
zMLsgMJHllgTMiQoB|7issRB+3&NK$ob_$~Be!4cjWt-(Xgc6aLAT}3@8rhs;;W(tuR8DCQ044!bl{REsy3_9#~
z_ArtTwyb75X8D#z*2~whNO{btN*DU()~DMZQ^2^ZMqRj0R86fz7Q*=6*NrRO2|x<$
z<$;t$5Hz(aMll6^t12)5FgncmdyyvarL=!SgAXjf0=Pew^Q7xC1lzUE6{gIg%5K@)
ztb>)1dG;6PGuw0;B)<2;kzbSb4ceM@IUy$nJQ8-}eI^lcip3v}=9%n|1Za3G!shX{NQl{ZV<&doPbErM-qX
z3X73lGbPD2val64sL(&?*{^FfQdu%iF%q9AAdT_&VNlR
zdPP@Hd-?n%AbY_L=VWs~OZFnyk7%@2yO~=auqN
zB$syl3&@un2e%jC!imT3LCWGok7`mlAW+NFWg9N$g0Xz8rV3T7g2Mivzqt%H2R|PCvw!R4(oY^i&rII?C1#A-Ns~20Rfy)SCbtL*Ljz
z$1xBn1VA<*bW~R?cA=Pbf9WFwvMFEA0ILR$QHZ78!fM<|Jc4Tp>=t2m8Kxn7Bz<_j
zM)HSc70&t{B6I!$YU;TlnPEE3u2`)Q2IGMoeEM4Rc2F7u0qH@xs;1F+Qp{hKskf{sR!;D0=71
z`BM&U#Q$JI5)J)itJ651^KgZ3RC5o(BYpaaaKck6bM!5nzrF;&wb_&nWYWy8MeE6o
z($~oJVlBolfYSTBg_U!0KNav~^F^W$a&bcq;Z9*l&D<9qmk3m=dQOPZ1mG^tmJgU6
zp%o{UFTaIxEj`SDY(WB5Bje#Z$8czaIL@#rIdy*Ey3WD~P;C_s2x8A_S^PdCW5BTZ
z{*{z?O9|7&{(Oij`zvHVhh|WKfG9x-!JqmlRQe}X*^xk&kp8hi&XFDo#b@fMGxk~!
zdM}}LN5A>5zd?tV-DsJP|{Cl&aLzQj{}IBpb;9>nu{=B-=X{IiUI7^vg7{q@Hk$MvI2jbbYI
zB3qKul-bA`&S*C{kSCYUGuEb#-~BPT>mT)|y|MdRf!$h-2lbk(sTsNf)EL_*r!*V1
z1wlvoxD-tR62tXB%9`-}(Ek9uD6%W-HAl75Aju7nr7K*bsVo=))Z&?O3G$B}$MdAR
zfQxxQ8d?wQRW;a@+(s8aH|0Q(%%GqkH#syLf8B$R;r^99qzA}@AKet~pq?tD(4lP(
z5eXUjvz&9*uaW`kGf8g-U>NFH)n$O6GmrUb!kpdNIC}odHnr|rF1Y){^QQTTI=KAm
zy}h|J$_V~HPhn0L#NIf^W&X7`M*jd^f67beN1PX5&YEUS<9Mjv)cvH4e+Tuc9@G6Y
zFn_pzn4v{6JZ!rQ=fnsFz$TE~M7S*Y$-v@?tv-8m(>uSFCDo?U5dQ$CpU}}{FRo9r
z9rlP+WVc>AQa!{=
zmS1aOMt=%f?Qv-19-q#qlGhe;@zD=z6@>9sJc`DDkiN#i8S6)$Oicb++6Hl&o@;O|
zWZ;Y`{#1RK3n_oxKgyblCF1J$DCG!LxR?nN1SAZaiL)!mMLGf0giKxE)ybBtB^;Mrp@AM(%oQ*G_R)8#nn
z8U99vVqPMza*S^yz+^ZWQg8>gC@=Oln4g#~M;uj{p$lO7AHaW=IiSXt{C@!cbRjzR
zKbWk+#gUsoHsu{ShpZI@Dp$(oe_JC&tXy@>#jDP5C
zf7t$&W?}w`{{U>q@}@WZd7t+O@}|i}a~^CV{{VDu9XF5V
zQK9|(-$njrkL&URB#3>q{{Yt^{OD+h+T;2^^A%-4`%7{E04&Gzrbs`2huP_+uri#m
zgDgMqpX6#ep&Ov%_=Q|A<{V9`mgZ=SS*rfL$xQH0v*@yF@>MYw$$E{kp1Ilhc
zh<`CjazD|g`Wh{w{<{VD8e$$u9^cZPV;A~7KD%mC2Ep|Hl=~1oh&cWlrin~~(h_ag
zkK%0pwHz=H-uiiuR_uxLNbQ#XW{5zM(SMPlpenpS=_iliAI_$GaBpKcAL`rrikk!NpYRd<%}XF3
zYmff9xBi4EiqIvwMtC{39?$(Lw~&lQz|Wii0J569a0csB-)sK>N@dvlpY_xK0A)2R
z;wfxZxQFGBkNIo|^QF0neV7iXdj9}Au{Yh1{=0vTEy(@S{{X(f&W5%Qx2>T@21MZ*YOp-iVOULm407|)b
z2iW8|=V_>AKj1r8{a#5r-Bsf7dhosh(CW=Klb2{{Sks;}(+-_7Czk8UFx}Sx5T^
z`3jqAS3&+r{?D7*GyJMJW5$~|`-l3~_XGPfem~`#e=4lM@(+{!-|?oFqL#%nfNApj
z`DUcJi*B65AHYADsU-keO~?GRKg?8@Kk?+>?yvKqL@rm7KlCLXaO+auE>hff^FO5|
zgEp!E09^%3cmVP-{rX907t}^k{i_J{j;8+rn2VqG7Nc+Z3a9;Z6({_}Wd8tlYNUl7
l$3lO9G4yl%sW*?X=h#zW{{UM*`|V6W@(&+{S3z|@|Jh=}hQ0s*
literal 0
HcmV?d00001
diff --git a/src/App.vue b/src/App.vue
new file mode 100644
index 0000000..f20284f
--- /dev/null
+++ b/src/App.vue
@@ -0,0 +1,47 @@
+
+
+
+
+
+
+
diff --git a/src/assets/base.css b/src/assets/base.css
new file mode 100644
index 0000000..d3de42e
--- /dev/null
+++ b/src/assets/base.css
@@ -0,0 +1,73 @@
+/* color palette from */
+:root {
+ --vt-c-white: #ffffff;
+ --vt-c-white-soft: #f8f8f8;
+ --vt-c-white-mute: #f2f2f2;
+
+ --vt-c-black: #181818;
+ --vt-c-black-soft: #222222;
+ --vt-c-black-mute: #282828;
+
+ --vt-c-indigo: #2c3e50;
+
+ --vt-c-divider-light-1: rgba(60, 60, 60, 0.29);
+ --vt-c-divider-light-2: rgba(60, 60, 60, 0.12);
+ --vt-c-divider-dark-1: rgba(84, 84, 84, 0.65);
+ --vt-c-divider-dark-2: rgba(84, 84, 84, 0.48);
+
+ --vt-c-text-light-1: var(--vt-c-indigo);
+ --vt-c-text-light-2: rgba(60, 60, 60, 0.66);
+ --vt-c-text-dark-1: var(--vt-c-white);
+ --vt-c-text-dark-2: rgba(235, 235, 235, 0.64);
+}
+
+/* semantic color variables for this project */
+:root {
+ --color-background: var(--vt-c-white);
+ --color-background-soft: var(--vt-c-white-soft);
+ --color-background-mute: var(--vt-c-white-mute);
+
+ --color-border: var(--vt-c-divider-light-2);
+ --color-border-hover: var(--vt-c-divider-light-1);
+
+ --color-heading: var(--vt-c-text-light-1);
+ --color-text: var(--vt-c-text-light-1);
+
+ --section-gap: 160px;
+}
+
+@media (prefers-color-scheme: dark) {
+ :root {
+ --color-background: var(--vt-c-black);
+ --color-background-soft: var(--vt-c-black-soft);
+ --color-background-mute: var(--vt-c-black-mute);
+
+ --color-border: var(--vt-c-divider-dark-2);
+ --color-border-hover: var(--vt-c-divider-dark-1);
+
+ --color-heading: var(--vt-c-text-dark-1);
+ --color-text: var(--vt-c-text-dark-2);
+ }
+}
+
+*,
+*::before,
+*::after {
+ box-sizing: border-box;
+ margin: 0;
+ font-weight: normal;
+}
+
+body {
+ min-height: 100vh;
+ color: var(--color-text);
+ background: var(--color-background);
+ transition: color 0.5s, background-color 0.5s;
+ line-height: 1.6;
+ font-family: Inter, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu,
+ Cantarell, 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif;
+ font-size: 15px;
+ text-rendering: optimizeLegibility;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
diff --git a/src/assets/logo.svg b/src/assets/logo.svg
new file mode 100644
index 0000000..7565660
--- /dev/null
+++ b/src/assets/logo.svg
@@ -0,0 +1 @@
+
diff --git a/src/assets/main.css b/src/assets/main.css
new file mode 100644
index 0000000..e8667cd
--- /dev/null
+++ b/src/assets/main.css
@@ -0,0 +1,35 @@
+@import './base.css';
+
+#app {
+ max-width: 1280px;
+ margin: 0 auto;
+ padding: 2rem;
+
+ font-weight: normal;
+}
+
+a,
+.green {
+ text-decoration: none;
+ color: hsla(160, 100%, 37%, 1);
+ transition: 0.4s;
+}
+
+@media (hover: hover) {
+ a:hover {
+ background-color: hsla(160, 100%, 37%, 0.2);
+ }
+}
+
+@media (min-width: 1024px) {
+ body {
+ display: flex;
+ place-items: center;
+ }
+
+ #app {
+ display: grid;
+ grid-template-columns: 1fr 1fr;
+ padding: 0 2rem;
+ }
+}
diff --git a/src/components/editor/Editor.vue b/src/components/editor/Editor.vue
new file mode 100644
index 0000000..0416da2
--- /dev/null
+++ b/src/components/editor/Editor.vue
@@ -0,0 +1,95 @@
+
+
+
+
+
+
+
diff --git a/src/components/editor/bottommenu/BottomMenu.vue b/src/components/editor/bottommenu/BottomMenu.vue
new file mode 100644
index 0000000..5bd1392
--- /dev/null
+++ b/src/components/editor/bottommenu/BottomMenu.vue
@@ -0,0 +1,38 @@
+
+
+
+
+
+
+
diff --git a/src/components/editor/canvasview/CanvasView.vue b/src/components/editor/canvasview/CanvasView.vue
new file mode 100644
index 0000000..eb7c78a
--- /dev/null
+++ b/src/components/editor/canvasview/CanvasView.vue
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
diff --git a/src/components/editor/propertyview/PropertyView.vue b/src/components/editor/propertyview/PropertyView.vue
new file mode 100644
index 0000000..bbea99b
--- /dev/null
+++ b/src/components/editor/propertyview/PropertyView.vue
@@ -0,0 +1,33 @@
+
+
+
+
+
+
+
diff --git a/src/components/editor/toolbox/Toolbox.vue b/src/components/editor/toolbox/Toolbox.vue
new file mode 100644
index 0000000..ecb602a
--- /dev/null
+++ b/src/components/editor/toolbox/Toolbox.vue
@@ -0,0 +1,42 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/editor/topmenu/TopMenu.vue b/src/components/editor/topmenu/TopMenu.vue
new file mode 100644
index 0000000..e9c6fcf
--- /dev/null
+++ b/src/components/editor/topmenu/TopMenu.vue
@@ -0,0 +1,38 @@
+
+
+
+
+
+
+
+
+
diff --git a/src/main.ts b/src/main.ts
new file mode 100644
index 0000000..0ac3a5f
--- /dev/null
+++ b/src/main.ts
@@ -0,0 +1,6 @@
+import './assets/main.css'
+
+import { createApp } from 'vue'
+import App from './App.vue'
+
+createApp(App).mount('#app')
diff --git a/tsconfig.app.json b/tsconfig.app.json
new file mode 100644
index 0000000..3e5b621
--- /dev/null
+++ b/tsconfig.app.json
@@ -0,0 +1,12 @@
+{
+ "extends": "@vue/tsconfig/tsconfig.dom.json",
+ "include": ["env.d.ts", "src/**/*", "src/**/*.vue"],
+ "exclude": ["src/**/__tests__/*"],
+ "compilerOptions": {
+ "composite": true,
+ "baseUrl": ".",
+ "paths": {
+ "@/*": ["./src/*"]
+ }
+ }
+}
diff --git a/tsconfig.json b/tsconfig.json
new file mode 100644
index 0000000..66b5e57
--- /dev/null
+++ b/tsconfig.json
@@ -0,0 +1,11 @@
+{
+ "files": [],
+ "references": [
+ {
+ "path": "./tsconfig.node.json"
+ },
+ {
+ "path": "./tsconfig.app.json"
+ }
+ ]
+}
diff --git a/tsconfig.node.json b/tsconfig.node.json
new file mode 100644
index 0000000..dee96be
--- /dev/null
+++ b/tsconfig.node.json
@@ -0,0 +1,16 @@
+{
+ "extends": "@tsconfig/node18/tsconfig.json",
+ "include": [
+ "vite.config.*",
+ "vitest.config.*",
+ "cypress.config.*",
+ "nightwatch.conf.*",
+ "playwright.config.*"
+ ],
+ "compilerOptions": {
+ "composite": true,
+ "module": "ESNext",
+ "moduleResolution": "Bundler",
+ "types": ["node"]
+ }
+}
diff --git a/vite.config.ts b/vite.config.ts
new file mode 100644
index 0000000..5c45e1d
--- /dev/null
+++ b/vite.config.ts
@@ -0,0 +1,16 @@
+import { fileURLToPath, URL } from 'node:url'
+
+import { defineConfig } from 'vite'
+import vue from '@vitejs/plugin-vue'
+
+// https://vitejs.dev/config/
+export default defineConfig({
+ plugins: [
+ vue(),
+ ],
+ resolve: {
+ alias: {
+ '@': fileURLToPath(new URL('./src', import.meta.url))
+ }
+ }
+})