├── .gitignore
├── .prettierc.json
├── index.html
├── main.js
├── package-lock.json
├── package.json
├── public
├── coral_fort_wall_02_2k.gltf
│ ├── coral_fort_wall_02.bin
│ ├── coral_fort_wall_02_2k.gltf
│ └── textures
│ │ ├── coral_fort_wall_02_diff_2k.jpg
│ │ ├── coral_fort_wall_02_nor_gl_2k.jpg
│ │ └── coral_fort_wall_02_rough_2k.jpg
└── vite.svg
├── style.css
└── window.js
/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 | pnpm-debug.log*
8 | lerna-debug.log*
9 |
10 | node_modules
11 | dist
12 | dist-ssr
13 | *.local
14 |
15 | # Editor directories and files
16 | .vscode/*
17 | !.vscode/extensions.json
18 | .idea
19 | .DS_Store
20 | *.suo
21 | *.ntvs*
22 | *.njsproj
23 | *.sln
24 | *.sw?
25 |
--------------------------------------------------------------------------------
/.prettierc.json:
--------------------------------------------------------------------------------
1 | {
2 | "tabWidth":4
3 | }
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Vite App
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/main.js:
--------------------------------------------------------------------------------
1 | import "./style.css"
2 |
3 | import WindowManager from './window';
4 | import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';
5 | import * as THREE from 'three';
6 |
7 | let camera, scene, renderer, world;
8 | let near, far;
9 | let objs = [];
10 | let sceneOffsetTarget = {x: 0, y: 0};
11 | let sceneOffset = {x: 0, y: 0};
12 |
13 | let today = new Date();
14 | today.setHours(0);
15 | today.setMinutes(0);
16 | today.setSeconds(0);
17 | today.setMilliseconds(0);
18 | today = today.getTime();
19 |
20 | const getTime =() =>{
21 | return (new Date().getTime() - today) / 1000.0;
22 | }
23 |
24 | let internalTime = getTime();
25 | let windowManager;
26 | let initialized = false;
27 |
28 |
29 | if (new URLSearchParams(window.location.search).get("clear")){
30 | localStorage.clear();
31 | }
32 | else {
33 | document.addEventListener("visibilitychange", () =>
34 | {
35 | if (document.visibilityState != 'hidden' && !initialized)
36 | {
37 | init();
38 | }
39 | });
40 |
41 | window.onload = () => {
42 | if (document.visibilityState != 'hidden')
43 | {
44 | initialized = true;
45 | init();
46 |
47 | }
48 | };
49 |
50 | const init = () => {
51 | setTimeout(() => {
52 | paintScene()
53 | setupWindowManager();
54 | resize();
55 | updateWindowShape(false);
56 | animate();
57 | window.addEventListener('resize', resize);
58 | }, 300)
59 | }
60 |
61 | const paintScene = () => {
62 | camera = new THREE.OrthographicCamera( window.innerWidth/-2, window.innerWidth/2, window.innerHeight/-2, window.innerHeight/2, 1, 1000);
63 | camera.position.z = 2.5;
64 | near = camera.position.z - .5;
65 | far = camera.position.z + 0.5;
66 |
67 | scene = new THREE.Scene();
68 | scene.add( camera );
69 |
70 | renderer = new THREE.WebGLRenderer({antialias: true, depthBuffer: true});
71 | renderer.setPixelRatio(window.devicePixelRatio ? window.devicePixelRatio : 1);
72 | renderer.setClearColor("lightblue");
73 |
74 | const loader = new GLTFLoader();
75 | loader.load('/coral_fort_wall_02_2k.gltf/coral_fort_wall_02_2k.gltf', (th) => {
76 | const text = th.scene.children[0].material.map;
77 | scene.background = text
78 | });
79 |
80 |
81 | world = new THREE.Object3D();
82 | scene.add(world);
83 |
84 | const ambientLight = new THREE.AmbientLight('white', 1);
85 | scene.add(ambientLight)
86 |
87 | const directionalLight = new THREE.DirectionalLight('white', 4);
88 | scene.add(directionalLight);
89 |
90 | renderer.domElement.setAttribute("id", "scene");
91 | document.body.appendChild( renderer.domElement );
92 | }
93 |
94 | const updateWindowShape = (easing = true)=> {
95 | sceneOffsetTarget = {x: -window.screenX, y: -window.screenY};
96 | if (!easing) sceneOffset = sceneOffsetTarget;
97 | }
98 |
99 | const setupWindowManager = ()=> {
100 | windowManager = new WindowManager();
101 | windowManager.setWinShapeChangeCallback(updateWindowShape);
102 | windowManager.setWinChangeCallback(updateWindow);
103 |
104 | let metaData = {foo: "bar"};
105 | windowManager.init(metaData);
106 | updateWindow();
107 | }
108 |
109 | const updateWindow =()=> {
110 | updateNumberOfobjs();
111 | }
112 |
113 | const updateNumberOfobjs = ()=> {
114 | let wins = windowManager.getWindows();
115 | objs.forEach((c) => {
116 | world.remove(c);
117 | })
118 | objs = [];
119 | for (let i = 0; i < wins.length; i++)
120 | {
121 | let win = wins[i];
122 |
123 | let color = new THREE.Color();
124 | color.setHSL(i * .1, 1.0, .5);
125 | let shape = 100 + i * 2;
126 | let obj = new THREE.Mesh(new THREE.TorusGeometry(shape, 30, shape), new THREE.MeshPhongMaterial({color: color, wireframe:true }));
127 | obj.position.x = win.shape.x + (win.shape.w * .5);
128 | obj.position.y = win.shape.y + (win.shape.h * .5);
129 | world.add(obj);
130 | objs.push(obj);
131 | }
132 | }
133 |
134 | function animate () {
135 | let time = getTime();
136 | windowManager.update();
137 | let falloff = 0.5;
138 | sceneOffset.x = sceneOffset.x + ((sceneOffsetTarget.x - sceneOffset.x) * falloff);
139 | sceneOffset.y = sceneOffset.y + ((sceneOffsetTarget.y - sceneOffset.y) * falloff);
140 |
141 | world.position.x = sceneOffset.x;
142 | world.position.y = sceneOffset.y;
143 |
144 | let wins = windowManager.getWindows();
145 | for (let i = 0; i < objs.length; i++) {
146 | let obj = objs[i];
147 | let win = wins[i];
148 | let posTarget = {x: win.shape.x + (win.shape.w * .5), y: win.shape.y + (win.shape.h * .5)}
149 | obj.position.x = obj.position.x + (posTarget.x - obj.position.x) * falloff;
150 | obj.position.y = obj.position.y + (posTarget.y - obj.position.y) * falloff;
151 | obj.rotation.y = time * 1;
152 | };
153 | renderer.render(scene, camera);
154 | requestAnimationFrame(animate)
155 | }
156 |
157 |
158 |
159 | function resize ()
160 | {
161 | let width = window.innerWidth;
162 | let height = window.innerHeight
163 |
164 | camera = new THREE.OrthographicCamera(0, width, 0, height, -10000, 10000);
165 | camera.updateProjectionMatrix();
166 | renderer.setSize( width, height );
167 | }
168 | }
--------------------------------------------------------------------------------
/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "multi-window",
3 | "version": "0.0.0",
4 | "lockfileVersion": 2,
5 | "requires": true,
6 | "packages": {
7 | "": {
8 | "name": "multi-window",
9 | "version": "0.0.0",
10 | "dependencies": {
11 | "three": "^0.158.0"
12 | },
13 | "devDependencies": {
14 | "vite": "^5.0.0"
15 | }
16 | },
17 | "node_modules/@esbuild/android-arm": {
18 | "version": "0.19.7",
19 | "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.19.7.tgz",
20 | "integrity": "sha512-YGSPnndkcLo4PmVl2tKatEn+0mlVMr3yEpOOT0BeMria87PhvoJb5dg5f5Ft9fbCVgtAz4pWMzZVgSEGpDAlww==",
21 | "cpu": [
22 | "arm"
23 | ],
24 | "dev": true,
25 | "optional": true,
26 | "os": [
27 | "android"
28 | ],
29 | "engines": {
30 | "node": ">=12"
31 | }
32 | },
33 | "node_modules/@esbuild/android-arm64": {
34 | "version": "0.19.7",
35 | "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.19.7.tgz",
36 | "integrity": "sha512-YEDcw5IT7hW3sFKZBkCAQaOCJQLONVcD4bOyTXMZz5fr66pTHnAet46XAtbXAkJRfIn2YVhdC6R9g4xa27jQ1w==",
37 | "cpu": [
38 | "arm64"
39 | ],
40 | "dev": true,
41 | "optional": true,
42 | "os": [
43 | "android"
44 | ],
45 | "engines": {
46 | "node": ">=12"
47 | }
48 | },
49 | "node_modules/@esbuild/android-x64": {
50 | "version": "0.19.7",
51 | "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.19.7.tgz",
52 | "integrity": "sha512-jhINx8DEjz68cChFvM72YzrqfwJuFbfvSxZAk4bebpngGfNNRm+zRl4rtT9oAX6N9b6gBcFaJHFew5Blf6CvUw==",
53 | "cpu": [
54 | "x64"
55 | ],
56 | "dev": true,
57 | "optional": true,
58 | "os": [
59 | "android"
60 | ],
61 | "engines": {
62 | "node": ">=12"
63 | }
64 | },
65 | "node_modules/@esbuild/darwin-arm64": {
66 | "version": "0.19.7",
67 | "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.19.7.tgz",
68 | "integrity": "sha512-dr81gbmWN//3ZnBIm6YNCl4p3pjnabg1/ZVOgz2fJoUO1a3mq9WQ/1iuEluMs7mCL+Zwv7AY5e3g1hjXqQZ9Iw==",
69 | "cpu": [
70 | "arm64"
71 | ],
72 | "dev": true,
73 | "optional": true,
74 | "os": [
75 | "darwin"
76 | ],
77 | "engines": {
78 | "node": ">=12"
79 | }
80 | },
81 | "node_modules/@esbuild/darwin-x64": {
82 | "version": "0.19.7",
83 | "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.19.7.tgz",
84 | "integrity": "sha512-Lc0q5HouGlzQEwLkgEKnWcSazqr9l9OdV2HhVasWJzLKeOt0PLhHaUHuzb8s/UIya38DJDoUm74GToZ6Wc7NGQ==",
85 | "cpu": [
86 | "x64"
87 | ],
88 | "dev": true,
89 | "optional": true,
90 | "os": [
91 | "darwin"
92 | ],
93 | "engines": {
94 | "node": ">=12"
95 | }
96 | },
97 | "node_modules/@esbuild/freebsd-arm64": {
98 | "version": "0.19.7",
99 | "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.7.tgz",
100 | "integrity": "sha512-+y2YsUr0CxDFF7GWiegWjGtTUF6gac2zFasfFkRJPkMAuMy9O7+2EH550VlqVdpEEchWMynkdhC9ZjtnMiHImQ==",
101 | "cpu": [
102 | "arm64"
103 | ],
104 | "dev": true,
105 | "optional": true,
106 | "os": [
107 | "freebsd"
108 | ],
109 | "engines": {
110 | "node": ">=12"
111 | }
112 | },
113 | "node_modules/@esbuild/freebsd-x64": {
114 | "version": "0.19.7",
115 | "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.19.7.tgz",
116 | "integrity": "sha512-CdXOxIbIzPJmJhrpmJTLx+o35NoiKBIgOvmvT+jeSadYiWJn0vFKsl+0bSG/5lwjNHoIDEyMYc/GAPR9jxusTA==",
117 | "cpu": [
118 | "x64"
119 | ],
120 | "dev": true,
121 | "optional": true,
122 | "os": [
123 | "freebsd"
124 | ],
125 | "engines": {
126 | "node": ">=12"
127 | }
128 | },
129 | "node_modules/@esbuild/linux-arm": {
130 | "version": "0.19.7",
131 | "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.19.7.tgz",
132 | "integrity": "sha512-Y+SCmWxsJOdQtjcBxoacn/pGW9HDZpwsoof0ttL+2vGcHokFlfqV666JpfLCSP2xLxFpF1lj7T3Ox3sr95YXww==",
133 | "cpu": [
134 | "arm"
135 | ],
136 | "dev": true,
137 | "optional": true,
138 | "os": [
139 | "linux"
140 | ],
141 | "engines": {
142 | "node": ">=12"
143 | }
144 | },
145 | "node_modules/@esbuild/linux-arm64": {
146 | "version": "0.19.7",
147 | "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.19.7.tgz",
148 | "integrity": "sha512-inHqdOVCkUhHNvuQPT1oCB7cWz9qQ/Cz46xmVe0b7UXcuIJU3166aqSunsqkgSGMtUCWOZw3+KMwI6otINuC9g==",
149 | "cpu": [
150 | "arm64"
151 | ],
152 | "dev": true,
153 | "optional": true,
154 | "os": [
155 | "linux"
156 | ],
157 | "engines": {
158 | "node": ">=12"
159 | }
160 | },
161 | "node_modules/@esbuild/linux-ia32": {
162 | "version": "0.19.7",
163 | "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.19.7.tgz",
164 | "integrity": "sha512-2BbiL7nLS5ZO96bxTQkdO0euGZIUQEUXMTrqLxKUmk/Y5pmrWU84f+CMJpM8+EHaBPfFSPnomEaQiG/+Gmh61g==",
165 | "cpu": [
166 | "ia32"
167 | ],
168 | "dev": true,
169 | "optional": true,
170 | "os": [
171 | "linux"
172 | ],
173 | "engines": {
174 | "node": ">=12"
175 | }
176 | },
177 | "node_modules/@esbuild/linux-loong64": {
178 | "version": "0.19.7",
179 | "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.19.7.tgz",
180 | "integrity": "sha512-BVFQla72KXv3yyTFCQXF7MORvpTo4uTA8FVFgmwVrqbB/4DsBFWilUm1i2Oq6zN36DOZKSVUTb16jbjedhfSHw==",
181 | "cpu": [
182 | "loong64"
183 | ],
184 | "dev": true,
185 | "optional": true,
186 | "os": [
187 | "linux"
188 | ],
189 | "engines": {
190 | "node": ">=12"
191 | }
192 | },
193 | "node_modules/@esbuild/linux-mips64el": {
194 | "version": "0.19.7",
195 | "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.19.7.tgz",
196 | "integrity": "sha512-DzAYckIaK+pS31Q/rGpvUKu7M+5/t+jI+cdleDgUwbU7KdG2eC3SUbZHlo6Q4P1CfVKZ1lUERRFP8+q0ob9i2w==",
197 | "cpu": [
198 | "mips64el"
199 | ],
200 | "dev": true,
201 | "optional": true,
202 | "os": [
203 | "linux"
204 | ],
205 | "engines": {
206 | "node": ">=12"
207 | }
208 | },
209 | "node_modules/@esbuild/linux-ppc64": {
210 | "version": "0.19.7",
211 | "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.19.7.tgz",
212 | "integrity": "sha512-JQ1p0SmUteNdUaaiRtyS59GkkfTW0Edo+e0O2sihnY4FoZLz5glpWUQEKMSzMhA430ctkylkS7+vn8ziuhUugQ==",
213 | "cpu": [
214 | "ppc64"
215 | ],
216 | "dev": true,
217 | "optional": true,
218 | "os": [
219 | "linux"
220 | ],
221 | "engines": {
222 | "node": ">=12"
223 | }
224 | },
225 | "node_modules/@esbuild/linux-riscv64": {
226 | "version": "0.19.7",
227 | "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.19.7.tgz",
228 | "integrity": "sha512-xGwVJ7eGhkprY/nB7L7MXysHduqjpzUl40+XoYDGC4UPLbnG+gsyS1wQPJ9lFPcxYAaDXbdRXd1ACs9AE9lxuw==",
229 | "cpu": [
230 | "riscv64"
231 | ],
232 | "dev": true,
233 | "optional": true,
234 | "os": [
235 | "linux"
236 | ],
237 | "engines": {
238 | "node": ">=12"
239 | }
240 | },
241 | "node_modules/@esbuild/linux-s390x": {
242 | "version": "0.19.7",
243 | "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.19.7.tgz",
244 | "integrity": "sha512-U8Rhki5PVU0L0nvk+E8FjkV8r4Lh4hVEb9duR6Zl21eIEYEwXz8RScj4LZWA2i3V70V4UHVgiqMpszXvG0Yqhg==",
245 | "cpu": [
246 | "s390x"
247 | ],
248 | "dev": true,
249 | "optional": true,
250 | "os": [
251 | "linux"
252 | ],
253 | "engines": {
254 | "node": ">=12"
255 | }
256 | },
257 | "node_modules/@esbuild/linux-x64": {
258 | "version": "0.19.7",
259 | "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.19.7.tgz",
260 | "integrity": "sha512-ZYZopyLhm4mcoZXjFt25itRlocKlcazDVkB4AhioiL9hOWhDldU9n38g62fhOI4Pth6vp+Mrd5rFKxD0/S+7aQ==",
261 | "cpu": [
262 | "x64"
263 | ],
264 | "dev": true,
265 | "optional": true,
266 | "os": [
267 | "linux"
268 | ],
269 | "engines": {
270 | "node": ">=12"
271 | }
272 | },
273 | "node_modules/@esbuild/netbsd-x64": {
274 | "version": "0.19.7",
275 | "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.19.7.tgz",
276 | "integrity": "sha512-/yfjlsYmT1O3cum3J6cmGG16Fd5tqKMcg5D+sBYLaOQExheAJhqr8xOAEIuLo8JYkevmjM5zFD9rVs3VBcsjtQ==",
277 | "cpu": [
278 | "x64"
279 | ],
280 | "dev": true,
281 | "optional": true,
282 | "os": [
283 | "netbsd"
284 | ],
285 | "engines": {
286 | "node": ">=12"
287 | }
288 | },
289 | "node_modules/@esbuild/openbsd-x64": {
290 | "version": "0.19.7",
291 | "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.19.7.tgz",
292 | "integrity": "sha512-MYDFyV0EW1cTP46IgUJ38OnEY5TaXxjoDmwiTXPjezahQgZd+j3T55Ht8/Q9YXBM0+T9HJygrSRGV5QNF/YVDQ==",
293 | "cpu": [
294 | "x64"
295 | ],
296 | "dev": true,
297 | "optional": true,
298 | "os": [
299 | "openbsd"
300 | ],
301 | "engines": {
302 | "node": ">=12"
303 | }
304 | },
305 | "node_modules/@esbuild/sunos-x64": {
306 | "version": "0.19.7",
307 | "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.19.7.tgz",
308 | "integrity": "sha512-JcPvgzf2NN/y6X3UUSqP6jSS06V0DZAV/8q0PjsZyGSXsIGcG110XsdmuWiHM+pno7/mJF6fjH5/vhUz/vA9fw==",
309 | "cpu": [
310 | "x64"
311 | ],
312 | "dev": true,
313 | "optional": true,
314 | "os": [
315 | "sunos"
316 | ],
317 | "engines": {
318 | "node": ">=12"
319 | }
320 | },
321 | "node_modules/@esbuild/win32-arm64": {
322 | "version": "0.19.7",
323 | "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.19.7.tgz",
324 | "integrity": "sha512-ZA0KSYti5w5toax5FpmfcAgu3ZNJxYSRm0AW/Dao5up0YV1hDVof1NvwLomjEN+3/GMtaWDI+CIyJOMTRSTdMw==",
325 | "cpu": [
326 | "arm64"
327 | ],
328 | "dev": true,
329 | "optional": true,
330 | "os": [
331 | "win32"
332 | ],
333 | "engines": {
334 | "node": ">=12"
335 | }
336 | },
337 | "node_modules/@esbuild/win32-ia32": {
338 | "version": "0.19.7",
339 | "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.19.7.tgz",
340 | "integrity": "sha512-CTOnijBKc5Jpk6/W9hQMMvJnsSYRYgveN6O75DTACCY18RA2nqka8dTZR+x/JqXCRiKk84+5+bRKXUSbbwsS0A==",
341 | "cpu": [
342 | "ia32"
343 | ],
344 | "dev": true,
345 | "optional": true,
346 | "os": [
347 | "win32"
348 | ],
349 | "engines": {
350 | "node": ">=12"
351 | }
352 | },
353 | "node_modules/@esbuild/win32-x64": {
354 | "version": "0.19.7",
355 | "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.19.7.tgz",
356 | "integrity": "sha512-gRaP2sk6hc98N734luX4VpF318l3w+ofrtTu9j5L8EQXF+FzQKV6alCOHMVoJJHvVK/mGbwBXfOL1HETQu9IGQ==",
357 | "cpu": [
358 | "x64"
359 | ],
360 | "dev": true,
361 | "optional": true,
362 | "os": [
363 | "win32"
364 | ],
365 | "engines": {
366 | "node": ">=12"
367 | }
368 | },
369 | "node_modules/@rollup/rollup-android-arm-eabi": {
370 | "version": "4.5.1",
371 | "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.5.1.tgz",
372 | "integrity": "sha512-YaN43wTyEBaMqLDYeze+gQ4ZrW5RbTEGtT5o1GVDkhpdNcsLTnLRcLccvwy3E9wiDKWg9RIhuoy3JQKDRBfaZA==",
373 | "cpu": [
374 | "arm"
375 | ],
376 | "dev": true,
377 | "optional": true,
378 | "os": [
379 | "android"
380 | ]
381 | },
382 | "node_modules/@rollup/rollup-android-arm64": {
383 | "version": "4.5.1",
384 | "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.5.1.tgz",
385 | "integrity": "sha512-n1bX+LCGlQVuPlCofO0zOKe1b2XkFozAVRoczT+yxWZPGnkEAKTTYVOGZz8N4sKuBnKMxDbfhUsB1uwYdup/sw==",
386 | "cpu": [
387 | "arm64"
388 | ],
389 | "dev": true,
390 | "optional": true,
391 | "os": [
392 | "android"
393 | ]
394 | },
395 | "node_modules/@rollup/rollup-darwin-arm64": {
396 | "version": "4.5.1",
397 | "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.5.1.tgz",
398 | "integrity": "sha512-QqJBumdvfBqBBmyGHlKxje+iowZwrHna7pokj/Go3dV1PJekSKfmjKrjKQ/e6ESTGhkfPNLq3VXdYLAc+UtAQw==",
399 | "cpu": [
400 | "arm64"
401 | ],
402 | "dev": true,
403 | "optional": true,
404 | "os": [
405 | "darwin"
406 | ]
407 | },
408 | "node_modules/@rollup/rollup-darwin-x64": {
409 | "version": "4.5.1",
410 | "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.5.1.tgz",
411 | "integrity": "sha512-RrkDNkR/P5AEQSPkxQPmd2ri8WTjSl0RYmuFOiEABkEY/FSg0a4riihWQGKDJ4LnV9gigWZlTMx2DtFGzUrYQw==",
412 | "cpu": [
413 | "x64"
414 | ],
415 | "dev": true,
416 | "optional": true,
417 | "os": [
418 | "darwin"
419 | ]
420 | },
421 | "node_modules/@rollup/rollup-linux-arm-gnueabihf": {
422 | "version": "4.5.1",
423 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.5.1.tgz",
424 | "integrity": "sha512-ZFPxvUZmE+fkB/8D9y/SWl/XaDzNSaxd1TJUSE27XAKlRpQ2VNce/86bGd9mEUgL3qrvjJ9XTGwoX0BrJkYK/A==",
425 | "cpu": [
426 | "arm"
427 | ],
428 | "dev": true,
429 | "optional": true,
430 | "os": [
431 | "linux"
432 | ]
433 | },
434 | "node_modules/@rollup/rollup-linux-arm64-gnu": {
435 | "version": "4.5.1",
436 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.5.1.tgz",
437 | "integrity": "sha512-FEuAjzVIld5WVhu+M2OewLmjmbXWd3q7Zcx+Rwy4QObQCqfblriDMMS7p7+pwgjZoo9BLkP3wa9uglQXzsB9ww==",
438 | "cpu": [
439 | "arm64"
440 | ],
441 | "dev": true,
442 | "optional": true,
443 | "os": [
444 | "linux"
445 | ]
446 | },
447 | "node_modules/@rollup/rollup-linux-arm64-musl": {
448 | "version": "4.5.1",
449 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.5.1.tgz",
450 | "integrity": "sha512-f5Gs8WQixqGRtI0Iq/cMqvFYmgFzMinuJO24KRfnv7Ohi/HQclwrBCYkzQu1XfLEEt3DZyvveq9HWo4bLJf1Lw==",
451 | "cpu": [
452 | "arm64"
453 | ],
454 | "dev": true,
455 | "optional": true,
456 | "os": [
457 | "linux"
458 | ]
459 | },
460 | "node_modules/@rollup/rollup-linux-x64-gnu": {
461 | "version": "4.5.1",
462 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.5.1.tgz",
463 | "integrity": "sha512-CWPkPGrFfN2vj3mw+S7A/4ZaU3rTV7AkXUr08W9lNP+UzOvKLVf34tWCqrKrfwQ0NTk5GFqUr2XGpeR2p6R4gw==",
464 | "cpu": [
465 | "x64"
466 | ],
467 | "dev": true,
468 | "optional": true,
469 | "os": [
470 | "linux"
471 | ]
472 | },
473 | "node_modules/@rollup/rollup-linux-x64-musl": {
474 | "version": "4.5.1",
475 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.5.1.tgz",
476 | "integrity": "sha512-ZRETMFA0uVukUC9u31Ed1nx++29073goCxZtmZARwk5aF/ltuENaeTtRVsSQzFlzdd4J6L3qUm+EW8cbGt0CKQ==",
477 | "cpu": [
478 | "x64"
479 | ],
480 | "dev": true,
481 | "optional": true,
482 | "os": [
483 | "linux"
484 | ]
485 | },
486 | "node_modules/@rollup/rollup-win32-arm64-msvc": {
487 | "version": "4.5.1",
488 | "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.5.1.tgz",
489 | "integrity": "sha512-ihqfNJNb2XtoZMSCPeoo0cYMgU04ksyFIoOw5S0JUVbOhafLot+KD82vpKXOurE2+9o/awrqIxku9MRR9hozHQ==",
490 | "cpu": [
491 | "arm64"
492 | ],
493 | "dev": true,
494 | "optional": true,
495 | "os": [
496 | "win32"
497 | ]
498 | },
499 | "node_modules/@rollup/rollup-win32-ia32-msvc": {
500 | "version": "4.5.1",
501 | "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.5.1.tgz",
502 | "integrity": "sha512-zK9MRpC8946lQ9ypFn4gLpdwr5a01aQ/odiIJeL9EbgZDMgbZjjT/XzTqJvDfTmnE1kHdbG20sAeNlpc91/wbg==",
503 | "cpu": [
504 | "ia32"
505 | ],
506 | "dev": true,
507 | "optional": true,
508 | "os": [
509 | "win32"
510 | ]
511 | },
512 | "node_modules/@rollup/rollup-win32-x64-msvc": {
513 | "version": "4.5.1",
514 | "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.5.1.tgz",
515 | "integrity": "sha512-5I3Nz4Sb9TYOtkRwlH0ow+BhMH2vnh38tZ4J4mggE48M/YyJyp/0sPSxhw1UeS1+oBgQ8q7maFtSeKpeRJu41Q==",
516 | "cpu": [
517 | "x64"
518 | ],
519 | "dev": true,
520 | "optional": true,
521 | "os": [
522 | "win32"
523 | ]
524 | },
525 | "node_modules/esbuild": {
526 | "version": "0.19.7",
527 | "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.19.7.tgz",
528 | "integrity": "sha512-6brbTZVqxhqgbpqBR5MzErImcpA0SQdoKOkcWK/U30HtQxnokIpG3TX2r0IJqbFUzqLjhU/zC1S5ndgakObVCQ==",
529 | "dev": true,
530 | "hasInstallScript": true,
531 | "bin": {
532 | "esbuild": "bin/esbuild"
533 | },
534 | "engines": {
535 | "node": ">=12"
536 | },
537 | "optionalDependencies": {
538 | "@esbuild/android-arm": "0.19.7",
539 | "@esbuild/android-arm64": "0.19.7",
540 | "@esbuild/android-x64": "0.19.7",
541 | "@esbuild/darwin-arm64": "0.19.7",
542 | "@esbuild/darwin-x64": "0.19.7",
543 | "@esbuild/freebsd-arm64": "0.19.7",
544 | "@esbuild/freebsd-x64": "0.19.7",
545 | "@esbuild/linux-arm": "0.19.7",
546 | "@esbuild/linux-arm64": "0.19.7",
547 | "@esbuild/linux-ia32": "0.19.7",
548 | "@esbuild/linux-loong64": "0.19.7",
549 | "@esbuild/linux-mips64el": "0.19.7",
550 | "@esbuild/linux-ppc64": "0.19.7",
551 | "@esbuild/linux-riscv64": "0.19.7",
552 | "@esbuild/linux-s390x": "0.19.7",
553 | "@esbuild/linux-x64": "0.19.7",
554 | "@esbuild/netbsd-x64": "0.19.7",
555 | "@esbuild/openbsd-x64": "0.19.7",
556 | "@esbuild/sunos-x64": "0.19.7",
557 | "@esbuild/win32-arm64": "0.19.7",
558 | "@esbuild/win32-ia32": "0.19.7",
559 | "@esbuild/win32-x64": "0.19.7"
560 | }
561 | },
562 | "node_modules/fsevents": {
563 | "version": "2.3.3",
564 | "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
565 | "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
566 | "dev": true,
567 | "hasInstallScript": true,
568 | "optional": true,
569 | "os": [
570 | "darwin"
571 | ],
572 | "engines": {
573 | "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
574 | }
575 | },
576 | "node_modules/nanoid": {
577 | "version": "3.3.7",
578 | "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz",
579 | "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==",
580 | "dev": true,
581 | "funding": [
582 | {
583 | "type": "github",
584 | "url": "https://github.com/sponsors/ai"
585 | }
586 | ],
587 | "bin": {
588 | "nanoid": "bin/nanoid.cjs"
589 | },
590 | "engines": {
591 | "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
592 | }
593 | },
594 | "node_modules/picocolors": {
595 | "version": "1.0.0",
596 | "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
597 | "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==",
598 | "dev": true
599 | },
600 | "node_modules/postcss": {
601 | "version": "8.4.31",
602 | "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz",
603 | "integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==",
604 | "dev": true,
605 | "funding": [
606 | {
607 | "type": "opencollective",
608 | "url": "https://opencollective.com/postcss/"
609 | },
610 | {
611 | "type": "tidelift",
612 | "url": "https://tidelift.com/funding/github/npm/postcss"
613 | },
614 | {
615 | "type": "github",
616 | "url": "https://github.com/sponsors/ai"
617 | }
618 | ],
619 | "dependencies": {
620 | "nanoid": "^3.3.6",
621 | "picocolors": "^1.0.0",
622 | "source-map-js": "^1.0.2"
623 | },
624 | "engines": {
625 | "node": "^10 || ^12 || >=14"
626 | }
627 | },
628 | "node_modules/rollup": {
629 | "version": "4.5.1",
630 | "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.5.1.tgz",
631 | "integrity": "sha512-0EQribZoPKpb5z1NW/QYm3XSR//Xr8BeEXU49Lc/mQmpmVVG5jPUVrpc2iptup/0WMrY9mzas0fxH+TjYvG2CA==",
632 | "dev": true,
633 | "bin": {
634 | "rollup": "dist/bin/rollup"
635 | },
636 | "engines": {
637 | "node": ">=18.0.0",
638 | "npm": ">=8.0.0"
639 | },
640 | "optionalDependencies": {
641 | "@rollup/rollup-android-arm-eabi": "4.5.1",
642 | "@rollup/rollup-android-arm64": "4.5.1",
643 | "@rollup/rollup-darwin-arm64": "4.5.1",
644 | "@rollup/rollup-darwin-x64": "4.5.1",
645 | "@rollup/rollup-linux-arm-gnueabihf": "4.5.1",
646 | "@rollup/rollup-linux-arm64-gnu": "4.5.1",
647 | "@rollup/rollup-linux-arm64-musl": "4.5.1",
648 | "@rollup/rollup-linux-x64-gnu": "4.5.1",
649 | "@rollup/rollup-linux-x64-musl": "4.5.1",
650 | "@rollup/rollup-win32-arm64-msvc": "4.5.1",
651 | "@rollup/rollup-win32-ia32-msvc": "4.5.1",
652 | "@rollup/rollup-win32-x64-msvc": "4.5.1",
653 | "fsevents": "~2.3.2"
654 | }
655 | },
656 | "node_modules/source-map-js": {
657 | "version": "1.0.2",
658 | "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz",
659 | "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==",
660 | "dev": true,
661 | "engines": {
662 | "node": ">=0.10.0"
663 | }
664 | },
665 | "node_modules/three": {
666 | "version": "0.158.0",
667 | "resolved": "https://registry.npmjs.org/three/-/three-0.158.0.tgz",
668 | "integrity": "sha512-TALj4EOpdDPF1henk2Q+s17K61uEAAWQ7TJB68nr7FKxqwyDr3msOt5IWdbGm4TaWKjrtWS8DJJWe9JnvsWOhQ=="
669 | },
670 | "node_modules/vite": {
671 | "version": "5.0.2",
672 | "resolved": "https://registry.npmjs.org/vite/-/vite-5.0.2.tgz",
673 | "integrity": "sha512-6CCq1CAJCNM1ya2ZZA7+jS2KgnhbzvxakmlIjN24cF/PXhRMzpM/z8QgsVJA/Dm5fWUWnVEsmtBoMhmerPxT0g==",
674 | "dev": true,
675 | "dependencies": {
676 | "esbuild": "^0.19.3",
677 | "postcss": "^8.4.31",
678 | "rollup": "^4.2.0"
679 | },
680 | "bin": {
681 | "vite": "bin/vite.js"
682 | },
683 | "engines": {
684 | "node": "^18.0.0 || >=20.0.0"
685 | },
686 | "funding": {
687 | "url": "https://github.com/vitejs/vite?sponsor=1"
688 | },
689 | "optionalDependencies": {
690 | "fsevents": "~2.3.3"
691 | },
692 | "peerDependencies": {
693 | "@types/node": "^18.0.0 || >=20.0.0",
694 | "less": "*",
695 | "lightningcss": "^1.21.0",
696 | "sass": "*",
697 | "stylus": "*",
698 | "sugarss": "*",
699 | "terser": "^5.4.0"
700 | },
701 | "peerDependenciesMeta": {
702 | "@types/node": {
703 | "optional": true
704 | },
705 | "less": {
706 | "optional": true
707 | },
708 | "lightningcss": {
709 | "optional": true
710 | },
711 | "sass": {
712 | "optional": true
713 | },
714 | "stylus": {
715 | "optional": true
716 | },
717 | "sugarss": {
718 | "optional": true
719 | },
720 | "terser": {
721 | "optional": true
722 | }
723 | }
724 | }
725 | },
726 | "dependencies": {
727 | "@esbuild/android-arm": {
728 | "version": "0.19.7",
729 | "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.19.7.tgz",
730 | "integrity": "sha512-YGSPnndkcLo4PmVl2tKatEn+0mlVMr3yEpOOT0BeMria87PhvoJb5dg5f5Ft9fbCVgtAz4pWMzZVgSEGpDAlww==",
731 | "dev": true,
732 | "optional": true
733 | },
734 | "@esbuild/android-arm64": {
735 | "version": "0.19.7",
736 | "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.19.7.tgz",
737 | "integrity": "sha512-YEDcw5IT7hW3sFKZBkCAQaOCJQLONVcD4bOyTXMZz5fr66pTHnAet46XAtbXAkJRfIn2YVhdC6R9g4xa27jQ1w==",
738 | "dev": true,
739 | "optional": true
740 | },
741 | "@esbuild/android-x64": {
742 | "version": "0.19.7",
743 | "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.19.7.tgz",
744 | "integrity": "sha512-jhINx8DEjz68cChFvM72YzrqfwJuFbfvSxZAk4bebpngGfNNRm+zRl4rtT9oAX6N9b6gBcFaJHFew5Blf6CvUw==",
745 | "dev": true,
746 | "optional": true
747 | },
748 | "@esbuild/darwin-arm64": {
749 | "version": "0.19.7",
750 | "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.19.7.tgz",
751 | "integrity": "sha512-dr81gbmWN//3ZnBIm6YNCl4p3pjnabg1/ZVOgz2fJoUO1a3mq9WQ/1iuEluMs7mCL+Zwv7AY5e3g1hjXqQZ9Iw==",
752 | "dev": true,
753 | "optional": true
754 | },
755 | "@esbuild/darwin-x64": {
756 | "version": "0.19.7",
757 | "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.19.7.tgz",
758 | "integrity": "sha512-Lc0q5HouGlzQEwLkgEKnWcSazqr9l9OdV2HhVasWJzLKeOt0PLhHaUHuzb8s/UIya38DJDoUm74GToZ6Wc7NGQ==",
759 | "dev": true,
760 | "optional": true
761 | },
762 | "@esbuild/freebsd-arm64": {
763 | "version": "0.19.7",
764 | "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.7.tgz",
765 | "integrity": "sha512-+y2YsUr0CxDFF7GWiegWjGtTUF6gac2zFasfFkRJPkMAuMy9O7+2EH550VlqVdpEEchWMynkdhC9ZjtnMiHImQ==",
766 | "dev": true,
767 | "optional": true
768 | },
769 | "@esbuild/freebsd-x64": {
770 | "version": "0.19.7",
771 | "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.19.7.tgz",
772 | "integrity": "sha512-CdXOxIbIzPJmJhrpmJTLx+o35NoiKBIgOvmvT+jeSadYiWJn0vFKsl+0bSG/5lwjNHoIDEyMYc/GAPR9jxusTA==",
773 | "dev": true,
774 | "optional": true
775 | },
776 | "@esbuild/linux-arm": {
777 | "version": "0.19.7",
778 | "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.19.7.tgz",
779 | "integrity": "sha512-Y+SCmWxsJOdQtjcBxoacn/pGW9HDZpwsoof0ttL+2vGcHokFlfqV666JpfLCSP2xLxFpF1lj7T3Ox3sr95YXww==",
780 | "dev": true,
781 | "optional": true
782 | },
783 | "@esbuild/linux-arm64": {
784 | "version": "0.19.7",
785 | "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.19.7.tgz",
786 | "integrity": "sha512-inHqdOVCkUhHNvuQPT1oCB7cWz9qQ/Cz46xmVe0b7UXcuIJU3166aqSunsqkgSGMtUCWOZw3+KMwI6otINuC9g==",
787 | "dev": true,
788 | "optional": true
789 | },
790 | "@esbuild/linux-ia32": {
791 | "version": "0.19.7",
792 | "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.19.7.tgz",
793 | "integrity": "sha512-2BbiL7nLS5ZO96bxTQkdO0euGZIUQEUXMTrqLxKUmk/Y5pmrWU84f+CMJpM8+EHaBPfFSPnomEaQiG/+Gmh61g==",
794 | "dev": true,
795 | "optional": true
796 | },
797 | "@esbuild/linux-loong64": {
798 | "version": "0.19.7",
799 | "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.19.7.tgz",
800 | "integrity": "sha512-BVFQla72KXv3yyTFCQXF7MORvpTo4uTA8FVFgmwVrqbB/4DsBFWilUm1i2Oq6zN36DOZKSVUTb16jbjedhfSHw==",
801 | "dev": true,
802 | "optional": true
803 | },
804 | "@esbuild/linux-mips64el": {
805 | "version": "0.19.7",
806 | "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.19.7.tgz",
807 | "integrity": "sha512-DzAYckIaK+pS31Q/rGpvUKu7M+5/t+jI+cdleDgUwbU7KdG2eC3SUbZHlo6Q4P1CfVKZ1lUERRFP8+q0ob9i2w==",
808 | "dev": true,
809 | "optional": true
810 | },
811 | "@esbuild/linux-ppc64": {
812 | "version": "0.19.7",
813 | "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.19.7.tgz",
814 | "integrity": "sha512-JQ1p0SmUteNdUaaiRtyS59GkkfTW0Edo+e0O2sihnY4FoZLz5glpWUQEKMSzMhA430ctkylkS7+vn8ziuhUugQ==",
815 | "dev": true,
816 | "optional": true
817 | },
818 | "@esbuild/linux-riscv64": {
819 | "version": "0.19.7",
820 | "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.19.7.tgz",
821 | "integrity": "sha512-xGwVJ7eGhkprY/nB7L7MXysHduqjpzUl40+XoYDGC4UPLbnG+gsyS1wQPJ9lFPcxYAaDXbdRXd1ACs9AE9lxuw==",
822 | "dev": true,
823 | "optional": true
824 | },
825 | "@esbuild/linux-s390x": {
826 | "version": "0.19.7",
827 | "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.19.7.tgz",
828 | "integrity": "sha512-U8Rhki5PVU0L0nvk+E8FjkV8r4Lh4hVEb9duR6Zl21eIEYEwXz8RScj4LZWA2i3V70V4UHVgiqMpszXvG0Yqhg==",
829 | "dev": true,
830 | "optional": true
831 | },
832 | "@esbuild/linux-x64": {
833 | "version": "0.19.7",
834 | "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.19.7.tgz",
835 | "integrity": "sha512-ZYZopyLhm4mcoZXjFt25itRlocKlcazDVkB4AhioiL9hOWhDldU9n38g62fhOI4Pth6vp+Mrd5rFKxD0/S+7aQ==",
836 | "dev": true,
837 | "optional": true
838 | },
839 | "@esbuild/netbsd-x64": {
840 | "version": "0.19.7",
841 | "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.19.7.tgz",
842 | "integrity": "sha512-/yfjlsYmT1O3cum3J6cmGG16Fd5tqKMcg5D+sBYLaOQExheAJhqr8xOAEIuLo8JYkevmjM5zFD9rVs3VBcsjtQ==",
843 | "dev": true,
844 | "optional": true
845 | },
846 | "@esbuild/openbsd-x64": {
847 | "version": "0.19.7",
848 | "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.19.7.tgz",
849 | "integrity": "sha512-MYDFyV0EW1cTP46IgUJ38OnEY5TaXxjoDmwiTXPjezahQgZd+j3T55Ht8/Q9YXBM0+T9HJygrSRGV5QNF/YVDQ==",
850 | "dev": true,
851 | "optional": true
852 | },
853 | "@esbuild/sunos-x64": {
854 | "version": "0.19.7",
855 | "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.19.7.tgz",
856 | "integrity": "sha512-JcPvgzf2NN/y6X3UUSqP6jSS06V0DZAV/8q0PjsZyGSXsIGcG110XsdmuWiHM+pno7/mJF6fjH5/vhUz/vA9fw==",
857 | "dev": true,
858 | "optional": true
859 | },
860 | "@esbuild/win32-arm64": {
861 | "version": "0.19.7",
862 | "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.19.7.tgz",
863 | "integrity": "sha512-ZA0KSYti5w5toax5FpmfcAgu3ZNJxYSRm0AW/Dao5up0YV1hDVof1NvwLomjEN+3/GMtaWDI+CIyJOMTRSTdMw==",
864 | "dev": true,
865 | "optional": true
866 | },
867 | "@esbuild/win32-ia32": {
868 | "version": "0.19.7",
869 | "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.19.7.tgz",
870 | "integrity": "sha512-CTOnijBKc5Jpk6/W9hQMMvJnsSYRYgveN6O75DTACCY18RA2nqka8dTZR+x/JqXCRiKk84+5+bRKXUSbbwsS0A==",
871 | "dev": true,
872 | "optional": true
873 | },
874 | "@esbuild/win32-x64": {
875 | "version": "0.19.7",
876 | "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.19.7.tgz",
877 | "integrity": "sha512-gRaP2sk6hc98N734luX4VpF318l3w+ofrtTu9j5L8EQXF+FzQKV6alCOHMVoJJHvVK/mGbwBXfOL1HETQu9IGQ==",
878 | "dev": true,
879 | "optional": true
880 | },
881 | "@rollup/rollup-android-arm-eabi": {
882 | "version": "4.5.1",
883 | "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.5.1.tgz",
884 | "integrity": "sha512-YaN43wTyEBaMqLDYeze+gQ4ZrW5RbTEGtT5o1GVDkhpdNcsLTnLRcLccvwy3E9wiDKWg9RIhuoy3JQKDRBfaZA==",
885 | "dev": true,
886 | "optional": true
887 | },
888 | "@rollup/rollup-android-arm64": {
889 | "version": "4.5.1",
890 | "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.5.1.tgz",
891 | "integrity": "sha512-n1bX+LCGlQVuPlCofO0zOKe1b2XkFozAVRoczT+yxWZPGnkEAKTTYVOGZz8N4sKuBnKMxDbfhUsB1uwYdup/sw==",
892 | "dev": true,
893 | "optional": true
894 | },
895 | "@rollup/rollup-darwin-arm64": {
896 | "version": "4.5.1",
897 | "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.5.1.tgz",
898 | "integrity": "sha512-QqJBumdvfBqBBmyGHlKxje+iowZwrHna7pokj/Go3dV1PJekSKfmjKrjKQ/e6ESTGhkfPNLq3VXdYLAc+UtAQw==",
899 | "dev": true,
900 | "optional": true
901 | },
902 | "@rollup/rollup-darwin-x64": {
903 | "version": "4.5.1",
904 | "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.5.1.tgz",
905 | "integrity": "sha512-RrkDNkR/P5AEQSPkxQPmd2ri8WTjSl0RYmuFOiEABkEY/FSg0a4riihWQGKDJ4LnV9gigWZlTMx2DtFGzUrYQw==",
906 | "dev": true,
907 | "optional": true
908 | },
909 | "@rollup/rollup-linux-arm-gnueabihf": {
910 | "version": "4.5.1",
911 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.5.1.tgz",
912 | "integrity": "sha512-ZFPxvUZmE+fkB/8D9y/SWl/XaDzNSaxd1TJUSE27XAKlRpQ2VNce/86bGd9mEUgL3qrvjJ9XTGwoX0BrJkYK/A==",
913 | "dev": true,
914 | "optional": true
915 | },
916 | "@rollup/rollup-linux-arm64-gnu": {
917 | "version": "4.5.1",
918 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.5.1.tgz",
919 | "integrity": "sha512-FEuAjzVIld5WVhu+M2OewLmjmbXWd3q7Zcx+Rwy4QObQCqfblriDMMS7p7+pwgjZoo9BLkP3wa9uglQXzsB9ww==",
920 | "dev": true,
921 | "optional": true
922 | },
923 | "@rollup/rollup-linux-arm64-musl": {
924 | "version": "4.5.1",
925 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.5.1.tgz",
926 | "integrity": "sha512-f5Gs8WQixqGRtI0Iq/cMqvFYmgFzMinuJO24KRfnv7Ohi/HQclwrBCYkzQu1XfLEEt3DZyvveq9HWo4bLJf1Lw==",
927 | "dev": true,
928 | "optional": true
929 | },
930 | "@rollup/rollup-linux-x64-gnu": {
931 | "version": "4.5.1",
932 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.5.1.tgz",
933 | "integrity": "sha512-CWPkPGrFfN2vj3mw+S7A/4ZaU3rTV7AkXUr08W9lNP+UzOvKLVf34tWCqrKrfwQ0NTk5GFqUr2XGpeR2p6R4gw==",
934 | "dev": true,
935 | "optional": true
936 | },
937 | "@rollup/rollup-linux-x64-musl": {
938 | "version": "4.5.1",
939 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.5.1.tgz",
940 | "integrity": "sha512-ZRETMFA0uVukUC9u31Ed1nx++29073goCxZtmZARwk5aF/ltuENaeTtRVsSQzFlzdd4J6L3qUm+EW8cbGt0CKQ==",
941 | "dev": true,
942 | "optional": true
943 | },
944 | "@rollup/rollup-win32-arm64-msvc": {
945 | "version": "4.5.1",
946 | "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.5.1.tgz",
947 | "integrity": "sha512-ihqfNJNb2XtoZMSCPeoo0cYMgU04ksyFIoOw5S0JUVbOhafLot+KD82vpKXOurE2+9o/awrqIxku9MRR9hozHQ==",
948 | "dev": true,
949 | "optional": true
950 | },
951 | "@rollup/rollup-win32-ia32-msvc": {
952 | "version": "4.5.1",
953 | "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.5.1.tgz",
954 | "integrity": "sha512-zK9MRpC8946lQ9ypFn4gLpdwr5a01aQ/odiIJeL9EbgZDMgbZjjT/XzTqJvDfTmnE1kHdbG20sAeNlpc91/wbg==",
955 | "dev": true,
956 | "optional": true
957 | },
958 | "@rollup/rollup-win32-x64-msvc": {
959 | "version": "4.5.1",
960 | "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.5.1.tgz",
961 | "integrity": "sha512-5I3Nz4Sb9TYOtkRwlH0ow+BhMH2vnh38tZ4J4mggE48M/YyJyp/0sPSxhw1UeS1+oBgQ8q7maFtSeKpeRJu41Q==",
962 | "dev": true,
963 | "optional": true
964 | },
965 | "esbuild": {
966 | "version": "0.19.7",
967 | "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.19.7.tgz",
968 | "integrity": "sha512-6brbTZVqxhqgbpqBR5MzErImcpA0SQdoKOkcWK/U30HtQxnokIpG3TX2r0IJqbFUzqLjhU/zC1S5ndgakObVCQ==",
969 | "dev": true,
970 | "requires": {
971 | "@esbuild/android-arm": "0.19.7",
972 | "@esbuild/android-arm64": "0.19.7",
973 | "@esbuild/android-x64": "0.19.7",
974 | "@esbuild/darwin-arm64": "0.19.7",
975 | "@esbuild/darwin-x64": "0.19.7",
976 | "@esbuild/freebsd-arm64": "0.19.7",
977 | "@esbuild/freebsd-x64": "0.19.7",
978 | "@esbuild/linux-arm": "0.19.7",
979 | "@esbuild/linux-arm64": "0.19.7",
980 | "@esbuild/linux-ia32": "0.19.7",
981 | "@esbuild/linux-loong64": "0.19.7",
982 | "@esbuild/linux-mips64el": "0.19.7",
983 | "@esbuild/linux-ppc64": "0.19.7",
984 | "@esbuild/linux-riscv64": "0.19.7",
985 | "@esbuild/linux-s390x": "0.19.7",
986 | "@esbuild/linux-x64": "0.19.7",
987 | "@esbuild/netbsd-x64": "0.19.7",
988 | "@esbuild/openbsd-x64": "0.19.7",
989 | "@esbuild/sunos-x64": "0.19.7",
990 | "@esbuild/win32-arm64": "0.19.7",
991 | "@esbuild/win32-ia32": "0.19.7",
992 | "@esbuild/win32-x64": "0.19.7"
993 | }
994 | },
995 | "fsevents": {
996 | "version": "2.3.3",
997 | "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
998 | "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
999 | "dev": true,
1000 | "optional": true
1001 | },
1002 | "nanoid": {
1003 | "version": "3.3.7",
1004 | "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz",
1005 | "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==",
1006 | "dev": true
1007 | },
1008 | "picocolors": {
1009 | "version": "1.0.0",
1010 | "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
1011 | "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==",
1012 | "dev": true
1013 | },
1014 | "postcss": {
1015 | "version": "8.4.31",
1016 | "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz",
1017 | "integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==",
1018 | "dev": true,
1019 | "requires": {
1020 | "nanoid": "^3.3.6",
1021 | "picocolors": "^1.0.0",
1022 | "source-map-js": "^1.0.2"
1023 | }
1024 | },
1025 | "rollup": {
1026 | "version": "4.5.1",
1027 | "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.5.1.tgz",
1028 | "integrity": "sha512-0EQribZoPKpb5z1NW/QYm3XSR//Xr8BeEXU49Lc/mQmpmVVG5jPUVrpc2iptup/0WMrY9mzas0fxH+TjYvG2CA==",
1029 | "dev": true,
1030 | "requires": {
1031 | "@rollup/rollup-android-arm-eabi": "4.5.1",
1032 | "@rollup/rollup-android-arm64": "4.5.1",
1033 | "@rollup/rollup-darwin-arm64": "4.5.1",
1034 | "@rollup/rollup-darwin-x64": "4.5.1",
1035 | "@rollup/rollup-linux-arm-gnueabihf": "4.5.1",
1036 | "@rollup/rollup-linux-arm64-gnu": "4.5.1",
1037 | "@rollup/rollup-linux-arm64-musl": "4.5.1",
1038 | "@rollup/rollup-linux-x64-gnu": "4.5.1",
1039 | "@rollup/rollup-linux-x64-musl": "4.5.1",
1040 | "@rollup/rollup-win32-arm64-msvc": "4.5.1",
1041 | "@rollup/rollup-win32-ia32-msvc": "4.5.1",
1042 | "@rollup/rollup-win32-x64-msvc": "4.5.1",
1043 | "fsevents": "~2.3.2"
1044 | }
1045 | },
1046 | "source-map-js": {
1047 | "version": "1.0.2",
1048 | "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz",
1049 | "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==",
1050 | "dev": true
1051 | },
1052 | "three": {
1053 | "version": "0.158.0",
1054 | "resolved": "https://registry.npmjs.org/three/-/three-0.158.0.tgz",
1055 | "integrity": "sha512-TALj4EOpdDPF1henk2Q+s17K61uEAAWQ7TJB68nr7FKxqwyDr3msOt5IWdbGm4TaWKjrtWS8DJJWe9JnvsWOhQ=="
1056 | },
1057 | "vite": {
1058 | "version": "5.0.2",
1059 | "resolved": "https://registry.npmjs.org/vite/-/vite-5.0.2.tgz",
1060 | "integrity": "sha512-6CCq1CAJCNM1ya2ZZA7+jS2KgnhbzvxakmlIjN24cF/PXhRMzpM/z8QgsVJA/Dm5fWUWnVEsmtBoMhmerPxT0g==",
1061 | "dev": true,
1062 | "requires": {
1063 | "esbuild": "^0.19.3",
1064 | "fsevents": "~2.3.3",
1065 | "postcss": "^8.4.31",
1066 | "rollup": "^4.2.0"
1067 | }
1068 | }
1069 | }
1070 | }
1071 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "multi-window",
3 | "private": true,
4 | "version": "0.0.0",
5 | "type": "module",
6 | "scripts": {
7 | "dev": "vite",
8 | "build": "vite build",
9 | "preview": "vite preview"
10 | },
11 | "devDependencies": {
12 | "vite": "^5.0.0"
13 | },
14 | "dependencies": {
15 | "three": "^0.158.0"
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/public/coral_fort_wall_02_2k.gltf/coral_fort_wall_02.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Akohjesse/mutli-browser-window-threejs/c6f100688f922f4c778514fe0080a7c9a617c7ce/public/coral_fort_wall_02_2k.gltf/coral_fort_wall_02.bin
--------------------------------------------------------------------------------
/public/coral_fort_wall_02_2k.gltf/coral_fort_wall_02_2k.gltf:
--------------------------------------------------------------------------------
1 | {
2 | "asset": {
3 | "generator": "Khronos glTF Blender I/O v3.2.43",
4 | "version": "2.0"
5 | },
6 | "scene": 0,
7 | "scenes": [
8 | {
9 | "name": "Scene",
10 | "nodes": [
11 | 0
12 | ]
13 | }
14 | ],
15 | "nodes": [
16 | {
17 | "mesh": 0,
18 | "name": "sphere_gltf"
19 | }
20 | ],
21 | "materials": [
22 | {
23 | "doubleSided": true,
24 | "name": "coral_fort_wall_02",
25 | "normalTexture": {
26 | "index": 0
27 | },
28 | "pbrMetallicRoughness": {
29 | "baseColorTexture": {
30 | "index": 1
31 | },
32 | "metallicFactor": 0,
33 | "metallicRoughnessTexture": {
34 | "index": 2
35 | }
36 | }
37 | }
38 | ],
39 | "meshes": [
40 | {
41 | "name": "Sphere.001",
42 | "primitives": [
43 | {
44 | "attributes": {
45 | "POSITION": 0,
46 | "NORMAL": 1,
47 | "TEXCOORD_0": 2
48 | },
49 | "indices": 3,
50 | "material": 0
51 | }
52 | ]
53 | }
54 | ],
55 | "textures": [
56 | {
57 | "sampler": 0,
58 | "source": 0
59 | },
60 | {
61 | "sampler": 0,
62 | "source": 1
63 | },
64 | {
65 | "sampler": 0,
66 | "source": 2
67 | }
68 | ],
69 | "images": [
70 | {
71 | "mimeType": "image/jpeg",
72 | "name": "coral_fort_wall_02_nor_gl_8k",
73 | "uri": "textures/coral_fort_wall_02_nor_gl_2k.jpg"
74 | },
75 | {
76 | "mimeType": "image/jpeg",
77 | "name": "coral_fort_wall_02_diff_8k",
78 | "uri": "textures/coral_fort_wall_02_diff_2k.jpg"
79 | },
80 | {
81 | "mimeType": "image/jpeg",
82 | "name": "coral_fort_wall_02_rough_8k",
83 | "uri": "textures/coral_fort_wall_02_rough_2k.jpg"
84 | }
85 | ],
86 | "accessors": [
87 | {
88 | "bufferView": 0,
89 | "componentType": 5126,
90 | "count": 53886,
91 | "max": [
92 | 0.5066426992416382,
93 | 0.5039550065994263,
94 | 0.5038047432899475
95 | ],
96 | "min": [
97 | -0.5066428184509277,
98 | -0.5026815533638,
99 | -0.5038062930107117
100 | ],
101 | "type": "VEC3"
102 | },
103 | {
104 | "bufferView": 1,
105 | "componentType": 5126,
106 | "count": 53886,
107 | "type": "VEC3"
108 | },
109 | {
110 | "bufferView": 2,
111 | "componentType": 5126,
112 | "count": 53886,
113 | "type": "VEC2"
114 | },
115 | {
116 | "bufferView": 3,
117 | "componentType": 5123,
118 | "count": 322170,
119 | "type": "SCALAR"
120 | }
121 | ],
122 | "bufferViews": [
123 | {
124 | "buffer": 0,
125 | "byteLength": 646632,
126 | "byteOffset": 0
127 | },
128 | {
129 | "buffer": 0,
130 | "byteLength": 646632,
131 | "byteOffset": 646632
132 | },
133 | {
134 | "buffer": 0,
135 | "byteLength": 431088,
136 | "byteOffset": 1293264
137 | },
138 | {
139 | "buffer": 0,
140 | "byteLength": 644340,
141 | "byteOffset": 1724352
142 | }
143 | ],
144 | "samplers": [
145 | {
146 | "magFilter": 9729,
147 | "minFilter": 9987
148 | }
149 | ],
150 | "buffers": [
151 | {
152 | "byteLength": 2368692,
153 | "uri": "coral_fort_wall_02.bin"
154 | }
155 | ]
156 | }
--------------------------------------------------------------------------------
/public/coral_fort_wall_02_2k.gltf/textures/coral_fort_wall_02_diff_2k.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Akohjesse/mutli-browser-window-threejs/c6f100688f922f4c778514fe0080a7c9a617c7ce/public/coral_fort_wall_02_2k.gltf/textures/coral_fort_wall_02_diff_2k.jpg
--------------------------------------------------------------------------------
/public/coral_fort_wall_02_2k.gltf/textures/coral_fort_wall_02_nor_gl_2k.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Akohjesse/mutli-browser-window-threejs/c6f100688f922f4c778514fe0080a7c9a617c7ce/public/coral_fort_wall_02_2k.gltf/textures/coral_fort_wall_02_nor_gl_2k.jpg
--------------------------------------------------------------------------------
/public/coral_fort_wall_02_2k.gltf/textures/coral_fort_wall_02_rough_2k.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Akohjesse/mutli-browser-window-threejs/c6f100688f922f4c778514fe0080a7c9a617c7ce/public/coral_fort_wall_02_2k.gltf/textures/coral_fort_wall_02_rough_2k.jpg
--------------------------------------------------------------------------------
/public/vite.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/style.css:
--------------------------------------------------------------------------------
1 | * {
2 | margin: 0;
3 | padding: 0;
4 | box-sizing: border-box;
5 | }
6 | body {
7 | overflow: hidden;
8 | }
9 |
--------------------------------------------------------------------------------
/window.js:
--------------------------------------------------------------------------------
1 | class WindowManager {
2 | #windows;
3 | #count;
4 | #id;
5 | #winData;
6 | #winShapeChangeCallback;
7 | #winChangeCallback;
8 |
9 | constructor() {
10 | let that = this;
11 | addEventListener("storage", (event) => {
12 | if (event.key == "windows") {
13 | let newWindows = JSON.parse(event.newValue);
14 | let winChange = that.#didWindowsChange(that.#windows, newWindows);
15 |
16 | that.#windows = newWindows;
17 |
18 | if (winChange) {
19 | if (that.#winChangeCallback) that.#winChangeCallback();
20 | }
21 | }
22 | });
23 |
24 | window.addEventListener("beforeunload", function (e) {
25 | let index = that.getWindowIndexFromId(that.#id);
26 |
27 | that.#windows.splice(index, 1);
28 | that.updateWindowsLocalStorage();
29 | });
30 | }
31 |
32 | #didWindowsChange(pWins, nWins) {
33 | if (pWins.length != nWins.length) {
34 | return true;
35 | } else {
36 | let c = false;
37 |
38 | for (let i = 0; i < pWins.length; i++) {
39 | if (pWins[i].id != nWins[i].id) c = true;
40 | }
41 |
42 | return c;
43 | }
44 | }
45 | init(metaData) {
46 | this.#windows = JSON.parse(localStorage.getItem("windows")) || [];
47 | this.#count = localStorage.getItem("count") || 0;
48 | this.#count++;
49 |
50 | this.#id = this.#count;
51 | let shape = this.getWinShape();
52 | this.#winData = { id: this.#id, shape: shape, metaData: metaData };
53 | this.#windows.push(this.#winData);
54 |
55 | localStorage.setItem("count", this.#count);
56 | this.updateWindowsLocalStorage();
57 | }
58 |
59 | getWinShape() {
60 | let shape = {
61 | x: window.screenLeft,
62 | y: window.screenTop,
63 | w: window.innerWidth,
64 | h: window.innerHeight,
65 | };
66 | return shape;
67 | }
68 |
69 | getWindowIndexFromId(id) {
70 | let index = -1;
71 |
72 | for (let i = 0; i < this.#windows.length; i++) {
73 | if (this.#windows[i].id == id) index = i;
74 | }
75 |
76 | return index;
77 | }
78 |
79 | updateWindowsLocalStorage() {
80 | localStorage.setItem("windows", JSON.stringify(this.#windows));
81 | }
82 |
83 | update() {
84 | let winShape = this.getWinShape();
85 |
86 | if (
87 | winShape.x != this.#winData.shape.x ||
88 | winShape.y != this.#winData.shape.y ||
89 | winShape.w != this.#winData.shape.w ||
90 | winShape.h != this.#winData.shape.h
91 | ) {
92 | this.#winData.shape = winShape;
93 |
94 | let index = this.getWindowIndexFromId(this.#id);
95 | this.#windows[index].shape = winShape;
96 |
97 | if (this.#winShapeChangeCallback) this.#winShapeChangeCallback();
98 | this.updateWindowsLocalStorage();
99 | }
100 | }
101 | setWinShapeChangeCallback(callback) {
102 | this.#winShapeChangeCallback = callback;
103 | }
104 | setWinChangeCallback(callback) {
105 | this.#winChangeCallback = callback;
106 | }
107 | getWindows() {
108 | return this.#windows;
109 | }
110 |
111 | getThisWindowData() {
112 | return this.#winData;
113 | }
114 | getThisWindowID() {
115 | return this.#id;
116 | }
117 | }
118 |
119 | export default WindowManager;
120 |
--------------------------------------------------------------------------------