diff --git a/mirror-2/components/engine/space-viewport-2.tsx b/mirror-2/components/engine/space-viewport-2.tsx
index 26b4fa9f..5f714566 100644
--- a/mirror-2/components/engine/space-viewport-2.tsx
+++ b/mirror-2/components/engine/space-viewport-2.tsx
@@ -14,7 +14,7 @@ import { skipToken } from '@reduxjs/toolkit/query/react' // Important for condit
import { setUpSpace } from '@/components/engine/space-engine.utils'
import { useGetAllEntitiesQuery } from '@/state/api/entities'
import { SpaceEngineNonGameContext } from '@/components/engine/non-game-context/space-engine-non-game-context'
-import main from '/Users/jared/GitHub/the-mirror/mirror-2/splat/src/index'
+import main from '/Users/jared/GitHub/the-mirror/mirror-2/splat-editor/src/index'
interface SpaceViewport2Props {
spaceId?: number
diff --git a/mirror-2/splat/.eslintignore b/mirror-2/splat/.eslintignore
deleted file mode 100644
index 63520da7..00000000
--- a/mirror-2/splat/.eslintignore
+++ /dev/null
@@ -1,3 +0,0 @@
-node_modules
-dist
-build
diff --git a/mirror-2/splat/.eslintrc.json b/mirror-2/splat/.eslintrc.json
deleted file mode 100644
index e9b96f50..00000000
--- a/mirror-2/splat/.eslintrc.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
- "root": true,
- "parser": "@typescript-eslint/parser",
- "extends": [
- "eslint:recommended",
- "plugin:@typescript-eslint/eslint-recommended",
- "plugin:@typescript-eslint/recommended"
- ],
- "plugins": ["@typescript-eslint"],
- "rules": {
- "no-constant-condition": "off",
- "no-empty": "off",
- "no-prototype-builtins": "off",
- "@typescript-eslint/ban-ts-comment": "off",
- "@typescript-eslint/ban-types": "off",
- "@typescript-eslint/no-explicit-any": "off",
- "@typescript-eslint/no-unused-vars": "off"
- }
-}
diff --git a/mirror-2/splat/.gitignore b/mirror-2/splat/.gitignore
deleted file mode 100644
index 0ca39c00..00000000
--- a/mirror-2/splat/.gitignore
+++ /dev/null
@@ -1,3 +0,0 @@
-node_modules
-dist
-.DS_Store
diff --git a/mirror-2/splat/.gitmodules b/mirror-2/splat/.gitmodules
deleted file mode 100644
index e69de29b..00000000
diff --git a/mirror-2/splat/.prettierignore b/mirror-2/splat/.prettierignore
deleted file mode 100644
index d1cb904c..00000000
--- a/mirror-2/splat/.prettierignore
+++ /dev/null
@@ -1,3 +0,0 @@
-node_modules
-package-lock.json
-build
diff --git a/mirror-2/splat/LICENSE b/mirror-2/splat/LICENSE
deleted file mode 100644
index 72ef4807..00000000
--- a/mirror-2/splat/LICENSE
+++ /dev/null
@@ -1,19 +0,0 @@
-Copyright (c) 2011-2024 PlayCanvas Ltd.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
diff --git a/mirror-2/splat/README.md b/mirror-2/splat/README.md
deleted file mode 100644
index 1b5c594f..00000000
--- a/mirror-2/splat/README.md
+++ /dev/null
@@ -1,50 +0,0 @@
-# SuperSplat - 3D Gaussian Splat Editor
-
-SuperSplat is a free and open source tool for inspecting and editing 3D Gaussian Splats. It is built on web technologies and runs in the browser, so there's nothing to download or install.
-
-A live version of this tool is available at: https://playcanvas.com/supersplat/editor
-
-
-
-See https://repo-sam.inria.fr/fungraph/3d-gaussian-splatting/ for more information on gaussian splats.
-
-## Loading Scenes
-
-To load a Gaussian splat PLY file, drag & drop it onto the application page. Alternatively, use the Scene menu and choose "Open".
-
-
-
-If you disable the "Load all PLY data" option before loading the file, then the PLY data not required by the editor is excluded (for example the spherical harmonic data). This can save on browser memory.
-
-## Editing Scenes
-
-Once a PLY file is loaded, you will see it appear in the SCENE MANAGER panel. Use this panel to hide splats, remove them from the scene, orientate them and select the current splat for editing.
-
-
-
-Use the bottom toolbar to access the selection tools, tranform tools and undo/redo.
-
-
-
-The SPLAT DATA panel plots various scene properties on a histogram display. You can select splats directly by dragging on the histogram view. Use the Shift key to add to the current selection and Ctrl key to remove from the current selection.
-
-
-
-## Saving Results
-
-Once you're done editing the scene, use the Scene menu to Save, Save As and Export the scene to the local file system. Only visible splats are written.
-
-## Local Development
-
-The steps required to clone the repo and run a local development server are as follows:
-
-```sh
-git clone https://github.com/playcanvas/supersplat.git
-cd supersplat
-npm i
-npm run develop
-```
-
-The last command `npm run develop` will build and run a local version of the editor on port 3000. Changes to the source are detected and the editor is automatically rebuilt.
-
-To access the local editor instance, open a browser tab and navigate to `http://localhost:3000`.
diff --git a/mirror-2/splat/copy-and-watch.mjs b/mirror-2/splat/copy-and-watch.mjs
deleted file mode 100644
index cdfe303e..00000000
--- a/mirror-2/splat/copy-and-watch.mjs
+++ /dev/null
@@ -1,64 +0,0 @@
-import fs from 'fs';
-import path from 'path';
-
-// custom plugin to copy files and watch them
-export default function copyAndWatch(config) {
- const resolvedConfig = {
- targets: []
- };
-
- // resolve source directories into files
- config.targets.forEach(target => {
- const readRec = pathname => {
- if (!fs.existsSync(pathname)) {
- console.log(`skipping missing file ${target.src}`);
- } else {
- if (fs.lstatSync(pathname).isDirectory()) {
- const children = fs.readdirSync(pathname);
- children.forEach(childPath => {
- readRec(path.join(pathname, childPath));
- });
- } else {
- let dest;
- if (fs.lstatSync(target.src).isDirectory()) {
- dest = path.join(
- target.dest || '',
- path.basename(target.destFilename || target.src),
- path.relative(target.src, pathname)
- );
- } else {
- dest = path.join(target.dest || '', path.basename(target.destFilename || target.src));
- }
- resolvedConfig.targets.push({
- src: pathname,
- dest: dest,
- transform: target.transform
- });
- }
- }
- };
- readRec(target.src);
- });
-
- return {
- name: 'copy-and-watch',
- async buildStart() {
- // disable watching during production build
- if (process.env.NODE_ENV !== 'production') {
- resolvedConfig.targets.forEach(target => {
- this.addWatchFile(target.src);
- });
- }
- },
- async generateBundle() {
- resolvedConfig.targets.forEach(target => {
- const contents = fs.readFileSync(target.src);
- this.emitFile({
- type: 'asset',
- fileName: target.dest,
- source: target.transform ? target.transform(contents, target.src) : contents
- });
- });
- }
- };
-}
diff --git a/mirror-2/splat/docs/index.md b/mirror-2/splat/docs/index.md
deleted file mode 100644
index 75ae25b8..00000000
--- a/mirror-2/splat/docs/index.md
+++ /dev/null
@@ -1,90 +0,0 @@
-# SuperSplat User Guide
-
-Welcome to the SuperSplat User Guide.
-
-SuperSplat is an open source, browser-based 3D Gaussian Splat Editor. You can use it to view, inspect, transform, combine, crop, clean up and optimize 3D Gaussian Splats.
-
-## Installing SuperSplat
-
-SuperSplat is a web app so you do not need to install it. Simply point your browser at:
-
-https://playcanvas.com/supersplat/editor
-
-However, for your convenience, you can also install SuperSplat as a PWA (Progressive Web App). This will make SuperSplat appear and behave more like a native application. An app icon for SuperSplat will be generated on your desktop or home screen. Furthermore, .ply files will be associated with the SuperSplat PWA, enabling you to launch SuperSplat more quickly.
-
-## Loading Splats
-
-SuperSplat loads splats from .ply files. Only .ply files containing 3D Gaussian Splat data can be loaded. If you attempt to load any other type of data from a .ply file, it will fail.
-
-There are three ways that you can load a .ply file:
-
-1. Drag and drop one or more .ply files from your file system into SuperSplat's client area.
-2. Select the `Scene` > `Open` menu item and select one or more .ply files from your file system.
-3. Use the `load` query parameter. This is in the form: `https://playcanvas.com/supersplat/editor?load=`. An example would be:
-
- https://playcanvas.com/supersplat/editor?load=https://raw.githubusercontent.com/willeastcott/assets/main/dragon.compressed.ply
-
- This is a useful mechanism for sharing splats with other people (say on social platforms like X and LinkedIn).
-
-## Saving Splats
-
-To save the currently loaded scene, select the `Scene` > `Save` or `Save As` menu items. This will save a `.ply` file to your file system.
-
-SuperSplat can also export to two additional formats via the `Scene` > `Export` sub-menu:
-
-* **Compressed Ply**: A lightweight, compressed format that is far smaller than the equivalent uncompressed .ply file. It quantizes splat data and drops spherical harmonics from the output file. See [this article](https://blog.playcanvas.com/compressing-gaussian-splats/) for more details on the format.
-* **Splat File**: Another compressed format, although not as efficient as the compressed ply format.
-
-## Controlling the Camera
-
-The camera controls in SuperSplat are as follows:
-
-| Control | Description |
-| ----------------------------------------------- | ------------------------------- |
-| Left Mouse Button
Shift + Right Mouse Button | Orbit camera |
-| Middle Mouse Button
Alt + Right Mouse Button | Dolly camera |
-| Right Mouse Button | Pan camera |
-| Left/Right Arrow Keys | Strafe camera left/right |
-| Up/Down Arrow Keys | Dolly camera forwards/backwards |
-| F Key | Frame selection |
-
-To set the target point for orbiting the camera, double click anywhere in the 3D view.
-
-## Visualizing Splats
-
-Splats can be rendered in two 'modes':
-
-* **Centers Mode**: A blue dot is rendered at the center of each Gaussian.
-* **Rings Mode**: A ring is rendered at the outer boundary of each Gaussian.
-
-You can disable rendering of the centers or rings (depending on the active mode) by pressing Space. This allows you to view the scene as it would normally appear.
-
-You can control the pixel size of the center dots in the VIEW OPTIONS panel.
-
-## Selecting and Deleting Splats
-
-Cropping splats or deleting unwanted Gaussians is a key function of SuperSplat. To help with this, there are 3 selection tools available:
-
-* **Picker Select**: Click to select, or click + drag to rect select.
-* **Brush Select**: Click and drag a selection circle. Change the brush size with the `[` and `]` keys.
-* **Sphere Select**: Activate a sphere volume to add or remove splats from the current selection. Double click on any splat to reposition the sphere volume.
-
-Once you are happy with your selection, you can delete it with the Delete key.
-
-## Transforming Splats
-
-SuperSplat can translate, rotate and scale splats. To do this, select a splat in the Scene Manager and activate one of the gizmos via the horizontal icon bar.
-
-To achieve fine grain control over the transform of the selected splat, you can use the TRANSFORM panel (below the SCENE MANAGER panel).
-
-To set the origin of the currently active gizmo, double click anywhere in the 3D view.
-
-## Merging Splats
-
-It is possible to merge multiple .ply files together and output a single, combine .ply file. Simply load any number of .ply files into Scene Manager, perform whatever transformations and edits you require, and then save the result via the `Scene` > `Save` menu item.
-
-## Inspecting Splat Data
-
-The Data Panel can be used to analyze the contents of your splat scenes. Initially, it is collapsed at the bottom of the application's window. To open it, click on the panel's header or press the 'D' key.
-
-The Data Panel plots various scene properties on a histogram display. You can select splats directly by dragging on the histogram view. Use the Shift key to add to the current selection and the Ctrl key to remove from the current selection.
diff --git a/mirror-2/splat/package.json b/mirror-2/splat/package.json
deleted file mode 100644
index 2235c754..00000000
--- a/mirror-2/splat/package.json
+++ /dev/null
@@ -1,57 +0,0 @@
-{
- "name": "supersplat",
- "version": "1.6.0",
- "author": "PlayCanvas",
- "homepage": "https://playcanvas.com/supersplat/editor",
- "description": "3D Gaussian Splat Editor",
- "keywords": [
- "playcanvas",
- "ply",
- "gaussian",
- "splat",
- "editor"
- ],
- "license": "MIT",
- "main": "index.js",
- "scripts": {
- "build": "rollup -c",
- "watch": "rollup -c -w",
- "serve": "serve dist -C",
- "develop": "concurrently --kill-others \"npm run watch\" \"npm run serve\"",
- "develop:local": "cross-env ENGINE_PATH=../engine npm run develop",
- "build:local": "cross-env ENGINE_PATH=../engine npm run build",
- "watch:local": "cross-env ENGINE_PATH=../engine npm run watch",
- "lint": "eslint --ext .ts src",
- "test": "jest"
- },
- "devDependencies": {
- "@playcanvas/eslint-config": "^1.7.4",
- "@playcanvas/pcui": "^4.5.0",
- "@rollup/plugin-alias": "^5.1.1",
- "@rollup/plugin-image": "^3.0.3",
- "@rollup/plugin-json": "^6.1.0",
- "@rollup/plugin-node-resolve": "^15.3.0",
- "@rollup/plugin-strip": "^3.0.4",
- "@rollup/plugin-terser": "^0.4.4",
- "@rollup/plugin-typescript": "^12.1.0",
- "@types/wicg-file-system-access": "^2023.10.5",
- "@typescript-eslint/eslint-plugin": "^7.15.0",
- "@typescript-eslint/parser": "^7.15.0",
- "autoprefixer": "^10.4.20",
- "concurrently": "^9.0.1",
- "cors": "^2.8.5",
- "cross-env": "^7.0.3",
- "eslint": "^8.56.0",
- "i18next": "^23.15.1",
- "i18next-browser-languagedetector": "^8.0.0",
- "jest": "^29.7.0",
- "playcanvas": "^1.74.0",
- "postcss": "^8.4.47",
- "rollup": "^4.23.0",
- "rollup-plugin-postcss": "^4.0.2",
- "rollup-plugin-visualizer": "^5.12.0",
- "sass": "^1.79.4",
- "serve": "^14.2.3",
- "tslib": "^2.7.0"
- }
-}
diff --git a/mirror-2/splat/rollup.config.mjs b/mirror-2/splat/rollup.config.mjs
deleted file mode 100644
index 88e6337b..00000000
--- a/mirror-2/splat/rollup.config.mjs
+++ /dev/null
@@ -1,136 +0,0 @@
-import path from 'path';
-import copyAndWatch from './copy-and-watch.mjs';
-import alias from '@rollup/plugin-alias';
-import image from '@rollup/plugin-image';
-import terser from '@rollup/plugin-terser';
-import resolve from '@rollup/plugin-node-resolve';
-import strip from '@rollup/plugin-strip';
-import typescript from '@rollup/plugin-typescript';
-import json from '@rollup/plugin-json';
-// import { visualizer } from 'rollup-plugin-visualizer';
-
-import autoprefixer from 'autoprefixer';
-import postcss from 'rollup-plugin-postcss';
-
-// prod is release build
-if (process.env.BUILD_TYPE === 'prod') {
- process.env.BUILD_TYPE = 'release';
-}
-
-const HREF = process.env.BASE_HREF || '';
-
-// debug, profile, release
-const BUILD_TYPE = process.env.BUILD_TYPE || 'release';
-
-const ENGINE_DIR = process.env.ENGINE_PATH || './node_modules/playcanvas';
-const ENGINE_NAME = (BUILD_TYPE === 'debug') ? 'playcanvas.dbg/src/index.js' : 'playcanvas/src/index.js';
-const ENGINE_PATH = path.resolve(ENGINE_DIR, 'build', ENGINE_NAME);
-
-const PCUI_DIR = path.resolve(process.env.PCUI_PATH || 'node_modules/@playcanvas/pcui');
-
-const outputHeader = () => {
- const BLUE_OUT = '\x1b[34m';
- const BOLD_OUT = `\x1b[1m`;
- const REGULAR_OUT = `\x1b[22m`;
- const RESET_OUT = `\x1b[0m`;
-
- const title = [
- `Building SuperSplat`,
- `type ${BOLD_OUT}${BUILD_TYPE}${REGULAR_OUT}`,
- `engine ${BOLD_OUT}${ENGINE_DIR}${REGULAR_OUT}`,
- `pcui ${BOLD_OUT}${PCUI_DIR}${REGULAR_OUT}`
- ].map(l => `${BLUE_OUT}${l}`).join(`\n`);
- console.log(`${BLUE_OUT}${title}${RESET_OUT}\n`);
-};
-
-outputHeader();
-
-const aliasEntries = [
- { find: 'playcanvas', replacement: ENGINE_PATH },
- { find: 'pcui', replacement: PCUI_DIR }
-];
-
-const tsCompilerOptions = {
- baseUrl: '.',
- paths: {
- playcanvas: [ENGINE_DIR],
- pcui: [PCUI_DIR]
- }
-};
-
-const application = {
- input: 'src/index.ts',
- output: {
- dir: 'dist',
- format: 'esm',
- sourcemap: true
- },
- plugins: [
- copyAndWatch({
- targets: [
- {
- src: 'src/index.html',
- transform: (contents, filename) => {
- return contents.toString().replace('__BASE_HREF__', HREF);
- }
- },
- { src: 'src/manifest.json' },
- { src: 'static/images', dest: 'static' },
- { src: 'static/icons', dest: 'static' },
- { src: 'static/env/VertebraeHDRI_v1_512.png', dest: 'static/env' }
- ]
- }),
- alias({ entries: aliasEntries }),
- resolve(),
- image({ dom: false }),
- postcss({
- extract: 'index.css',
- extensions: ['.scss', '.sass', '.css'],
- use: [
- ['sass', {
- includePaths: [ path.resolve(PCUI_DIR, 'dist') ]
- }]
- ],
- plugins: [
- autoprefixer
- ]
- }),
- json(),
- typescript({
- compilerOptions: tsCompilerOptions
- }),
- BUILD_TYPE === 'release' &&
- strip({
- include: ['**/*.ts'],
- functions: ['Debug.exec']
- }),
- BUILD_TYPE !== 'debug' && terser()
- // visualizer()
- ],
- treeshake: 'smallest',
- cache: false
-};
-
-const serviceWorker = {
- input: 'src/sw.ts',
- output: {
- dir: 'dist',
- format: 'esm',
- sourcemap: true
- },
- plugins: [
- resolve(),
- json(),
- typescript({
- compilerOptions: tsCompilerOptions
- }),
- // BUILD_TYPE !== 'debug' && terser()
- ],
- treeshake: 'smallest',
- cache: false
-};
-
-export default [
- application,
- serviceWorker
-];
diff --git a/mirror-2/splat/src/asset-loader.ts b/mirror-2/splat/src/asset-loader.ts
deleted file mode 100644
index 54d84f16..00000000
--- a/mirror-2/splat/src/asset-loader.ts
+++ /dev/null
@@ -1,215 +0,0 @@
-import { Asset, AssetRegistry, GraphicsDevice, GSplatData, GSplatResource, TEXTURETYPE_RGBP } from 'playcanvas';
-import { Splat } from './splat';
-import { Env } from './env';
-
-import { startSpinner, stopSpinner } from './ui/spinner';
-
-interface ModelLoadRequest {
- url?: string;
- contents?: ArrayBuffer;
- filename?: string;
- maxAnisotropy?: number;
-}
-
-interface EnvLoadRequest {
- url: string;
- filename?: string;
-}
-
-// ideally this function would stream data directly into GSplatData buffers.
-// unfortunately the .splat file format has no header specifying total number
-// of splats so filesize must be known in order to allocate the correct amount
-// of memory.
-const deserializeFromSSplat = (data: ArrayBufferLike) => {
- const totalSplats = data.byteLength / 32;
- const dataView = new DataView(data);
-
- const storage_x = new Float32Array(totalSplats);
- const storage_y = new Float32Array(totalSplats);
- const storage_z = new Float32Array(totalSplats);
- const storage_opacity = new Float32Array(totalSplats);
- const storage_rot_0 = new Float32Array(totalSplats);
- const storage_rot_1 = new Float32Array(totalSplats);
- const storage_rot_2 = new Float32Array(totalSplats);
- const storage_rot_3 = new Float32Array(totalSplats);
- const storage_f_dc_0 = new Float32Array(totalSplats);
- const storage_f_dc_1 = new Float32Array(totalSplats);
- const storage_f_dc_2 = new Float32Array(totalSplats);
- const storage_scale_0 = new Float32Array(totalSplats);
- const storage_scale_1 = new Float32Array(totalSplats);
- const storage_scale_2 = new Float32Array(totalSplats);
- const storage_state = new Uint8Array(totalSplats);
-
-
- const SH_C0 = 0.28209479177387814;
- let off;
-
- for(let i = 0; i < totalSplats; i++){
- off = i * 32;
- storage_x[i] = dataView.getFloat32(off + 0, true);
- storage_y[i] = dataView.getFloat32(off + 4, true);
- storage_z[i] = dataView.getFloat32(off + 8, true);
-
- storage_scale_0[i] = Math.log(dataView.getFloat32(off + 12, true));
- storage_scale_1[i] = Math.log(dataView.getFloat32(off + 16, true));
- storage_scale_2[i] = Math.log(dataView.getFloat32(off + 20, true));
-
- storage_f_dc_0[i] = (dataView.getUint8(off + 24) / 255 - 0.5) / SH_C0;
- storage_f_dc_1[i] = (dataView.getUint8(off + 25) / 255 - 0.5) / SH_C0;
- storage_f_dc_2[i] = (dataView.getUint8(off + 26) / 255 - 0.5) / SH_C0;
-
- storage_opacity[i] = -Math.log(255 / dataView.getUint8(off + 27) - 1);
-
- storage_rot_0[i] = (dataView.getUint8(off + 28) - 128) / 128;
- storage_rot_1[i] = (dataView.getUint8(off + 29) - 128) / 128;
- storage_rot_2[i] = (dataView.getUint8(off + 30) - 128) / 128;
- storage_rot_3[i] = (dataView.getUint8(off + 31) - 128) / 128;
- }
-
-
- return new GSplatData([{
- name: 'vertex',
- count: totalSplats,
- properties: [
- {type: 'float', name: 'x', storage: storage_x, byteSize: 4},
- {type: 'float', name: 'y', storage: storage_y, byteSize: 4},
- {type: 'float', name: 'z', storage: storage_z, byteSize: 4},
- {type: 'float', name: 'opacity', storage: storage_opacity, byteSize: 4},
- {type: 'float', name: 'rot_0', storage: storage_rot_0, byteSize: 4},
- {type: 'float', name: 'rot_1', storage: storage_rot_1, byteSize: 4},
- {type: 'float', name: 'rot_2', storage: storage_rot_2, byteSize: 4},
- {type: 'float', name: 'rot_3', storage: storage_rot_3, byteSize: 4},
- {type: 'float', name: 'f_dc_0', storage: storage_f_dc_0, byteSize: 4},
- {type: 'float', name: 'f_dc_1', storage: storage_f_dc_1, byteSize: 4},
- {type: 'float', name: 'f_dc_2', storage: storage_f_dc_2, byteSize: 4},
- {type: 'float', name: 'scale_0', storage: storage_scale_0, byteSize: 4},
- {type: 'float', name: 'scale_1', storage: storage_scale_1, byteSize: 4},
- {type: 'float', name: 'scale_2', storage: storage_scale_2, byteSize: 4},
- {type: 'float', name: 'state', storage: storage_state, byteSize: 4}
- ]
- }]);
-};
-
-// handles loading gltf container assets
-class AssetLoader {
- device: GraphicsDevice;
- registry: AssetRegistry;
- defaultAnisotropy: number;
- loadAllData = true;
-
- constructor(device: GraphicsDevice, registry: AssetRegistry, defaultAnisotropy?: number) {
- this.device = device;
- this.registry = registry;
- this.defaultAnisotropy = defaultAnisotropy || 1;
- }
-
- loadPly(loadRequest: ModelLoadRequest) {
- startSpinner();
-
- return new Promise((resolve, reject) => {
- const asset = new Asset(
- loadRequest.filename || loadRequest.url,
- 'gsplat',
- {
- url: loadRequest.url,
- filename: loadRequest.filename,
- contents: loadRequest.contents
- },
- {
- elementFilter: this.loadAllData ? (() => true) : null,
- // decompress data on load
- decompress: true
- }
- );
-
- asset.on('load', () => {
- // support loading 2d splats by adding scale_2 property with almost 0 scale
- const splatData = asset.resource.splatData;
- if (splatData.getProp('scale_0') && splatData.getProp('scale_1') && !splatData.getProp('scale_2')) {
- const scale2 = new Float32Array(splatData.numSplats).fill(Math.log(1e-6));
- splatData.addProp('scale_2', scale2);
-
- // place the new scale_2 property just after scale_1
- const props = splatData.getElement('vertex').properties;
- props.splice(props.findIndex((prop: any) => prop.name === 'scale_1') + 1, 0, props.splice(props.length - 1, 1)[0]);
- }
-
- // check the PLY contains minimal set of we expect
- const required = [
- 'x', 'y', 'z',
- 'scale_0', 'scale_1', 'scale_2',
- 'rot_0', 'rot_1', 'rot_2', 'rot_3',
- 'f_dc_0', 'f_dc_1', 'f_dc_2', 'opacity'
- ];
- const missing = required.filter(x => !splatData.getProp(x));
- if (missing.length > 0) {
- reject(`This file does not contain gaussian splatting data. The following properties are missing: ${missing.join(', ')}`);
- } else {
- resolve(new Splat(asset));
- }
- });
-
- asset.on('error', (err: string) => reject(err));
-
- this.registry.add(asset);
- this.registry.load(asset);
- }).finally(() => {
- stopSpinner();
- });
- }
-
- loadSplat(loadRequest: ModelLoadRequest) {
- startSpinner();
-
- return new Promise((resolve, reject) => {
- fetch(loadRequest.url || loadRequest.filename)
- .then((response) => {
- if (!response || !response.ok || !response.body) {
- reject('Failed to fetch splat data');
- } else {
- return response.arrayBuffer();
- }
- })
- .then((arrayBuffer) => deserializeFromSSplat(arrayBuffer))
- .then((gsplatData) => {
- const asset = new Asset(loadRequest.filename || loadRequest.url, 'gsplat', {
- url: loadRequest.url,
- filename: loadRequest.filename
- });
- asset.resource = new GSplatResource(this.device, gsplatData);
- resolve(new Splat(asset));
- })
- .catch((err) => {
- console.error(err);
- reject('Failed to load splat data');
- });
- }).finally(() => {
- stopSpinner();
- });
- }
-
- loadModel(loadRequest: ModelLoadRequest) {
- const filename = (loadRequest.filename || loadRequest.url).toLowerCase();
- if (filename.endsWith('.ply')) {
- return this.loadPly(loadRequest);
- } else if (filename.endsWith('.splat')) {
- return this.loadSplat(loadRequest);
- }
- }
-
- loadEnv(loadRequest: EnvLoadRequest) {
- const registry = this.registry;
- return new Promise((resolve, reject) => {
- const textureAsset = new Asset('skybox_equi', 'texture', loadRequest, {
- mipmaps: false,
- type: TEXTURETYPE_RGBP
- });
- textureAsset.ready(() => resolve(new Env(textureAsset)));
- textureAsset.on('error', (err: string) => reject(err));
- registry.add(textureAsset);
- registry.load(textureAsset);
- });
- }
-}
-
-export {AssetLoader};
diff --git a/mirror-2/splat/src/camera.ts b/mirror-2/splat/src/camera.ts
deleted file mode 100644
index 3ec3f6f1..00000000
--- a/mirror-2/splat/src/camera.ts
+++ /dev/null
@@ -1,509 +0,0 @@
-import {
- math,
- ADDRESS_CLAMP_TO_EDGE,
- FILTER_NEAREST,
- PIXELFORMAT_RGBA8,
- PIXELFORMAT_DEPTH,
- BoundingBox,
- Color,
- Entity,
- EventHandler,
- Picker,
- Plane,
- Ray,
- RenderTarget,
- Texture,
- Vec3,
- WebglGraphicsDevice,
- TONEMAP_LINEAR,
- TONEMAP_FILMIC,
- TONEMAP_HEJL,
- TONEMAP_ACES,
- TONEMAP_ACES2
-} from 'playcanvas';
-import { Element, ElementType } from './element';
-import { TweenValue } from './tween-value';
-import { Serializer } from './serializer';
-import { PointerController } from './controllers';
-import { Splat } from './splat';
-
-// calculate the forward vector given azimuth and elevation
-const calcForwardVec = (result: Vec3, azim: number, elev: number) => {
- const ex = elev * math.DEG_TO_RAD;
- const ey = azim * math.DEG_TO_RAD;
- const s1 = Math.sin(-ex);
- const c1 = Math.cos(-ex);
- const s2 = Math.sin(-ey);
- const c2 = Math.cos(-ey);
- result.set(-c1 * s2, s1, c1 * c2);
-};
-
-// work globals
-const forwardVec = new Vec3();
-const cameraPosition = new Vec3();
-const plane = new Plane();
-const ray = new Ray();
-const vec = new Vec3();
-const vecb = new Vec3();
-
-// modulo dealing with negative numbers
-const mod = (n: number, m: number) => ((n % m) + m) % m;
-
-class Camera extends Element {
- controller: PointerController;
- entity: Entity;
- focalPointTween = new TweenValue({ x: 0, y: 0.5, z: 0 });
- azimElevTween = new TweenValue({ azim: 30, elev: -15 });
- distanceTween = new TweenValue({ distance: 2 });
-
- minElev = -90;
- maxElev = 90;
-
- events = new EventHandler();
-
- sceneRadius = 5;
-
- picker: Picker;
- pickModeRenderTarget: RenderTarget;
-
- constructor() {
- super(ElementType.camera);
- // create the camera entity
- this.entity = new Entity('Camera');
- this.entity.addComponent('camera', {
- fov: 60,
- clearColor: new Color(0, 0, 0, 0),
- frustumCulling: true
- });
-
- // NOTE: this call is needed for refraction effect to work correctly, but
- // it slows rendering and should only be made when required.
- // this.entity.camera.requestSceneColorMap(true);
- }
-
- // fov
- set fov(value: number) {
- this.entity.camera.fov = value;
- }
-
- get fov() {
- return this.entity.camera.fov;
- }
-
- // near clip
- set near(value: number) {
- this.entity.camera.nearClip = value;
- }
-
- get near() {
- return this.entity.camera.nearClip;
- }
-
- // far clip
- set far(value: number) {
- this.entity.camera.farClip = value;
- }
-
- get far() {
- return this.entity.camera.farClip;
- }
-
- // focal point
- get focalPoint() {
- const t = this.focalPointTween.target;
- return new Vec3(t.x, t.y, t.z);
- }
-
- setFocalPoint(point: Vec3, dampingFactorFactor: number = 1) {
- this.focalPointTween.goto(point, dampingFactorFactor * this.scene.config.controls.dampingFactor);
- }
-
- // azimuth, elevation
- get azimElev() {
- return this.azimElevTween.target;
- }
-
- get azim() {
- return this.azimElev.azim;
- }
-
- get elevation() {
- return this.azimElev.elev;
- }
-
- get distance() {
- return this.distanceTween.target.distance;
- }
-
- setAzimElev(azim: number, elev: number, dampingFactorFactor: number = 1) {
- // clamp
- azim = mod(azim, 360);
- elev = Math.max(this.minElev, Math.min(this.maxElev, elev));
-
- const t = this.azimElevTween;
- t.goto({azim, elev}, dampingFactorFactor * this.scene.config.controls.dampingFactor);
-
- // handle wraparound
- if (t.source.azim - azim < -180) {
- t.source.azim += 360;
- } else if (t.source.azim - azim > 180) {
- t.source.azim -= 360;
- }
- }
-
- setDistance(distance: number, dampingFactorFactor: number = 1) {
- const controls = this.scene.config.controls;
-
- // clamp
- distance = Math.max(controls.minZoom, Math.min(controls.maxZoom, distance));
-
- const t = this.distanceTween;
- t.goto({ distance }, dampingFactorFactor * controls.dampingFactor);
- }
-
- setPose(position: Vec3, target: Vec3, dampingFactorFactor: number = 1) {
- vec.sub2(target, position);
- const l = vec.length();
- const azim = Math.atan2(-vec.x / l, -vec.z / l) * math.RAD_TO_DEG;
- const elev = Math.asin(vec.y / l) * math.RAD_TO_DEG;
- this.setFocalPoint(target, dampingFactorFactor);
- this.setAzimElev(azim, elev, dampingFactorFactor);
- this.setDistance(l / this.sceneRadius * this.fovFactor, dampingFactorFactor);
- }
-
- // convert world to screen coordinate
- worldToScreen(world: Vec3, screen: Vec3) {
- this.entity.camera.worldToScreen(world, screen);
- }
-
- add() {
- this.scene.cameraRoot.addChild(this.entity);
- this.entity.camera.layers = this.entity.camera.layers.concat([
- this.scene.shadowLayer.id,
- this.scene.debugLayer.id,
- this.scene.gizmoLayer.id
- ]);
-
- if (this.scene.config.camera.debug_render) {
- this.entity.camera.setShaderPass(`debug_${this.scene.config.camera.debug_render}`);
- }
-
- const target = document.getElementById('canvas-container');
-
- this.controller = new PointerController(this, target);
-
- // apply scene config
- const config = this.scene.config;
- const controls = config.controls;
-
- // configure background
- this.entity.camera.clearColor.set(0, 0, 0, 0);
-
- this.minElev = (controls.minPolarAngle * 180) / Math.PI - 90;
- this.maxElev = (controls.maxPolarAngle * 180) / Math.PI - 90;
-
- // tonemapping
- this.scene.app.scene.toneMapping = {
- linear: TONEMAP_LINEAR,
- filmic: TONEMAP_FILMIC,
- hejl: TONEMAP_HEJL,
- aces: TONEMAP_ACES,
- aces2: TONEMAP_ACES2
- }[config.camera.toneMapping];
-
- // exposure
- this.scene.app.scene.exposure = config.camera.exposure;
-
- this.fov = config.camera.fov;
-
- // initial camera position and orientation
- this.setAzimElev(controls.initialAzim, controls.initialElev, 0);
- this.setDistance(controls.initialZoom, 0);
-
- // picker
- const { width, height } = this.scene.targetSize;
- this.picker = new Picker(this.scene.app, width, height);
-
- this.scene.events.on('scene.boundChanged', this.onBoundChanged, this);
- }
-
- remove() {
- this.controller.destroy();
- this.controller = null;
-
- this.entity.camera.layers = this.entity.camera.layers.filter(layer => layer !== this.scene.shadowLayer.id);
- this.scene.cameraRoot.removeChild(this.entity);
-
- // destroy doesn't exist on picker?
- // this.picker.destroy();
- this.picker = null;
-
- this.scene.events.off('scene.boundChanged', this.onBoundChanged, this);
- }
-
- // handle the scene's bound changing. the camera must be configured to render
- // the entire extents as well as possible.
- // also update the existing camera distance to maintain the current view
- onBoundChanged(bound: BoundingBox) {
- const prevDistance = this.distanceTween.value.distance * this.sceneRadius;
- this.sceneRadius = bound.halfExtents.length();
- this.setDistance(prevDistance / this.sceneRadius, 0);
- }
-
- serialize(serializer: Serializer) {
- const camera = this.entity.camera.camera;
- serializer.pack(this.fov);
- serializer.packa(this.entity.getWorldTransform().data);
- serializer.pack(this.entity.camera.renderTarget?.width, this.entity.camera.renderTarget?.height);
- }
-
- // handle the viewer canvas resizing
- rebuildRenderTargets() {
- const device = this.scene.graphicsDevice as WebglGraphicsDevice;
- const { width, height } = this.scene.targetSize;
-
- const rt = this.entity.camera.renderTarget;
- if (rt && rt.width === width && rt.height === height) {
- return;
- }
-
- // out with the old
- if (rt) {
- rt.colorBuffer.destroy();
- rt.depthBuffer.destroy();
- rt.destroy();
-
- this.pickModeRenderTarget.destroy();
- this.pickModeRenderTarget = null;
- }
-
- const createTexture = (name: string, width: number, height: number, format: number) => {
- return new Texture(device, {
- name, width, height, format,
- mipmaps: false,
- minFilter: FILTER_NEAREST,
- magFilter: FILTER_NEAREST,
- addressU: ADDRESS_CLAMP_TO_EDGE,
- addressV: ADDRESS_CLAMP_TO_EDGE
- });
- };
-
- // in with the new
- const pixelFormat = PIXELFORMAT_RGBA8;
- const samples = this.scene.config.camera.multisample ? device.maxSamples : 1;
-
- const colorBuffer = createTexture('cameraColor', width, height, pixelFormat);
- const depthBuffer = createTexture('cameraDepth', width, height, PIXELFORMAT_DEPTH);
- const renderTarget = new RenderTarget({
- colorBuffer,
- depthBuffer,
- flipY: false,
- samples,
- autoResolve: false
- });
- this.entity.camera.renderTarget = renderTarget;
- this.entity.camera.camera.horizontalFov = width > height;
-
- // create pick mode render target (reuse color buffer)
- this.pickModeRenderTarget = new RenderTarget({
- colorBuffer,
- depth: false,
- flipY: false,
- samples,
- autoResolve: false
- });
-
- this.scene.events.fire('camera.resize', {width, height});
- }
-
- onUpdate(deltaTime: number) {
- // controller update
- this.controller.update(deltaTime);
-
- // update underlying values
- this.focalPointTween.update(deltaTime);
- this.azimElevTween.update(deltaTime);
- this.distanceTween.update(deltaTime);
-
- const azimElev = this.azimElevTween.value;
- const distance = this.distanceTween.value;
-
- calcForwardVec(forwardVec, azimElev.azim, azimElev.elev);
- cameraPosition.copy(forwardVec);
- cameraPosition.mulScalar(distance.distance * this.sceneRadius / this.fovFactor);
- cameraPosition.add(this.focalPointTween.value);
-
- this.entity.setLocalPosition(cameraPosition);
- this.entity.setLocalEulerAngles(azimElev.elev, azimElev.azim, 0);
-
- this.fitClippingPlanes(this.entity.getLocalPosition(), this.entity.forward);
-
- this.entity.camera.camera._updateViewProjMat();
- }
-
- fitClippingPlanes(cameraPosition: Vec3, forwardVec: Vec3) {
- const bound = this.scene.bound;
- const boundRadius = bound.halfExtents.length();
-
- vec.sub2(bound.center, cameraPosition);
- const dist = vec.dot(forwardVec);
-
- this.far = dist + boundRadius;
- // if camera is placed inside the sphere bound calculate near based far
- this.near = Math.max(1e-6, dist < boundRadius ? this.far / (1024 * 16) : dist - boundRadius);
- }
-
- onPreRender() {
- this.rebuildRenderTargets();
- }
-
- onPostRender() {
- const device = this.scene.graphicsDevice as WebglGraphicsDevice;
- const renderTarget = this.entity.camera.renderTarget;
-
- // resolve msaa buffer
- if (renderTarget.samples > 1) {
- renderTarget.resolve(true, false);
- }
-
- // copy render target
- device.copyRenderTarget(renderTarget, null, true, false);
- }
-
- focus(options?: { focalPoint: Vec3, radius: number, speed: number }) {
- const getSplatFocalPoint = () => {
- for (const element of this.scene.elements) {
- if (element.type === ElementType.splat) {
- const focalPoint = (element as Splat).focalPoint?.();
- if (focalPoint) {
- return focalPoint;
- }
- }
- }
- };
-
- const focalPoint = options ? options.focalPoint : (getSplatFocalPoint() ?? this.scene.bound.center);
- const focalRadius = options ? options.radius : this.scene.bound.halfExtents.length();
-
- const fdist = focalRadius / this.sceneRadius;
-
- this.setDistance(isNaN(fdist) ? 1 : fdist, options?.speed ?? 0);
- this.setFocalPoint(focalPoint, options?.speed ?? 0);
- }
-
- get fovFactor() {
- return Math.sin(this.fov * math.DEG_TO_RAD * 0.5);
- }
-
- // interesect the scene at the given screen coordinate and focus the camera on this location
- pickFocalPoint(screenX: number, screenY: number) {
- const scene = this.scene;
- const cameraPos = this.entity.getPosition();
-
- // @ts-ignore
- const target = scene.canvas;
- const sx = screenX / target.clientWidth * scene.targetSize.width;
- const sy = screenY / target.clientHeight * scene.targetSize.height;
-
- const splats = scene.getElementsByType(ElementType.splat);
-
- let closestD = 0;
- const closestP = new Vec3();
- let closestSplat = null;
-
- for (let i = 0; i < splats.length; ++i) {
- const splat = splats[i] as Splat;
-
- this.pickPrep(splat);
- const pickId = this.pick(sx, sy);
-
- if (pickId !== -1) {
- splat.calcSplatWorldPosition(pickId, vec);
-
- // create a plane at the world position facing perpendicular to the camera
- plane.setFromPointNormal(vec, this.entity.forward);
-
- // create the pick ray in world space
- this.entity.camera.screenToWorld(screenX, screenY, 1.0, vec);
- vec.sub(cameraPos).normalize();
- ray.set(cameraPos, vec);
-
- // find intersection
- if (plane.intersectsRay(ray, vec)) {
- const distance = vecb.sub2(vec, cameraPos).length();
- if (!closestSplat || distance < closestD) {
- closestD = distance;
- closestP.copy(vec);
- closestSplat = splat;
- }
- }
- }
- }
-
- if (closestSplat) {
- this.setFocalPoint(closestP);
- this.setDistance(closestD / this.sceneRadius * this.fovFactor);
- scene.events.fire('camera.focalPointPicked', {
- camera: this,
- splat: closestSplat,
- position: closestP
- });
- }
- }
-
- // pick mode
-
- // render picker contents
- pickPrep(splat: Splat) {
- const { width, height } = this.scene.targetSize;
- const worldLayer = this.scene.app.scene.layers.getLayerByName('World');
-
- const device = this.scene.graphicsDevice as WebglGraphicsDevice;
- const events = this.scene.events;
- const alpha = events.invoke('camera.mode') === 'rings' ? 0.0 : 0.2;
-
- // hide non-selected elements
- const splats = this.scene.getElementsByType(ElementType.splat);
- splats.forEach((s: Splat) => {
- s.entity.enabled = s === splat;
- });
-
- device.scope.resolve('pickerAlpha').setValue(alpha);
- this.picker.resize(width, height);
- this.picker.prepare(this.entity.camera, this.scene.app.scene, [worldLayer]);
-
- // re-enable all splats
- splats.forEach((splat: Splat) => {
- splat.entity.enabled = true;
- });
- }
-
- pick(x: number, y: number) {
- return this.pickRect(x, y, 1, 1)[0];
- }
-
- pickRect(x: number, y: number, width: number, height: number) {
- const device = this.scene.graphicsDevice as WebglGraphicsDevice;
- const pixels = new Uint8Array(width * height * 4);
-
- // read pixels
- device.setRenderTarget(this.picker.renderTarget);
- device.updateBegin();
- device.readPixels(x, this.picker.renderTarget.height - y - height, width, height, pixels);
- device.updateEnd();
-
- const result: number[] = [];
- for (let i = 0; i < width * height; i++) {
- result.push(
- pixels[i * 4] |
- (pixels[i * 4 + 1] << 8) |
- (pixels[i * 4 + 2] << 16) |
- (pixels[i * 4 + 3] << 24)
- );
- }
-
- return result;
- }
-}
-
-export { Camera };
diff --git a/mirror-2/splat/src/controllers.ts b/mirror-2/splat/src/controllers.ts
deleted file mode 100644
index 44d7963a..00000000
--- a/mirror-2/splat/src/controllers.ts
+++ /dev/null
@@ -1,212 +0,0 @@
-import { Camera } from './camera';
-import { Vec3 } from 'playcanvas';
-
-const fromWorldPoint = new Vec3();
-const toWorldPoint = new Vec3();
-const worldDiff = new Vec3();
-
-// calculate the distance between two 2d points
-const dist = (x0: number, y0: number, x1: number, y1: number) => Math.sqrt((x1 - x0) ** 2 + (y1 - y0) ** 2);
-
-class PointerController {
- update: (deltaTime: number) => void;
- destroy: () => void;
-
- constructor(camera: Camera, target: HTMLElement) {
-
- const orbit = (dx: number, dy: number) => {
- const azim = camera.azim - dx * camera.scene.config.controls.orbitSensitivity;
- const elev = camera.elevation - dy * camera.scene.config.controls.orbitSensitivity;
- camera.setAzimElev(azim, elev);
- }
-
- const pan = (x: number, y: number, dx: number, dy: number) => {
- // For panning to work at any zoom level, we use screen point to world projection
- // to work out how far we need to pan the pivotEntity in world space
- const c = camera.entity.camera;
- const distance = camera.distanceTween.value.distance * camera.sceneRadius / camera.fovFactor;
-
- c.screenToWorld(x, y, distance, fromWorldPoint);
- c.screenToWorld(x - dx, y - dy, distance, toWorldPoint);
-
- worldDiff.sub2(toWorldPoint, fromWorldPoint);
- worldDiff.add(camera.focalPoint);
-
- camera.setFocalPoint(worldDiff);
- };
-
- const zoom = (amount: number) => {
- camera.setDistance(camera.distance - (camera.distance * 0.999 + 0.001) * amount * camera.scene.config.controls.zoomSensitivity, 2);
- };
-
- // mouse state
- const buttons = [false, false, false];
- let x: number, y: number;
-
- // touch state
- let touches: { id: number, x: number, y: number}[] = [];
- let midx: number, midy: number, midlen: number;
-
- const pointerdown = (event: PointerEvent) => {
- if (event.pointerType === 'mouse') {
- if (buttons.every(b => !b)) {
- target.setPointerCapture(event.pointerId);
- }
- buttons[event.button] = true;
- x = event.offsetX;
- y = event.offsetY;
- } else if (event.pointerType === 'touch') {
- if (touches.length === 0) {
- target.setPointerCapture(event.pointerId);
- }
- touches.push({
- x: event.offsetX,
- y: event.offsetY,
- id: event.pointerId
- });
-
- if (touches.length === 2) {
- midx = (touches[0].x + touches[1].x) * 0.5;
- midy = (touches[0].y + touches[1].y) * 0.5;
- midlen = dist(touches[0].x, touches[0].y, touches[1].x, touches[1].y);
- }
- }
- };
-
- const pointerup = (event: PointerEvent) => {
- if (event.pointerType === 'mouse') {
- buttons[event.button] = false;
- if (buttons.every(b => !b)) {
- target.releasePointerCapture(event.pointerId);
- }
- } else {
- touches = touches.filter((touch) => touch.id !== event.pointerId);
- if (touches.length === 0) {
- target.releasePointerCapture(event.pointerId);
- }
- }
- };
-
- const pointermove = (event: PointerEvent) => {
- if (event.pointerType === 'mouse') {
- const dx = event.offsetX - x;
- const dy = event.offsetY - y;
- x = event.offsetX;
- y = event.offsetY;
-
- // right button can be used to orbit with ctrl key and to zoom with alt | meta key
- const mod = buttons[2] ?
- (event.shiftKey || event.ctrlKey ? 'orbit' :
- (event.altKey || event.metaKey ? 'zoom' : null)) :
- null;
-
- if (mod === 'orbit' || (mod === null && buttons[0])) {
- orbit(dx, dy);
- } else if (mod === 'zoom' || (mod === null && buttons[1])) {
- zoom(dy * -0.02);
- } else if (mod === 'pan' || (mod === null && buttons[2])) {
- pan(x, y, dx, dy);
- }
- } else {
- if (touches.length === 1) {
- const touch = touches[0];
- const dx = event.offsetX - touch.x;
- const dy = event.offsetY - touch.y;
- touch.x = event.offsetX;
- touch.y = event.offsetY;
- orbit(dx, dy);
- } else if (touches.length === 2) {
- const touch = touches[touches.map(t => t.id).indexOf(event.pointerId)];
- touch.x = event.offsetX;
- touch.y = event.offsetY;
-
- const mx = (touches[0].x + touches[1].x) * 0.5;
- const my = (touches[0].y + touches[1].y) * 0.5;
- const ml = dist(touches[0].x, touches[0].y, touches[1].x, touches[1].y);
-
- pan(mx, my, (mx - midx), (my - midy));
- zoom((ml - midlen) * 0.01);
-
- midx = mx;
- midy = my;
- midlen = ml;
- }
- }
- };
-
- const wheel = (event: WheelEvent) => {
- const sign = (v: number) => v > 0 ? 1 : v < 0 ? -1 : 0;
- zoom(sign(event.deltaY) * -0.2);
- orbit(sign(event.deltaX) * 2.0, 0);
- };
-
- // FIXME: safari sends canvas as target of dblclick event but chrome sends the target element
- const canvas = camera.scene.app.graphicsDevice.canvas;
-
- const dblclick = (event: globalThis.MouseEvent) => {
- if (event.target === target || event.target === canvas) {
- camera.pickFocalPoint(event.offsetX, event.offsetY);
- }
- };
-
- // key state
- const keys: any = {
- ArrowUp: 0,
- ArrowDown: 0,
- ArrowLeft: 0,
- ArrowRight: 0
- };
-
- const keydown = (event: KeyboardEvent) => {
- if (keys.hasOwnProperty(event.key) && event.target === document.body) {
- keys[event.key] = event.shiftKey ? 10 : (event.ctrlKey || event.metaKey || event.altKey ? 0.1 : 1);
- }
- };
-
- const keyup = (event: KeyboardEvent) => {
- if (keys.hasOwnProperty(event.key)) {
- keys[event.key] = 0;
- }
- };
-
- this.update = (deltaTime: number) => {
- const x = keys.ArrowRight - keys.ArrowLeft;
- const z = keys.ArrowDown - keys.ArrowUp;
-
- if (x || z) {
- const factor = deltaTime * camera.distance * camera.sceneRadius * 20;
- const worldTransform = camera.entity.getWorldTransform();
- const xAxis = worldTransform.getX().mulScalar(x * factor);
- const zAxis = worldTransform.getZ().mulScalar(z * factor);
- const p = camera.focalPoint.add(xAxis).add(zAxis);
- camera.setFocalPoint(p);
- }
- };
-
- let destroy: () => void = null;
-
- const wrap = (target: any, name: string, fn: any) => {
- const callback = (event: any) => {
- camera.scene.events.fire('camera.controller', name);
- fn(event);
- };
- target.addEventListener(name, callback);
- destroy = () => {
- destroy?.();
- target.removeEventListener(name, callback);
- };
- };
-
- wrap(target, 'pointerdown', pointerdown);
- wrap(target, 'pointerup', pointerup);
- wrap(target, 'pointermove', pointermove);
- wrap(target, 'wheel', wheel);
- wrap(target, 'dblclick', dblclick);
- wrap(document, 'keydown', keydown);
- wrap(document, 'keyup', keyup);
-
- this.destroy = destroy;
- }
-}
-
-export { PointerController };
diff --git a/mirror-2/splat/src/custom-shadow.ts b/mirror-2/splat/src/custom-shadow.ts
deleted file mode 100644
index 6e239c94..00000000
--- a/mirror-2/splat/src/custom-shadow.ts
+++ /dev/null
@@ -1,365 +0,0 @@
-import {
- ADDRESS_CLAMP_TO_EDGE,
- BLEND_PREMULTIPLIED,
- PROJECTION_ORTHOGRAPHIC,
- SEMANTIC_POSITION,
- SEMANTIC_TEXCOORD0,
- createShaderFromCode,
- drawQuadWithShader,
- shaderChunks,
- Color,
- Entity,
- GraphicsDevice,
- Material,
- MeshInstance,
- RenderComponent,
- RenderTarget,
- Shader,
- StandardMaterial,
- Texture
-} from 'playcanvas';
-import {Element, ElementType} from './element';
-import {Model} from './model';
-
-// shadow map dimension
-const dim = 512;
-
-const shadowPS = (dim: string) => {
- return /*glsl_*/ `
-uniform sampler2D source;
-varying vec2 vUv0;
-
-float dim = ${dim};
-float step = 1.0 / ${dim};
-
-const int numSamples = 32;
-
-float random(vec2 co)
-{
- float a = 12.9898;
- float b = 78.233;
- float c = 43758.5453;
- float dt = dot(co.xy ,vec2(a,b));
- float sn = mod(dt,3.14);
- return fract(sin(sn) * c);
-}
-
-void main(void)
-{
- vec2 uv = vUv0;
-
- float filterSize = step * 10.0;
-
- float sum = 0.0;
- for (int i = 0; i < numSamples; ++i) {
-
- float radius = random(vec2(uv.x * dim, i)) * filterSize;
- float angle = random(vec2(i, uv.y * dim)) * 2.0 * 3.14159;
- vec2 offset = vec2(cos(angle), sin(angle)) * radius;
-
- vec4 t = texture2D(source, uv + offset);
-
- sum += 1.0 - t.y;
- }
-
- gl_FragColor = vec4(0, 0, 0, sum / float(numSamples));
-}
-`;
-};
-
-const shadowDef = {
- vertex: (shaderChunks as any).fullscreenQuadVS,
- fragment: shadowPS(`${dim}.0`)
-};
-
-// blur shader
-const blurPS = (stepX: string, stepY: string) => {
- return /*glsl_*/ `
-uniform sampler2D source;
-varying vec2 vUv0;
-
-vec2 step = vec2(${stepX}, ${stepY});
-
-void main(void)
-{
- vec2 uv = vUv0;
-
- gl_FragColor = (
- texture2D(source, uv - step * 3.5) +
- texture2D(source, uv - step * 2.5) +
- texture2D(source, uv - step * 1.5) +
- texture2D(source, uv - step * 0.5) +
- texture2D(source, uv + step * 0.5) +
- texture2D(source, uv + step * 1.5) +
- texture2D(source, uv + step * 2.5) +
- texture2D(source, uv + step * 3.5)
- ) / 8.0;
-}
-`;
-};
-
-const hblurDef = {
- vertex: (shaderChunks as any).fullscreenQuadVS,
- fragment: blurPS(`1.0 / ${dim}.0`, `0.0`)
-};
-
-const vblurDef = {
- vertex: (shaderChunks as any).fullscreenQuadVS,
- fragment: blurPS(`0.0`, `1.0 / ${dim}.0`)
-};
-
-// catcher shader
-const catcherVS = /*glsl_*/ `
-attribute vec3 vertex_position;
-attribute vec2 vertex_texCoord;
-
-uniform mat4 matrix_model;
-uniform mat4 matrix_viewProjection;
-
-varying vec2 texCoord;
-varying vec3 worldPos;
-
-void main(void)
-{
- // vertex in the world space
- gl_Position = matrix_viewProjection * matrix_model * vec4(vertex_position, 1.0);
- texCoord = vertex_texCoord;
- worldPos = (matrix_model * vec4(vertex_position, 1.0)).xyz;
-}
-`;
-
-const catcherPS = /*glsl_*/ `
-uniform sampler2D source;
-uniform float shadowIntensity;
-
-varying vec2 texCoord;
-varying vec3 worldPos;
-
-uniform vec3 view_position;
-uniform vec3 sceneMin;
-uniform vec3 sceneMax;
-
-void main(void)
-{
- float shadow = texture2D(source, texCoord).a;
-
- shadow = pow(shadow, 1.25);
-
- float v = max(0.0, min(1.0, normalize(view_position - worldPos).y * 6.0)) * 2.0;
- float fade = (v < 1.0) ? (v * v * 0.5) : ((v - 1.0) * (v - 3.0) - 1.0) * -0.5;
- gl_FragColor = vec4(0, 0, 0, mix(0.0, shadowIntensity, shadow) * fade);
-}
-`;
-
-const catcherDef = {
- vertex: catcherVS,
- fragment: catcherPS,
- attributes: {
- vertex_position: SEMANTIC_POSITION,
- vertex_texCoord: SEMANTIC_TEXCOORD0
- }
-};
-
-// helper function to create shader
-const createShader = (
- graphicsDevice: GraphicsDevice,
- name: string,
- shaderInfo: {vertex: string; fragment: string; attributes?: any}
-) => {
- return createShaderFromCode(graphicsDevice, shaderInfo.vertex, shaderInfo.fragment, name, shaderInfo.attributes);
-};
-
-class CustomShadow extends Element {
- material: Material;
- plane: Entity;
-
- shadowShader: Shader;
- hblurShader: Shader;
- vblurShader: Shader;
-
- camera: Entity;
- textures: Texture[] = [];
- renderTargets: RenderTarget[] = [];
-
- constructor() {
- super(ElementType.shadow);
-
- this.material = new Material();
- this.material.depthWrite = false;
- this.material.blendType = BLEND_PREMULTIPLIED;
-
- this.plane = new Entity('ShadowPlane');
- this.plane.addComponent('render', {
- type: 'plane',
- castShadows: false,
- material: this.material
- });
-
- // create camera
- this.camera = new Entity('ShadowCamera');
- this.camera.addComponent('camera', {
- clearColor: new Color(255, 255, 255, 0),
- frustumCulling: false,
- projection: PROJECTION_ORTHOGRAPHIC,
- aspectRatio: 1
- });
- this.camera.enabled = false;
- this.camera.camera.setShaderPass('shadow_catcher_depth');
- }
-
- destroy() {
- super.destroy();
- this.plane.destroy();
- }
-
- add() {
- // create the camera render target
- for (let i = 0; i < 2; ++i) {
- this.textures[i] = new Texture(this.scene.graphicsDevice, {
- name: `custom-shadow-${i}`,
- width: dim,
- height: dim,
- mipmaps: false,
- addressU: ADDRESS_CLAMP_TO_EDGE,
- addressV: ADDRESS_CLAMP_TO_EDGE
- });
- }
-
- this.renderTargets = this.textures.map(texture => new RenderTarget({colorBuffer: texture, depth: true}));
-
- this.camera.camera.renderTarget = this.renderTargets[0];
-
- this.material.shader = createShader(this.scene.graphicsDevice, 'ShadowCatcher', catcherDef);
- this.material.setParameter('source', this.textures[1]);
- this.material.update();
-
- this.shadowShader = createShader(this.scene.graphicsDevice, 'Shadow', shadowDef);
-
- this.hblurShader = createShader(this.scene.graphicsDevice, 'HBlur', hblurDef);
- this.vblurShader = createShader(this.scene.graphicsDevice, 'VBlur', vblurDef);
-
- this.scene.app.root.addChild(this.plane);
- this.scene.app.root.addChild(this.camera);
-
- this.scene.events.on('scene.boundChanged', this.regenerate, this);
- this.scene.graphicsDevice.on('devicerestored', this.regenerate, this);
- }
-
- remove() {
- this.scene.graphicsDevice.off('devicerestored', this.regenerate, this);
- this.scene.events.off('scene.boundChanged', this.regenerate, this);
-
- this.scene.app.root.removeChild(this.camera);
- this.scene.app.root.removeChild(this.plane);
-
- this.camera.camera.renderTarget = null;
-
- this.shadowShader.destroy();
- this.shadowShader = null;
-
- this.hblurShader.destroy();
- this.vblurShader.destroy();
- this.hblurShader = this.vblurShader = null;
-
- this.material.shader.destroy();
- this.material.shader = null;
- this.material.update();
-
- this.renderTargets.forEach(rt => rt.destroy());
- this.renderTargets = [];
-
- this.textures.forEach(tex => tex.destroy());
- this.textures = [];
- }
-
- regenerate() {
- const bound = this.scene.bound;
- const center = bound.center;
- const extents = bound.halfExtents;
- const len = Math.max(extents.x, extents.z);
-
- // place camera
- this.camera.setPosition(center.x, bound.getMin().y, center.z);
- this.camera.setLocalEulerAngles(90, 0, 0);
- this.camera.camera.nearClip = 0;
- this.camera.camera.farClip = extents.y * 2;
- this.camera.camera.orthoHeight = len * 2;
-
- // place the plane under the scene
- this.plane.setPosition(center.x, bound.getMin().y, center.z);
- this.plane.setLocalScale(len * 4, 1, len * 4);
-
- const graphicsDevice = this.scene.graphicsDevice;
-
- graphicsDevice.scope.resolve('sceneMin').setValue([center.x - len, bound.getMin().y, center.z - len]);
- graphicsDevice.scope.resolve('sceneMax').setValue([center.x + len, bound.getMax().y, center.z + len]);
-
- // render the top-down view
- this.camera.enabled = true;
- this.plane.enabled = false;
- this.scene.camera.entity.enabled = false;
-
- this.scene.app.root.syncHierarchy();
- this.scene.app.renderComposition(this.scene.app.scene.layers);
-
- const source = graphicsDevice.scope.resolve('source');
-
- // resolve shadow
- source.setValue(this.textures[0]);
- drawQuadWithShader(graphicsDevice, this.renderTargets[1], this.shadowShader);
-
- for (let i = 0; i < 2; ++i) {
- // hblur
- source.setValue(this.textures[1]);
- drawQuadWithShader(graphicsDevice, this.renderTargets[0], this.hblurShader);
-
- // vblur
- source.setValue(this.textures[0]);
- drawQuadWithShader(graphicsDevice, this.renderTargets[1], this.vblurShader);
- }
-
- // restore cameras
- this.camera.enabled = false;
- this.plane.enabled = true;
- this.scene.camera.entity.enabled = true;
- }
-
- onPreRender() {
- this.material.setParameter('shadowIntensity', this.scene.config.shadow.intensity);
- }
-
- onAdded(element: Element): void {
- if (element.type === ElementType.model || element.type === ElementType.splat) {
- const seen = new Set();
-
- const modelElement = element as Model;
-
- modelElement.entity.findComponents('render').forEach((render: RenderComponent) => {
- render.meshInstances.forEach((meshInstance: MeshInstance) => {
- const material = meshInstance.material as StandardMaterial;
-
- if (!seen.has(material)) {
- seen.add(material);
-
- material.chunks = {
- basePS:
- (shaderChunks as any).basePS +
- /*glsl*/ `
- uniform vec3 sceneMin;
- uniform vec3 sceneMax;
- `,
- debugOutputPS: /*glsl*/ `
- #ifdef SHADOW_CATCHER_DEPTH_PASS
- gl_FragColor.rgb = (vPositionW - sceneMin) / (sceneMax - sceneMin);
- #endif
- `
- };
- material.update();
- }
- });
- });
- }
- }
-}
-
-export {CustomShadow};
diff --git a/mirror-2/splat/src/data-processor.ts b/mirror-2/splat/src/data-processor.ts
deleted file mode 100644
index 84f83f37..00000000
--- a/mirror-2/splat/src/data-processor.ts
+++ /dev/null
@@ -1,399 +0,0 @@
-import {
- ADDRESS_CLAMP_TO_EDGE,
- PIXELFORMAT_RGBA8,
- PIXELFORMAT_RGBA32F,
- SEMANTIC_POSITION,
- createShaderFromCode,
- drawQuadWithShader,
- BoundingBox,
- GraphicsDevice,
- Mat4,
- RenderTarget,
- ScopeSpace,
- Shader,
- Texture,
- Vec3,
- WebglGraphicsDevice,
-} from 'playcanvas';
-import { Splat } from './splat';
-
-import { vertexShader as intersectionVS, fragmentShader as intersectionFS } from './shaders/intersection-shader';
-import { vertexShader as boundVS, fragmentShader as boundFS } from './shaders/bound-shader';
-import { vertexShader as positionVS, fragmentShader as positionFS } from './shaders/position-shader';
-
-type MaskOptions = {
- mask: Texture;
-};
-
-type RectOptions = {
- rect: { x1: number, y1: number, x2: number, y2: number };
-};
-
-type SphereOptions = {
- sphere: { x: number, y: number, z: number, radius: number };
-};
-
-const v1 = new Vec3();
-const v2 = new Vec3();
-
-const resolve = (scope: ScopeSpace, values: any) => {
- for (const key in values) {
- scope.resolve(key).setValue(values[key]);
- }
-};
-
-type IntersectResources = {
- shader: Shader;
- texture: Texture;
- renderTarget: RenderTarget;
- data: Uint8Array;
-};
-
-type BoundResources = {
- shader: Shader;
- minTexture: Texture;
- maxTexture: Texture;
- renderTarget: RenderTarget;
- minRenderTarget: RenderTarget;
- maxRenderTarget: RenderTarget;
- minData: Float32Array;
- maxData: Float32Array;
-};
-
-type PositionResources = {
- shader: Shader;
- texture: Texture;
- renderTarget: RenderTarget;
- data: Float32Array;
-};
-
-// gpu processor for splat data
-class DataProcessor {
- device: GraphicsDevice;
- dummyTexture: Texture;
- viewProjectionMat = new Mat4();
- splatParams = new Int32Array(3);
-
- getIntersectResources: (width: number, numSplats: number) => IntersectResources;
- getBoundResources: (splatTextureWidth: number) => BoundResources;
- getPositionResources: (width: number, height: number, numSplats: number) => PositionResources;
-
- constructor(device: GraphicsDevice) {
- this.device = device;
- this.dummyTexture = new Texture(device, {
- width: 1,
- height: 1,
- format: PIXELFORMAT_RGBA8
- });
-
- const createTexture = (name: string, width: number, height: number, format: number) => {
- return new Texture(device, {
- name, width, height, format,
- mipmaps: false,
- addressU: ADDRESS_CLAMP_TO_EDGE,
- addressV: ADDRESS_CLAMP_TO_EDGE
- });
- };
-
- // intersection test
-
- this.getIntersectResources = (() => {
- let shader: Shader = null;
- let texture: Texture = null;
- let renderTarget: RenderTarget = null;
- let data: Uint8Array = null;
-
- return (width: number, numSplats: number) => {
- if (!shader) {
- shader = createShaderFromCode(device, intersectionVS, intersectionFS, 'intersectByMaskShader', {
- vertex_position: SEMANTIC_POSITION
- });
- }
-
- const resultWidth = Math.max(1, Math.floor(width / 2));
- const resultHeight = Math.ceil(numSplats / (resultWidth * 4));
-
- if (!texture || texture.width !== resultWidth || texture.height !== resultHeight) {
- if (texture) {
- texture.destroy();
- renderTarget.destroy();
- }
-
- texture = createTexture('intersectTexture', resultWidth, resultHeight, PIXELFORMAT_RGBA8);
- renderTarget = new RenderTarget({
- colorBuffer: texture,
- depth: false
- });
-
- data = new Uint8Array(resultWidth * resultHeight * 4);
- }
-
- return { shader, texture, renderTarget, data };
- };
- })();
-
- // calc bound
-
- this.getBoundResources = (() => {
- let shader: Shader = null;
- let minTexture: Texture = null;
- let maxTexture: Texture = null;
- let renderTarget: RenderTarget = null;
- let minRenderTarget: RenderTarget = null;
- let maxRenderTarget: RenderTarget = null;
- let minData: Float32Array = null;
- let maxData: Float32Array = null;
-
- return (width: number) => {
- if (!shader) {
- shader = createShaderFromCode(device, boundVS, boundFS, 'calcBoundShader', {
- vertex_position: SEMANTIC_POSITION
- });
- }
-
- if (!minTexture || minTexture.width !== width) {
- if (minTexture) {
- minTexture.destroy();
- maxTexture.destroy();
- renderTarget.destroy();
- minRenderTarget.destroy();
- maxRenderTarget.destroy();
- }
-
- minTexture = createTexture('calcBoundMin', width, 1, PIXELFORMAT_RGBA32F);
- maxTexture = createTexture('calcBoundMax', width, 1, PIXELFORMAT_RGBA32F);
-
- renderTarget = new RenderTarget({
- colorBuffers: [minTexture, maxTexture],
- depth: false
- });
-
- maxRenderTarget = new RenderTarget({
- colorBuffer: maxTexture,
- depth: false
- });
-
- minRenderTarget = new RenderTarget({
- colorBuffer: minTexture,
- depth: false
- });
-
- minData = new Float32Array(width * 4);
- maxData = new Float32Array(width * 4);
- }
-
- return { shader, minTexture, maxTexture, renderTarget, minRenderTarget, maxRenderTarget, minData, maxData };
- };
- })();
-
- // calc position
-
- this.getPositionResources = (() => {
- let shader: Shader = null;
- let texture: Texture = null;
- let renderTarget: RenderTarget = null;
- let data: Float32Array = null;
-
- return (width: number, height: number, numSplats: number) => {
- if (!shader) {
- shader = createShaderFromCode(device, positionVS, positionFS, 'calcPositionShader', {
- vertex_position: SEMANTIC_POSITION
- });
- }
-
- if (!texture || texture.width !== width || texture.height !== height) {
- if (texture) {
- texture.destroy();
- renderTarget.destroy();
- }
-
- texture = createTexture('positionTex', width, height, PIXELFORMAT_RGBA32F);
- renderTarget = new RenderTarget({
- colorBuffer: texture,
- depth: false
- });
- data = new Float32Array(width * height * 4);
- }
-
- return { shader, texture, renderTarget, data };
- };
- })();
- }
-
- // calculate the intersection of a mask canvas with splat centers
- intersect(options: MaskOptions | RectOptions | SphereOptions, splat: Splat) {
- const { device } = this;
- const { scope } = device;
-
- const numSplats = splat.splatData.numSplats;
- const transformA = splat.entity.gsplat.instance.splat.transformATexture;
- const splatTransform = splat.transformTexture;
- const transformPalette = splat.transformPalette.texture;
-
- // update view projection matrix
- const camera = splat.scene.camera.entity.camera;
- this.viewProjectionMat.mul2(camera.projectionMatrix, camera.viewMatrix);
-
- // allocate resources
- const resources = this.getIntersectResources(transformA.width, numSplats);
-
- resolve(scope, {
- transformA,
- splatTransform,
- transformPalette,
- splat_params: [transformA.width, numSplats],
- matrix_model: splat.entity.getWorldTransform().data,
- matrix_viewProjection: this.viewProjectionMat.data,
- output_params: [resources.texture.width, resources.texture.height]
- });
-
- const maskOptions = options as MaskOptions;
-
- if (maskOptions.mask) {
- resolve(scope, {
- mode: 0,
- mask: maskOptions.mask,
- mask_params: [maskOptions.mask.width, maskOptions.mask.height]
- });
- } else {
- resolve(scope, {
- mask: this.dummyTexture,
- mask_params: [0, 0]
- })
- }
-
- const rectOptions = options as RectOptions;
- if (rectOptions.rect) {
- resolve(scope, {
- mode: 1,
- rect_params: [
- rectOptions.rect.x1 * 2.0 - 1.0,
- rectOptions.rect.y1 * 2.0 - 1.0,
- rectOptions.rect.x2 * 2.0 - 1.0,
- rectOptions.rect.y2 * 2.0 - 1.0
- ]
- })
- } else {
- resolve(scope, {
- rect_params: [0, 0, 0, 0]
- });
- }
-
- const sphereOptions = options as SphereOptions;
- if (sphereOptions.sphere) {
- resolve(scope, {
- mode: 2,
- sphere_params: [
- sphereOptions.sphere.x,
- sphereOptions.sphere.y,
- sphereOptions.sphere.z,
- sphereOptions.sphere.radius
- ]
- });
- } else {
- resolve(scope, {
- sphere_params: [0, 0, 0, 0]
- });
- }
-
- drawQuadWithShader(device, resources.renderTarget, resources.shader);
-
- const glDevice = device as WebglGraphicsDevice;
- glDevice.readPixels(0, 0, resources.texture.width, resources.texture.height, resources.data);
-
- return resources.data;
- }
-
- // use gpu to calculate either bound of the currently selected splats or the bound of
- // all visible splats
- calcBound(splat: Splat, boundingBox: BoundingBox, onlySelected: boolean) {
- const device = splat.scene.graphicsDevice;
- const { scope } = device;
-
- const numSplats = splat.splatData.numSplats;
- const transformA = splat.entity.gsplat.instance.splat.transformATexture;
- const splatTransform = splat.transformTexture;
- const transformPalette = splat.transformPalette.texture;
- const splatState = splat.stateTexture;
-
- this.splatParams[0] = transformA.width;
- this.splatParams[1] = transformA.height;
- this.splatParams[2] = numSplats;
-
- // get resources
- const resources = this.getBoundResources(transformA.width);
-
- resolve(scope, {
- transformA,
- splatTransform,
- transformPalette,
- splatState,
- splat_params: this.splatParams,
- mode: onlySelected ? 0 : 1,
- });
-
- const glDevice = device as WebglGraphicsDevice;
-
- drawQuadWithShader(device, resources.renderTarget, resources.shader);
- glDevice.gl.readPixels(0, 0, transformA.width, 1, resources.minTexture.impl._glFormat, resources.minTexture.impl._glPixelType, resources.minData);
-
- glDevice.setRenderTarget(resources.maxRenderTarget);
- glDevice.updateBegin();
- glDevice.gl.readPixels(0, 0, transformA.width, 1, resources.maxTexture.impl._glFormat, resources.maxTexture.impl._glPixelType, resources.maxData);
- glDevice.updateEnd();
-
- // resolve mins/maxs
- const { minData, maxData } = resources;
- v1.set(minData[0], minData[1], minData[2]);
- v2.set(maxData[0], maxData[1], maxData[2]);
-
- for (let i = 1; i < transformA.width; i++) {
- v1.x = Math.min(v1.x, minData[i * 4]);
- v1.y = Math.min(v1.y, minData[i * 4 + 1]);
- v1.z = Math.min(v1.z, minData[i * 4 + 2]);
-
- v2.x = Math.max(v2.x, maxData[i * 4]);
- v2.y = Math.max(v2.y, maxData[i * 4 + 1]);
- v2.z = Math.max(v2.z, maxData[i * 4 + 2]);
- }
-
- boundingBox.setMinMax(v1, v2);
- }
-
- // calculate world-space splat positions
- calcPositions(splat: Splat) {
- const { device } = this;
- const { scope } = device;
-
- const numSplats = splat.splatData.numSplats;
- const transformA = splat.entity.gsplat.instance.splat.transformATexture;
- const splatTransform = splat.transformTexture;
- const transformPalette = splat.transformPalette.texture;
-
- // allocate resources
- const resources = this.getPositionResources(transformA.width, transformA.height, numSplats);
-
- resolve(scope, {
- transformA,
- splatTransform,
- transformPalette,
- splat_params: [transformA.width, numSplats]
- });
-
- drawQuadWithShader(device, resources.renderTarget, resources.shader);
-
- const glDevice = device as WebglGraphicsDevice;
- glDevice.gl.readPixels(
- 0, 0,
- resources.texture.width,
- resources.texture.height,
- resources.texture.impl._glFormat,
- resources.texture.impl._glPixelType,
- resources.data
- );
-
- return resources.data;
- }
-}
-
-export { DataProcessor };
diff --git a/mirror-2/splat/src/debug.ts b/mirror-2/splat/src/debug.ts
deleted file mode 100644
index 9ca09b72..00000000
--- a/mirror-2/splat/src/debug.ts
+++ /dev/null
@@ -1,97 +0,0 @@
-import {
- BLEND_NONE,
- SEMANTIC_COLOR,
- SEMANTIC_POSITION,
- createShaderFromCode,
- GraphNode,
- Material,
- Mesh,
- MeshInstance,
- Shader,
-} from 'playcanvas';
-import { Element, ElementType } from './element';
-
-const vertexShader = `
-attribute vec3 vertex_position;
-attribute vec4 vertex_color;
-
-varying vec4 vColor;
-varying vec2 vZW;
-
-uniform mat4 matrix_model;
-uniform mat4 matrix_viewProjection;
-
-void main(void) {
- gl_Position = matrix_viewProjection * matrix_model * vec4(vertex_position, 1.0);
-
- // store z/w for later use in fragment shader
- vColor = vertex_color;
- vZW = gl_Position.zw;
-
- // disable depth clipping
- gl_Position.z = 0.0;
-}`;
-
-const fragmentShader = `
-precision highp float;
-
-varying vec4 vColor;
-varying vec2 vZW;
-
-void main(void) {
- gl_FragColor = vColor;
-
- // clamp depth in Z to [0, 1] range
- gl_FragDepth = max(0.0, min(1.0, (vZW.x / vZW.y + 1.0) * 0.5));
-}`;
-
-class Debug extends Element {
- shader: Shader;
- material: Material;
- instance: MeshInstance;
-
- constructor() {
- super(ElementType.debug);
- }
-
- destroy() {
- this.shader.destroy();
- this.material.destroy();
- }
-
- add() {
- const app = this.scene.app;
- const device = app.graphicsDevice;
-
- this.shader = createShaderFromCode(device, vertexShader, fragmentShader, 'debug-lines', {
- vertex_position: SEMANTIC_POSITION,
- vertex_color: SEMANTIC_COLOR
- });
-
- this.material = new Material();
- this.material.shader = this.shader;
- this.material.blendType = BLEND_NONE;
- this.material.update();
- }
-
- remove() {
-
- }
-
- set mesh(mesh: Mesh) {
- if (this.instance) {
- this.scene.debugLayer.removeMeshInstances([this.instance], true);
- }
-
- this.instance = new MeshInstance(mesh, this.material, new GraphNode());
- this.instance.cull = false;
- // this.instance.visible = true;
- this.scene.debugLayer.addMeshInstances([this.instance], true);
- }
-
- get mesh() {
- return this.instance?.mesh;
- }
-}
-
-export { Debug };
diff --git a/mirror-2/splat/src/declaration.d.ts b/mirror-2/splat/src/declaration.d.ts
deleted file mode 100644
index b7a7e65d..00000000
--- a/mirror-2/splat/src/declaration.d.ts
+++ /dev/null
@@ -1,14 +0,0 @@
-declare module '*.png' {
- const value: any;
- export default value;
-}
-
-declare module '*.svg' {
- const value: any;
- export default value;
-}
-
-declare module '*.scss' {
- const value: any;
- export default value;
-}
\ No newline at end of file
diff --git a/mirror-2/splat/src/drop-handler.ts b/mirror-2/splat/src/drop-handler.ts
deleted file mode 100644
index da7734d2..00000000
--- a/mirror-2/splat/src/drop-handler.ts
+++ /dev/null
@@ -1,127 +0,0 @@
-import { path } from 'playcanvas';
-
-class DroppedFile {
- filename: string;
- file: File;
-
- constructor(filename: string, file: File) {
- this.filename = filename;
- this.file = file;
- }
-
- get url() {
- return URL.createObjectURL(this.file);
- }
-}
-
-type DropHandlerFunc = (files: Array, resetScene: boolean) => void;
-
-const resolveDirectories = (entries: Array): Promise> => {
- const promises: Promise>[] = [];
- const result: Array = [];
-
- entries.forEach(entry => {
- if (entry.isFile) {
- result.push(entry as FileSystemFileEntry);
- } else if (entry.isDirectory) {
- promises.push(
- new Promise((resolve, reject) => {
- const reader = (entry as FileSystemDirectoryEntry).createReader();
-
- const p: Promise[] = [];
-
- const read = () => {
- reader.readEntries((children: Array) => {
- if (children.length > 0) {
- p.push(resolveDirectories(children));
- read();
- } else {
- Promise.all(p).then((children: Array>) => {
- resolve(children.flat());
- });
- }
- });
- };
- read();
- })
- );
- }
- });
-
- return Promise.all(promises).then((children: Array>) => {
- return result.concat(...children);
- });
-};
-
-const removeCommonPrefix = (urls: Array) => {
- const split = (pathname: string) => {
- const parts = pathname.split(path.delimiter);
- const base = parts[0];
- const rest = parts.slice(1).join(path.delimiter);
- return [base, rest];
- };
- while (true) {
- const parts = split(urls[0].filename);
- if (parts[1].length === 0) {
- return;
- }
- for (let i = 1; i < urls.length; ++i) {
- const other = split(urls[i].filename);
- if (parts[0] !== other[0]) {
- return;
- }
- }
- for (let i = 0; i < urls.length; ++i) {
- urls[i].filename = split(urls[i].filename)[1];
- }
- }
-};
-
-// configure drag and drop
-const CreateDropHandler = (target: HTMLElement, dropHandler: DropHandlerFunc) => {
-
- const dragstart = (ev: DragEvent) => {
- ev.preventDefault();
- ev.stopPropagation();
- ev.dataTransfer.effectAllowed = 'all';
- };
-
- const dragover = (ev: DragEvent) => {
- ev.preventDefault();
- ev.stopPropagation();
- ev.dataTransfer.effectAllowed = 'all';
- };
-
- const drop = async (ev: DragEvent) => {
- ev.preventDefault();
-
- // resolve directories to files
- const entries = await resolveDirectories(
- Array.from(ev.dataTransfer.items).map(item => item.webkitGetAsEntry())
- );
-
- const files = await Promise.all(
- entries.map(entry => {
- return new Promise((resolve, reject) => {
- entry.file((entryFile: any) => {
- resolve(new DroppedFile(entry.fullPath.substring(1), entryFile));
- });
- });
- })
- );
-
- if (files.length > 1) {
- // if all files share a common filename prefix, remove it
- removeCommonPrefix(files);
- }
-
- // finally, call the drop handler
- dropHandler(files, !ev.shiftKey);
- };
-
- target.addEventListener('dragstart', dragstart, true);
- target.addEventListener('dragover', dragover, true);
- target.addEventListener('drop', drop, true);
-};
-
-export { CreateDropHandler };
diff --git a/mirror-2/splat/src/edit-history.ts b/mirror-2/splat/src/edit-history.ts
deleted file mode 100644
index 70a19288..00000000
--- a/mirror-2/splat/src/edit-history.ts
+++ /dev/null
@@ -1,75 +0,0 @@
-import { Events } from './events';
-import { EditOp } from './edit-ops';
-
-class EditHistory {
- history: EditOp[] = [];
- cursor = 0;
- events: Events;
-
- constructor(events: Events) {
- this.events = events;
-
- events.on('edit.undo', () => {
- if (this.canUndo()) {
- this.undo();
- }
- });
-
- events.on('edit.redo', () => {
- if (this.canRedo()) {
- this.redo();
- }
- });
-
- events.on('edit.add', (editOp: EditOp, suppressOp = false) => {
- this.add(editOp, suppressOp);
- });
- }
-
- add(editOp: EditOp, suppressOp = false) {
- while (this.cursor < this.history.length) {
- this.history.pop().destroy?.();
- }
- this.history.push(editOp);
- this.redo(suppressOp);
- }
-
- canUndo() {
- return this.cursor > 0;
- }
-
- canRedo() {
- return this.cursor < this.history.length;
- }
-
- undo() {
- const editOp = this.history[--this.cursor];
- editOp.undo();
- this.events.fire('edit.apply', editOp);
- this.fireEvents();
- }
-
- redo(suppressOp = false) {
- const editOp = this.history[this.cursor++];
- if (!suppressOp) {
- editOp.do();
- }
- this.events.fire('edit.apply', editOp);
- this.fireEvents();
- }
-
- fireEvents() {
- this.events.fire('edit.canUndo', this.canUndo());
- this.events.fire('edit.canRedo', this.canRedo());
- }
-
- clear() {
- this.history.forEach((editOp) => {
- editOp.destroy?.();
- });
- this.history = [];
- this.cursor = 0;
- }
-}
-
-export { EditHistory };
diff --git a/mirror-2/splat/src/edit-ops.ts b/mirror-2/splat/src/edit-ops.ts
deleted file mode 100644
index 4e9d9120..00000000
--- a/mirror-2/splat/src/edit-ops.ts
+++ /dev/null
@@ -1,352 +0,0 @@
-import { Mat4, Vec3 } from 'playcanvas';
-import { Splat } from './splat';
-import { State } from './splat-state';
-import { Transform } from './transform';
-import { Pivot } from './pivot';
-
-interface EditOp {
- name: string;
- do(): void;
- undo(): void;
- destroy?(): void;
-}
-
-// build an index array based on a boolean predicate over indices
-const buildIndex = (total: number, pred: (i: number) => boolean) => {
- let num = 0;
- for (let i = 0; i < total; ++i) {
- if (pred(i)) num++;
- }
-
- const result = new Uint32Array(num);
- let idx = 0;
- for (let i = 0; i < total; ++i) {
- if (pred(i)) {
- result[idx++] = i;
- }
- }
-
- return result;
-};
-
-type filterFunc = (state: number, index: number) => boolean;
-type doFunc = (state: number) => number;
-type undoFunc = (state: number) => number;
-
-class StateOp {
- splat: Splat;
- indices: Uint32Array;
- doIt: doFunc;
- undoIt: undoFunc;
- updateFlags: number;
-
- constructor(splat: Splat, filter: filterFunc, doIt: doFunc, undoIt: undoFunc, updateFlags = State.selected) {
- const splatData = splat.splatData;
- const state = splatData.getProp('state') as Uint8Array;
- const indices = buildIndex(splatData.numSplats, (i) => filter(state[i], i));
-
- this.splat = splat;
- this.indices = indices;
- this.doIt = doIt;
- this.undoIt = undoIt;
- this.updateFlags = updateFlags;
- }
-
- do() {
- const splatData = this.splat.splatData;
- const state = splatData.getProp('state') as Uint8Array;
- for (let i = 0; i < this.indices.length; ++i) {
- const idx = this.indices[i];
- state[idx] = this.doIt(state[idx]);
- }
- this.splat.updateState(this.updateFlags);
- }
-
- undo() {
- const splatData = this.splat.splatData;
- const state = splatData.getProp('state') as Uint8Array;
- for (let i = 0; i < this.indices.length; ++i) {
- const idx = this.indices[i];
- state[idx] = this.undoIt(state[idx]);
- }
- this.splat.updateState(this.updateFlags);
- }
-
- destroy() {
- this.splat = null;
- this.indices = null;
- }
-}
-
-class SelectAllOp extends StateOp {
- name = 'selectAll';
-
- constructor(splat: Splat) {
- super(splat,
- (state) => state === 0,
- (state) => state | State.selected,
- (state) => state & (~State.selected)
- );
- }
-}
-
-class SelectNoneOp extends StateOp {
- name = 'selectNone';
-
- constructor(splat: Splat) {
- super(splat,
- (state) => state === State.selected,
- (state) => state & (~State.selected),
- (state) => state | State.selected
- );
- }
-}
-
-class SelectInvertOp extends StateOp {
- name = 'selectInvert';
-
- constructor(splat: Splat) {
- super(splat,
- (state) => (state & (State.hidden | State.deleted)) === 0,
- (state) => state ^ State.selected,
- (state) => state ^ State.selected
- );
- }
-}
-
-class SelectOp extends StateOp {
- name = 'selectOp';
-
- constructor(splat: Splat, op: 'add'|'remove'|'set', filter: (i: number) => boolean) {
- const filterFunc = {
- add: (state: number, index: number) => (state === 0) && filter(index),
- remove: (state: number, index: number) => (state === State.selected) && filter(index),
- set: (state: number, index: number) => (state === State.selected) !== filter(index),
- };
-
- const doIt = {
- add: (state: number) => state | State.selected,
- remove: (state: number) => state & (~State.selected),
- set: (state: number) => state ^ State.selected
- };
-
- const undoIt = {
- add: (state: number) => state & (~State.selected),
- remove: (state: number) => state | State.selected,
- set: (state: number) => state ^ State.selected
- };
-
- super(splat, filterFunc[op], doIt[op], undoIt[op]);
- }
-}
-
-class HideSelectionOp extends StateOp {
- name = 'hideSelection';
-
- constructor(splat: Splat) {
- super(splat,
- (state) => state === State.selected,
- (state) => state | State.hidden,
- (state) => state & (~State.hidden),
- State.hidden
- );
- }
-}
-
-class UnhideAllOp extends StateOp {
- name = 'unhideAll';
-
- constructor(splat: Splat) {
- super(splat,
- (state) => (state & (State.hidden | State.deleted)) === State.hidden,
- (state) => state & (~State.hidden),
- (state) => state | State.hidden,
- State.hidden
- );
- }
-}
-
-class DeleteSelectionOp extends StateOp {
- name = 'deleteSelection';
-
- constructor(splat: Splat) {
- super(splat,
- (state) => state === State.selected,
- (state) => state | State.deleted,
- (state) => state & (~State.deleted),
- State.deleted
- );
- }
-}
-
-class ResetOp extends StateOp {
- name = 'reset';
-
- constructor(splat: Splat) {
- super(splat,
- (state) => (state & State.deleted) !== 0,
- (state) => state & (~State.deleted),
- (state) => state | State.deleted,
- State.deleted
- );
- }
-}
-
-// op for modifying a splat transform
-class EntityTransformOp {
- name = 'entityTransform';
- splat: Splat;
- oldt: Transform;
- newt: Transform;
-
- constructor(options: { splat: Splat, oldt: Transform, newt: Transform }) {
- this.splat = options.splat;
- this.oldt = options.oldt;
- this.newt = options.newt;
- }
-
- do() {
- this.splat.move(this.newt.position, this.newt.rotation, this.newt.scale);
- }
-
- undo() {
- this.splat.move(this.oldt.position, this.oldt.rotation, this.oldt.scale);
- }
-
- destroy() {
- this.splat = null;
- this.oldt = null;
- this.newt = null;
- }
-}
-
-const mat = new Mat4();
-
-// op for modifying a subset of individual splats
-class SplatsTransformOp {
- name = 'splatsTransform';
-
- splat: Splat;
- transform: Mat4;
- paletteMap: Map;
-
- constructor(options: { splat: Splat, transform: Mat4, paletteMap: Map }) {
- this.splat = options.splat;
- this.transform = options.transform;
- this.paletteMap = options.paletteMap;
- }
-
- do() {
- const { splat, transform, paletteMap } = this;
- const state = splat.splatData.getProp('state') as Uint8Array;
- const indices = splat.transformTexture.lock() as Uint16Array;
-
- // update splat transform palette indices
- for (let i = 0; i < state.length; ++i) {
- if (state[i] === State.selected) {
- indices[i] = paletteMap.get(indices[i]);
- }
- }
-
- splat.transformTexture.unlock();
-
- splat.transformPalette.alloc(paletteMap.size);
-
- // update transform palette
- const { transformPalette } = splat;
- this.paletteMap.forEach((newIdx, oldIdx) => {
- transformPalette.getTransform(oldIdx, mat);
- mat.mul2(transform, mat);
- transformPalette.setTransform(newIdx, mat);
- });
-
- splat.makeSelectionBoundDirty();
- splat.updatePositions();
- }
-
- undo() {
- const { splat, paletteMap } = this;
- const state = splat.splatData.getProp('state') as Uint8Array;
- const indices = splat.transformTexture.lock() as Uint16Array;
-
- // invert the palette map
- const inverseMap = new Map();
- paletteMap.forEach((newIdx, oldIdx) => {
- inverseMap.set(newIdx, oldIdx);
- });
-
- splat.transformTexture.unlock();
-
- // restore the original transform indices
- for (let i = 0; i < state.length; ++i) {
- if (state[i] === State.selected) {
- indices[i] = inverseMap.get(indices[i]);
- }
- }
-
- splat.transformPalette.free(paletteMap.size);
-
- splat.makeSelectionBoundDirty();
- splat.updatePositions();
- }
-
- destroy() {
- this.splat = null;
- this.transform = null;
- this.paletteMap = null;
- }
-}
-
-class PlacePivotOp {
- name = "setPivot";
- pivot: Pivot;
- oldt: Transform;
- newt: Transform;
-
- constructor(options: { pivot: Pivot, oldt: Transform, newt: Transform }) {
- this.pivot = options.pivot;
- this.oldt = options.oldt;
- this.newt = options.newt;
- }
-
- do() {
- this.pivot.place(this.newt);
- }
-
- undo() {
- this.pivot.place(this.oldt);
- }
-}
-
-class MultiOp {
- name = "multiOp";
- ops: EditOp[];
-
- constructor(ops: EditOp[]) {
- this.ops = ops;
- }
-
- do() {
- this.ops.forEach(op => op.do());
- }
-
- undo() {
- this.ops.forEach(op => op.undo());
- }
-}
-
-export {
- EditOp,
- SelectAllOp,
- SelectNoneOp,
- SelectInvertOp,
- SelectOp,
- HideSelectionOp,
- UnhideAllOp,
- DeleteSelectionOp,
- ResetOp,
- EntityTransformOp,
- SplatsTransformOp,
- PlacePivotOp,
- MultiOp
-};
diff --git a/mirror-2/splat/src/editor.ts b/mirror-2/splat/src/editor.ts
deleted file mode 100644
index bfa5923b..00000000
--- a/mirror-2/splat/src/editor.ts
+++ /dev/null
@@ -1,500 +0,0 @@
-import {
- PIXELFORMAT_RGBA8,
- BoundingBox,
- Mat4,
- RenderTarget,
- Texture,
- Vec3,
- Vec4,
-} from 'playcanvas';
-import { Scene } from './scene';
-import { EditHistory } from './edit-history';
-import { Splat } from './splat';
-import { SelectAllOp, SelectNoneOp, SelectInvertOp, SelectOp, HideSelectionOp, UnhideAllOp, DeleteSelectionOp, ResetOp } from './edit-ops';
-import { Events } from './events';
-
-// register for editor and scene events
-const registerEditorEvents = (events: Events, editHistory: EditHistory, scene: Scene) => {
- const vec = new Vec3();
- const vec2 = new Vec3();
- const vec4 = new Vec4();
- const mat = new Mat4();
- const aabb = new BoundingBox();
-
- // get the list of selected splats (currently limited to just a single one)
- const selectedSplats = () => {
- const selected = events.invoke('selection') as Splat;
- return selected?.visible ? [selected] : [];
- };
-
- let lastExportCursor = 0;
-
- // add unsaved changes warning message.
- window.addEventListener("beforeunload", function (e) {
- if (!events.invoke('scene.dirty')) {
- // if the undo cursor matches last export, then we have no unsaved changes
- return undefined;
- }
-
- const msg = 'You have unsaved changes. Are you sure you want to leave?';
- e.returnValue = msg;
- return msg;
- });
-
- events.on('scene.clear', () => {
- scene.clear();
- editHistory.clear();
- lastExportCursor = 0;
- });
-
- events.function('scene.dirty', () => {
- return editHistory.cursor !== lastExportCursor;
- });
-
- events.on('scene.saved', () => {
- lastExportCursor = editHistory.cursor;
- });
-
- events.on('camera.mode', () => {
- scene.forceRender = true;
- });
-
- events.on('camera.overlay', () => {
- scene.forceRender = true;
- });
-
- events.on('camera.splatSize', () => {
- scene.forceRender = true;
- });
-
- events.on('view.bands', (bands: number) => {
- scene.forceRender = true;
- });
-
- events.on('camera.bound', () => {
- scene.forceRender = true;
- });
-
- // grid.visible
-
- const setGridVisible = (visible: boolean) => {
- if (visible !== scene.grid.visible) {
- scene.grid.visible = visible;
- events.fire('grid.visible', visible);
- }
- };
-
- events.function('grid.visible', () => {
- return scene.grid.visible;
- });
-
- events.on('grid.setVisible', (visible: boolean) => {
- setGridVisible(visible);
- });
-
- events.on('grid.toggleVisible', () => {
- setGridVisible(!scene.grid.visible);
- });
-
- setGridVisible(scene.config.show.grid);
-
- // camera.fov
-
- const setCameraFov = (fov: number) => {
- if (fov !== scene.camera.fov) {
- scene.camera.fov = fov;
- events.fire('camera.fov', scene.camera.fov);
- }
- };
-
- events.function('camera.fov', () => {
- return scene.camera.fov;
- });
-
- events.on('camera.setFov', (fov: number) => {
- setCameraFov(fov);
- });
-
- // camera.bound
-
- let bound = scene.config.show.bound;
-
- const setBoundVisible = (visible: boolean) => {
- if (visible !== bound) {
- bound = visible;
- events.fire('camera.bound', bound);
- }
- };
-
- events.function('camera.bound', () => {
- return bound;
- });
-
- events.on('camera.setBound', (value: boolean) => {
- setBoundVisible(value);
- });
-
- events.on('camera.toggleBound', () => {
- setBoundVisible(!events.invoke('camera.bound'));
- });
-
- // camera.focus
-
- events.on('camera.focus', () => {
- const splat = selectedSplats()[0];
- if (splat) {
-
- const bound = splat.numSelected > 0 ? splat.selectionBound : splat.localBound;
- vec.copy(bound.center);
-
- const worldTransform = splat.worldTransform;
- worldTransform.transformPoint(vec, vec);
- worldTransform.getScale(vec2);
-
- scene.camera.focus({
- focalPoint: vec,
- radius: bound.halfExtents.length() * vec2.x,
- speed: 1
- });
- }
- });
-
- // handle camera align events
- events.on('camera.align', (axis: string) => {
- switch (axis) {
- case 'px': scene.camera.setAzimElev(90, 0); break;
- case 'py': scene.camera.setAzimElev(0, -90); break;
- case 'pz': scene.camera.setAzimElev(0, 0); break;
- case 'nx': scene.camera.setAzimElev(270, 0); break;
- case 'ny': scene.camera.setAzimElev(0, 90); break;
- case 'nz': scene.camera.setAzimElev(180, 0); break;
- }
- });
-
- events.on('select.all', () => {
- selectedSplats().forEach((splat) => {
- events.fire('edit.add', new SelectAllOp(splat));
- });
- });
-
- events.on('select.none', () => {
- selectedSplats().forEach((splat) => {
- events.fire('edit.add', new SelectNoneOp(splat));
- });
- });
-
- events.on('select.invert', () => {
- selectedSplats().forEach((splat) => {
- events.fire('edit.add', new SelectInvertOp(splat));
- });
- });
-
- events.on('select.pred', (op, pred: (i: number) => boolean) => {
- selectedSplats().forEach((splat) => {
- events.fire('edit.add', new SelectOp(splat, op, pred));
- });
- });
-
- const intersectCenters = (splat: Splat, op: 'add'|'remove'|'set', options: any) => {
- const data = scene.dataProcessor.intersect(options, splat);
- const filter = (i: number) => data[i] === 255;
- events.fire('edit.add', new SelectOp(splat, op, filter));
- };
-
- events.on('select.bySphere', (op: 'add'|'remove'|'set', sphere: number[]) => {
- selectedSplats().forEach((splat) => {
- intersectCenters(splat, op, {
- sphere: { x: sphere[0], y: sphere[1], z: sphere[2], radius: sphere[3] }
- });
- });
- });
-
- events.on('select.rect', (op: 'add'|'remove'|'set', rect: any) => {
- const mode = events.invoke('camera.mode');
-
- selectedSplats().forEach((splat) => {
- if (mode === 'centers') {
- intersectCenters(splat, op, {
- rect: { x1: rect.start.x, y1: rect.start.y, x2: rect.end.x, y2: rect.end.y },
- });
- } else if (mode === 'rings') {
- const { width, height } = scene.targetSize;
-
- scene.camera.pickPrep(splat);
- const pick = scene.camera.pickRect(
- Math.floor(rect.start.x * width),
- Math.floor(rect.start.y * height),
- Math.floor((rect.end.x - rect.start.x) * width),
- Math.floor((rect.end.y - rect.start.y) * height)
- );
-
- const selected = new Set(pick);
- const filter = (i: number) => {
- return selected.has(i);
- };
-
- events.fire('edit.add', new SelectOp(splat, op, filter));
- }
- });
- });
-
- let maskTexture: Texture = null;
-
- events.on('select.byMask', (op: 'add'|'remove'|'set', canvas: HTMLCanvasElement, context: CanvasRenderingContext2D) => {
- const mode = events.invoke('camera.mode');
-
- selectedSplats().forEach((splat) => {
- if (mode === 'centers') {
- // create mask texture
- if (!maskTexture || maskTexture.width !== canvas.width || maskTexture.height !== canvas.height) {
- if (maskTexture) {
- maskTexture.destroy();
- }
- maskTexture = new Texture(scene.graphicsDevice);
- }
- maskTexture.setSource(canvas);
-
- intersectCenters(splat, op, {
- mask: maskTexture
- });
- } else if (mode === 'rings') {
- const mask = context.getImageData(0, 0, canvas.width, canvas.height);
-
- // calculate mask bound so we limit pixel operations
- let mx0 = mask.width - 1;
- let my0 = mask.height - 1;
- let mx1 = 0;
- let my1 = 0;
- for (let y = 0; y < mask.height; ++y) {
- for (let x = 0; x < mask.width; ++x) {
- if (mask.data[(y * mask.width + x) * 4 + 3] === 255) {
- mx0 = Math.min(mx0, x);
- my0 = Math.min(my0, y);
- mx1 = Math.max(mx1, x);
- my1 = Math.max(my1, y);
- }
- }
- }
-
- const { width, height } = scene.targetSize;
- const px0 = Math.floor(mx0 / mask.width * width);
- const py0 = Math.floor(my0 / mask.height * height);
- const px1 = Math.floor(mx1 / mask.width * width);
- const py1 = Math.floor(my1 / mask.height * height);
- const pw = px1 - px0 + 1;
- const ph = py1 - py0 + 1;
-
- scene.camera.pickPrep(splat);
- const pick = scene.camera.pickRect(px0, py0, pw, ph);
-
- const selected = new Set();
- for (let y = 0; y < ph; ++y) {
- for (let x = 0; x < pw; ++x) {
- const mx = Math.floor((px0 + x) / width * mask.width);
- const my = Math.floor((py0 + y) / height * mask.height);
- if (mask.data[(my * mask.width + mx) * 4] === 255) {
- selected.add(pick[(ph - y) * pw + x]);
- }
- }
- }
-
- const filter = (i: number) => {
- return selected.has(i);
- };
-
- events.fire('edit.add', new SelectOp(splat, op, filter));
- }
- });
- });
-
- events.on('select.point', (op: 'add'|'remove'|'set', point: { x: number, y: number }) => {
- const { width, height } = scene.targetSize;
- const mode = events.invoke('camera.mode');
-
- selectedSplats().forEach((splat) => {
- const splatData = splat.splatData;
-
- if (mode === 'centers') {
- const x = splatData.getProp('x');
- const y = splatData.getProp('y');
- const z = splatData.getProp('z');
-
- const splatSize = events.invoke('camera.splatSize');
- const camera = scene.camera.entity.camera;
- const sx = point.x * width;
- const sy = point.y * height;
-
- // calculate final matrix
- mat.mul2(camera.camera._viewProjMat, splat.worldTransform);
-
- const filter = (i: number) => {
- vec4.set(x[i], y[i], z[i], 1.0);
- mat.transformVec4(vec4, vec4);
- const px = (vec4.x / vec4.w * 0.5 + 0.5) * width;
- const py = (-vec4.y / vec4.w * 0.5 + 0.5) * height;
- return Math.abs(px - sx) < splatSize && Math.abs(py - sy) < splatSize;
- };
-
- events.fire('edit.add', new SelectOp(splat, op, filter));
- } else if (mode === 'rings') {
- scene.camera.pickPrep(splat);
-
- const pickId = scene.camera.pickRect(
- Math.floor(point.x * width),
- Math.floor(point.y * height),
- 1, 1
- )[0];
-
- const filter = (i: number) => {
- return i === pickId;
- };
-
- events.fire('edit.add', new SelectOp(splat, op, filter));
- }
- });
- });
-
- events.on('select.hide', () => {
- selectedSplats().forEach((splat) => {
- events.fire('edit.add', new HideSelectionOp(splat));
- });
- });
-
- events.on('select.unhide', () => {
- selectedSplats().forEach((splat) => {
- events.fire('edit.add', new UnhideAllOp(splat));
- });
- });
-
- events.on('select.delete', () => {
- selectedSplats().forEach((splat) => {
- editHistory.add(new DeleteSelectionOp(splat));
- });
- });
-
- events.on('scene.reset', () => {
- selectedSplats().forEach((splat) => {
- editHistory.add(new ResetOp(splat));
- });
- });
-
- const setAllData = (value: boolean) => {
- if (value !== scene.assetLoader.loadAllData) {
- scene.assetLoader.loadAllData = value;
- events.fire('allData', scene.assetLoader.loadAllData);
- }
- };
-
- events.function('allData', () => {
- return scene.assetLoader.loadAllData;
- });
-
- events.on('toggleAllData', (value: boolean) => {
- setAllData(!events.invoke('allData'));
- });
-
- // camera mode
-
- let activeMode = 'centers';
-
- const setCameraMode = (mode: string) => {
- if (mode !== activeMode) {
- activeMode = mode;
- events.fire('camera.mode', activeMode);
- }
- };
-
- events.function('camera.mode', () => {
- return activeMode;
- });
-
- events.on('camera.setMode', (mode: string) => {
- setCameraMode(mode);
- });
-
- events.on('camera.toggleMode', () => {
- setCameraMode(events.invoke('camera.mode') === 'centers' ? 'rings' : 'centers');
- });
-
- // camera overlay
-
- let cameraOverlay = scene.config.camera.overlay;
-
- const setCameraOverlay = (enabled: boolean) => {
- if (enabled !== cameraOverlay) {
- cameraOverlay = enabled;
- events.fire('camera.overlay', cameraOverlay);
- }
- };
-
- events.function('camera.overlay', () => {
- return cameraOverlay;
- });
-
- events.on('camera.setOverlay', (value: boolean) => {
- setCameraOverlay(value);
- });
-
- events.on('camera.toggleOverlay', () => {
- setCameraOverlay(!events.invoke('camera.overlay'));
- });
-
- // splat size
-
- let splatSize = 2;
-
- const setSplatSize = (value: number) => {
- if (value !== splatSize) {
- splatSize = value;
- events.fire('camera.splatSize', splatSize);
- }
- };
-
- events.function('camera.splatSize', () => {
- return splatSize;
- });
-
- events.on('camera.setSplatSize', (value: number) => {
- setSplatSize(value);
- });
-
- // view spherical harmonic bands
-
- let viewBands = scene.config.show.shBands;
-
- const setViewBands = (value: number) => {
- if (value !== viewBands) {
- viewBands = value;
- events.fire('view.bands', viewBands);
- }
- };
-
- events.function('view.bands', () => {
- return viewBands;
- });
-
- events.on('view.setBands', (value: number) => {
- setViewBands(value);
- });
-
- events.function('camera.getPose', () => {
- const camera = scene.camera;
- const position = camera.entity.getPosition();
- const focalPoint = camera.focalPoint;
- return {
- position: { x: position.x, y: position.y, z: position.z },
- target: { x: focalPoint.x, y: focalPoint.y, z: focalPoint.z }
- };
- });
-
- events.on('camera.setPose', (pose: { position: Vec3, target: Vec3 }, speed = 1) => {
- scene.camera.setPose(pose.position, pose.target, speed);
- });
-
- // hack: fire events to initialize UI
- events.fire('camera.fov', scene.camera.fov);
- events.fire('camera.overlay', cameraOverlay);
- events.fire('view.bands', viewBands);
-}
-
-export { registerEditorEvents };
diff --git a/mirror-2/splat/src/element.ts b/mirror-2/splat/src/element.ts
deleted file mode 100644
index 11e445b9..00000000
--- a/mirror-2/splat/src/element.ts
+++ /dev/null
@@ -1,66 +0,0 @@
-import { BoundingBox, Quat, Vec3 } from 'playcanvas';
-import { Serializer } from './serializer';
-import { Scene } from './scene';
-
-enum ElementType {
- camera = 'camera',
- model = 'model',
- splat = 'splat',
- shadow = 'shadow',
- debug = 'debug',
- other = 'other'
-}
-
-const ElementTypeList = [
- ElementType.camera,
- ElementType.model,
- ElementType.splat,
- ElementType.shadow,
- ElementType.debug,
- ElementType.other
-];
-
-let nextUid = 1;
-
-class Element {
- type: ElementType;
- scene: Scene = null;
- uid: number;
-
- constructor(type: ElementType) {
- this.type = type;
- this.uid = nextUid++;
- }
-
- destroy() {
- if (this.scene) {
- this.scene.remove(this);
- }
- }
-
- add() {}
-
- remove() {}
-
- serialize(serializer: Serializer) {}
-
- onUpdate(deltaTime: number) {}
-
- onPostUpdate() {}
-
- onPreRender() {}
-
- onPostRender() {}
-
- onAdded(element: Element) {}
-
- onRemoved(element: Element) {}
-
- move(position?: Vec3, rotation?: Quat, scale?: Vec3) {}
-
- get worldBound(): BoundingBox | null {
- return null;
- }
-}
-
-export {ElementType, ElementTypeList, Element};
diff --git a/mirror-2/splat/src/entity-transform-handler.ts b/mirror-2/splat/src/entity-transform-handler.ts
deleted file mode 100644
index 3753034f..00000000
--- a/mirror-2/splat/src/entity-transform-handler.ts
+++ /dev/null
@@ -1,126 +0,0 @@
-import { Mat4, Quat, Vec3 } from 'playcanvas';
-import { Events } from './events';
-import { Splat } from './splat';
-import { Transform } from './transform';
-import { PlacePivotOp, EntityTransformOp, MultiOp } from './edit-ops';
-import { TransformHandler } from './transform-handler';
-import { Pivot } from './pivot';
-
-const vec = new Vec3();
-const mat = new Mat4();
-const quat = new Quat();
-const transform = new Transform();
-
-class EntityTransformHandler implements TransformHandler {
- events: Events;
- splat: Splat;
- top: EntityTransformOp;
- pop: PlacePivotOp;
- bindMat = new Mat4();
-
- constructor(events: Events) {
- this.events = events;
-
- events.on('pivot.started', (pivot: Pivot) => {
- if (this.splat) {
- this.start();
- }
- });
-
- events.on('pivot.moved', (pivot: Pivot) => {
- if (this.splat) {
- this.update(pivot.transform);
- }
- });
-
- events.on('pivot.ended', (pivot: Pivot) => {
- if (this.splat) {
- this.end();
- }
- });
-
- events.on('camera.focalPointPicked', (details: { splat: Splat, position: Vec3 }) => {
- if (this.splat) {
- const pivot = events.invoke('pivot') as Pivot;
- const newt = new Transform(details.position, pivot.transform.rotation, pivot.transform.scale);
- const op = new PlacePivotOp({ pivot, oldt: pivot.transform.clone(), newt });
- events.fire('edit.add', op);
- }
- });
- }
-
- placePivot() {
- // place initial pivot point
- const { entity } = this.splat;
- entity.getLocalTransform().transformPoint(this.splat.localBound.center, vec);
- transform.set(vec, entity.getLocalRotation(), entity.getLocalScale());
- this.events.fire('pivot.place', transform);
- }
-
- activate() {
- this.splat = this.events.invoke('selection') as Splat;
- if (this.splat) {
- this.placePivot();
- }
- }
-
- deactivate() {
- this.splat = null;
- }
-
- start() {
- const pivot = this.events.invoke('pivot') as Pivot;
- const { transform } = pivot;
- const { entity } = this.splat;
-
- // calculate bind matrix
- this.bindMat.setTRS(transform.position, transform.rotation, transform.scale);
- this.bindMat.invert();
- this.bindMat.mul2(this.bindMat, entity.getLocalTransform());
-
- const p = entity.getLocalPosition();
- const r = entity.getLocalRotation();
- const s = entity.getLocalScale();
-
- // create op
- this.top = new EntityTransformOp({
- splat: this.splat,
- oldt: new Transform(p, r, s),
- newt: new Transform(p, r, s)
- });
-
- this.pop = new PlacePivotOp({
- pivot,
- oldt: transform.clone(),
- newt: transform.clone()
- });
- }
-
- update(transform: Transform) {
- mat.setTRS(transform.position, transform.rotation, transform.scale);
- mat.mul2(mat, this.bindMat);
- quat.setFromMat4(mat);
-
- const t = mat.getTranslation();
- const r = quat;
- const s = mat.getScale();
-
- this.splat.move(t, r, s);
- this.top.newt.set(t, r, s);
- this.pop.newt.copy(transform);
- }
-
- end() {
- // if anything changed then register the op with undo/redo system
- const { oldt, newt } = this.top;
-
- if (!oldt.equals(newt)) {
- this.events.fire('edit.add', new MultiOp([this.top, this.pop]));
- }
-
- this.top = null;
- this.pop = null;
- }
-}
-
-export { EntityTransformHandler };
diff --git a/mirror-2/splat/src/env.ts b/mirror-2/splat/src/env.ts
deleted file mode 100644
index 1c98a050..00000000
--- a/mirror-2/splat/src/env.ts
+++ /dev/null
@@ -1,71 +0,0 @@
-import {LAYERID_SKYBOX, Asset, Texture, Quat} from 'playcanvas';
-import {Element, ElementType} from './element';
-import {Serializer} from './serializer';
-
-const quat = new Quat();
-
-class Env extends Element {
- asset: Asset;
- envAtlas: Texture;
-
- constructor(asset: Asset) {
- super(ElementType.other);
- this.envAtlas = asset.resource;
- }
-
- destroy() {
- super.destroy();
- this.asset.registry.remove(this.asset);
- this.asset.unload();
- this.envAtlas.destroy();
- }
-
- add() {
- this.scene.app.scene.envAtlas = this.envAtlas;
- this.scene.graphicsDevice.scope.resolve('texture_envAtlas').setValue(this.envAtlas);
-
- // apply scene config
- const config = this.scene.config;
- this.show = false;
- this.intensity = config.env?.intensity || 1.0;
- this.rotation = config.env?.rotation || -90;
- }
-
- remove() {
- this.scene.app.scene.envAtlas = null;
- }
-
- serialize(serializer: Serializer) {
- serializer.pack(this.show, this.intensity, this.rotation);
- }
-
- // show
- set show(value: boolean) {
- this.scene.app.scene.layers.getLayerById(LAYERID_SKYBOX).enabled = value;
- }
-
- get show() {
- return this.scene.app.scene.layers.getLayerById(LAYERID_SKYBOX).enabled;
- }
-
- // intensity
- set intensity(exposure: number) {
- this.scene.app.scene.skyboxIntensity = exposure;
- }
-
- get intensity() {
- return this.scene.app.scene.skyboxIntensity;
- }
-
- // rotation
- set rotation(angle: number) {
- quat.setFromEulerAngles(0, angle, 0);
- this.scene.app.scene.skyboxRotation = quat;
- }
-
- get rotation() {
- return this.scene.app.scene.skyboxRotation.getEulerAngles().y;
- }
-}
-
-export {Env};
diff --git a/mirror-2/splat/src/events.ts b/mirror-2/splat/src/events.ts
deleted file mode 100644
index 8098f190..00000000
--- a/mirror-2/splat/src/events.ts
+++ /dev/null
@@ -1,29 +0,0 @@
-import { EventHandler } from "playcanvas";
-
-class Events extends EventHandler {
- functions = new Map();
-
- constructor() {
- super();
- }
-
- // declare an editor function
- function(name: string, fn: Function) {
- if (this.functions.has(name)) {
- throw new Error(`error: function ${name} already exists`);
- }
- this.functions.set(name, fn);
- }
-
- // invoke an editor function
- invoke(name: string, ...args: any[]) {
- const fn = this.functions.get(name);
- if (!fn) {
- console.log(`error: function not found '${name}'`);
- return;
- }
- return fn(...args);
- }
-}
-
-export { Events };
diff --git a/mirror-2/splat/src/file-handler.ts b/mirror-2/splat/src/file-handler.ts
deleted file mode 100644
index 1835b1aa..00000000
--- a/mirror-2/splat/src/file-handler.ts
+++ /dev/null
@@ -1,380 +0,0 @@
-import { path, Vec3 } from 'playcanvas';
-import { Scene } from './scene';
-import { Events } from './events';
-import { CreateDropHandler } from './drop-handler';
-import { convertPly, convertPlyCompressed, convertSplat } from './splat-convert';
-import { startSpinner, stopSpinner } from './ui/spinner';
-import { ElementType } from './element';
-import { Splat } from './splat';
-import { localize } from './ui/localization';
-
-interface RemoteStorageDetails {
- method: string;
- url: string;
-}
-
-type ExportType = 'ply' | 'compressed-ply' | 'splat';
-
-interface SceneWriteOptions {
- type: ExportType;
- filename?: string;
- stream?: FileSystemWritableFileStream;
-}
-
-const filePickerTypes = {
- 'ply': [{
- description: 'Gaussian Splat PLY File',
- accept: {
- 'application/ply': ['.ply']
- }
- }],
- 'compressed-ply': [{
- description: 'Compressed Gaussian Splat PLY File',
- accept: {
- 'application/ply': ['.ply']
- }
- }],
- 'splat': [{
- description: 'Gaussian Splat File',
- accept: {
- 'application/octet-stream': ['.splat']
- }
- }]
-};
-
-let fileHandle: FileSystemFileHandle = null;
-
-const vec = new Vec3();
-
-// download the data to the given filename
-const download = (filename: string, data: ArrayBuffer) => {
- const blob = new Blob([data], { type: "octet/stream" });
- const url = window.URL.createObjectURL(blob);
-
- const lnk = document.createElement('a');
- lnk.download = filename;
- lnk.href = url;
-
- // create a "fake" click-event to trigger the download
- if (document.createEvent) {
- const e = document.createEvent("MouseEvents");
- e.initMouseEvent("click", true, true, window,
- 0, 0, 0, 0, 0, false, false, false,
- false, 0, null);
- lnk.dispatchEvent(e);
- } else {
- // @ts-ignore
- lnk.fireEvent?.("onclick");
- }
-
- window.URL.revokeObjectURL(url);
-};
-
-// send the file to the remote storage
-const sendToRemoteStorage = async (filename: string, data: ArrayBuffer, remoteStorageDetails: RemoteStorageDetails) => {
- const formData = new FormData();
- formData.append('file', new Blob([data], { type: "octet/stream" }), filename);
- formData.append('preserveThumbnail', 'true');
- await fetch(remoteStorageDetails.url, {
- method: remoteStorageDetails.method,
- body: formData
- });
-};
-
-// write the data to file
-const writeToFile = async (stream: FileSystemWritableFileStream, data: ArrayBuffer) => {
- await stream.seek(0);
- await stream.write(data);
- await stream.truncate(data.byteLength);
- await stream.close();
-};
-
-const loadCameraPoses = async (url: string, filename: string, events: Events) => {
- const response = await fetch(url);
- const json = await response.json();
- if (json.length > 0) {
- // calculate the average position of the camera poses
- const ave = new Vec3(0, 0, 0);
- json.forEach((pose: any) => {
- vec.set(pose.position[0], pose.position[1], pose.position[2]);
- ave.add(vec);
- });
- ave.mulScalar(1 / json.length);
-
- json.forEach((pose: any, i: number) => {
- if (pose.hasOwnProperty('position') && pose.hasOwnProperty('rotation')) {
- const p = new Vec3(pose.position);
- const z = new Vec3(pose.rotation[0][2], pose.rotation[1][2], pose.rotation[2][2]);
-
- const dot = vec.sub2(ave, p).dot(z);
- vec.copy(z).mulScalar(dot).add(p);
-
- events.fire('camera.addPose', {
- name: pose.img_name ?? `${filename}_${i}`,
- position: new Vec3(-p.x, -p.y, p.z),
- target: new Vec3(-vec.x, -vec.y, vec.z)
- });
- }
- });
- }
-};
-
-// initialize file handler events
-const initFileHandler = async (scene: Scene, events: Events, dropTarget: HTMLElement, remoteStorageDetails: RemoteStorageDetails) => {
-
- // returns a promise that resolves when the file is loaded
- const handleLoad = async (url: string, filename: string) => {
- try {
- const lowerFilename = (filename || url).toLowerCase();
- if (lowerFilename.endsWith('.json')) {
- await loadCameraPoses(url, filename, events);
- } else if (lowerFilename.endsWith('.ply') || lowerFilename.endsWith('.splat')) {
- const model = await scene.assetLoader.loadModel({ url, filename });
- scene.add(model);
- scene.camera.focus();
- events.fire('loaded', filename);
- } else {
- throw new Error(`Unsupported file type`);
- }
- } catch (err) {
- events.invoke('showPopup', {
- type: 'error',
- header: localize('popup.error-loading'),
- message: `${err.message ?? err} while loading '${filename}'`
- });
- }
- };
-
- events.function('load', (url: string, filename: string) => {
- return handleLoad(url, filename);
- });
-
- // create a file selector element as fallback when showOpenFilePicker isn't available
- let fileSelector: HTMLInputElement;
- if (!window.showOpenFilePicker) {
- fileSelector = document.createElement('input');
- fileSelector.setAttribute('id', 'file-selector');
- fileSelector.setAttribute('type', 'file');
- fileSelector.setAttribute('accept', '.ply,.splat');
- fileSelector.setAttribute('multiple', 'true');
-
- fileSelector.onchange = async () => {
- const files = fileSelector.files;
- for (let i = 0; i < files.length; i++) {
- const file = fileSelector.files[i];
- const url = URL.createObjectURL(file);
- await handleLoad(url, file.name);
- URL.revokeObjectURL(url);
- }
- };
- document.body.append(fileSelector);
- }
-
- // create the file drag & drop handler
- CreateDropHandler(dropTarget, async (entries) => {
- for (let i = 0; i < entries.length; i++) {
- const entry = entries[i];
- await handleLoad(entry.url, entry.filename);
- }
- });
-
- // get the array of visible splats
- const getSplats = () => {
- return (scene.getElementsByType(ElementType.splat) as Splat[]).filter(splat => splat.visible);
- };
-
- events.function('scene.empty', () => {
- return getSplats().length === 0;
- });
-
- events.function('scene.new', async () => {
- if (events.invoke('scene.dirty')) {
- const result = await events.invoke('showPopup', {
- type: 'yesno',
- header: 'RESET SCENE',
- message: `You have unsaved changes. Are you sure you want to reset the scene?`
- });
-
- if (result.action !== 'yes') {
- return false;
- }
- }
-
- events.fire('scene.clear');
-
- return true;
- });
-
- events.on('scene.open', async () => {
- if (fileSelector) {
- fileSelector.click();
- } else {
- try {
- const handles = await window.showOpenFilePicker({
- id: 'SuperSplatFileOpen',
- multiple: true,
- types: [filePickerTypes.ply, filePickerTypes.splat] as FilePickerAcceptType[]
- });
- for (let i = 0; i < handles.length; i++) {
- const handle = handles[i];
- const file = await handle.getFile();
- const url = URL.createObjectURL(file);
- await handleLoad(url, file.name);
- URL.revokeObjectURL(url);
-
- if (i === 0) {
- fileHandle = handle;
- }
- }
- } catch (error) {
- if (error.name !== 'AbortError') {
- console.error(error);
- }
- }
- }
- });
-
- events.on('scene.save', async () => {
- if (fileHandle) {
- try {
- await events.invoke('scene.write', {
- type: 'ply',
- stream: await fileHandle.createWritable()
- });
- events.fire('scene.saved');
- } catch (error) {
- if (error.name !== 'AbortError') {
- console.error(error);
- }
- }
- } else {
- events.fire('scene.saveAs');
- }
- });
-
- events.on('scene.saveAs', async () => {
- const splats = getSplats();
- const splat = splats[0];
-
- if (window.showSaveFilePicker) {
- try {
- const handle = await window.showSaveFilePicker({
- id: 'SuperSplatFileSave',
- types: filePickerTypes.ply as FilePickerAcceptType[],
- suggestedName: fileHandle?.name ?? splat.filename ?? 'scene.ply'
- });
- await events.invoke('scene.write', {
- type: 'ply',
- stream: await handle.createWritable()
- });
- fileHandle = handle;
- events.fire('scene.saved');
- } catch (error) {
- if (error.name !== 'AbortError') {
- console.error(error);
- }
- }
- } else {
- await events.invoke('scene.export', 'ply', splat.filename, 'saveAs');
- events.fire('scene.saved');
- }
- });
-
- events.function('scene.export', async (type: ExportType, outputFilename: string = null, exportType: 'export' | 'saveAs' = 'export') => {
- const extensions = {
- 'ply': '.ply',
- 'compressed-ply': '.compressed.ply',
- 'splat': '.splat'
- };
-
- const replaceExtension = (filename: string, extension: string) => {
- const removeExtension = (filename: string) => {
- return filename.substring(0, filename.length - path.getExtension(filename).length);
- };
- return `${removeExtension(filename)}${extension}`;
- }
-
- const splats = getSplats();
- const splat = splats[0];
- const filename = outputFilename ?? replaceExtension(splat.filename, extensions[type]);
-
- if (window.showSaveFilePicker) {
- try {
- const fileHandle = await window.showSaveFilePicker({
- id: 'SuperSplatFileExport',
- types: filePickerTypes[type] as FilePickerAcceptType[],
- suggestedName: filename
- });
- await events.invoke('scene.write', {
- type: type,
- stream: await fileHandle.createWritable()
- });
- } catch (error) {
- if (error.name !== 'AbortError') {
- console.error(error);
- }
- }
- } else {
- const result = await events.invoke('showPopup', {
- type: 'okcancel',
- header: exportType === 'saveAs' ? 'SAVE AS' : 'EXPORT',
- message: 'Please enter a filename',
- value: filename
- });
-
- if (result.action === 'ok') {
- await events.invoke('scene.write', {
- type: type,
- filename: result.value
- });
- }
- }
- });
-
- events.function('scene.write', async (options: SceneWriteOptions) => {
- startSpinner();
-
- try {
- const splats = getSplats();
-
- // setTimeout so spinner has a chance to activate
- await new Promise((resolve) => {
- setTimeout(resolve);
- });
-
- const data = (() => {
- switch (options.type) {
- case 'ply':
- return convertPly(splats);
- case 'compressed-ply':
- return convertPlyCompressed(splats);
- case 'splat':
- return convertSplat(splats);
- default:
- return null;
- }
- })();
-
- if (options.stream) {
- // write to stream
- await writeToFile(options.stream, data);
- } else if (remoteStorageDetails) {
- // write data to remote storage
- await sendToRemoteStorage(options.filename, data, remoteStorageDetails);
- } else if (options.filename) {
- // download file to local machine
- download(options.filename, data);
- }
- } catch (err) {
- events.invoke('showPopup', {
- type: 'error',
- header: localize('popup.error-loading'),
- message: `${err.message ?? err} while saving file`
- });
- } finally {
- stopSpinner();
- }
- });
-};
-
-export { initFileHandler };
diff --git a/mirror-2/splat/src/index.html b/mirror-2/splat/src/index.html
deleted file mode 100644
index 2b62aff5..00000000
--- a/mirror-2/splat/src/index.html
+++ /dev/null
@@ -1,39 +0,0 @@
-
-
-
- SuperSplat
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/mirror-2/splat/src/index.ts b/mirror-2/splat/src/index.ts
deleted file mode 100644
index 23a4541f..00000000
--- a/mirror-2/splat/src/index.ts
+++ /dev/null
@@ -1,19 +0,0 @@
-import './ui/style.scss'
-import { main } from './main'
-import { version as appVersion } from '../package.json'
-import {
- version as pcuiVersion,
- revision as pcuiRevision
-} from '@playcanvas/pcui'
-import {
- version as engineVersion,
- revision as engineRevision
-} from 'playcanvas'
-
-// print out versions of dependent packages
-// NOTE: add dummy style reference to prevent tree shaking
-console.log(
- `SuperSplat v${appVersion} | PCUI v${pcuiVersion} (${pcuiRevision}) | Engine v${engineVersion} (${engineRevision})`
-)
-
-export default main
diff --git a/mirror-2/splat/src/infinite-grid.ts b/mirror-2/splat/src/infinite-grid.ts
deleted file mode 100644
index c3bdeb69..00000000
--- a/mirror-2/splat/src/infinite-grid.ts
+++ /dev/null
@@ -1,247 +0,0 @@
-import {
- CULLFACE_NONE,
- SEMANTIC_POSITION,
- BlendState,
- DepthState,
- Mat4,
- QuadRender,
- Shader,
- createShaderFromCode,
- FUNC_LESSEQUAL,
- BLENDMODE_ONE,
- BLENDMODE_ONE_MINUS_SRC_ALPHA,
- BLENDMODE_SRC_ALPHA,
- BLENDEQUATION_ADD
-} from 'playcanvas';
-import { Element, ElementType } from './element';
-import { Serializer } from './serializer';
-
-const vsCode = /*glsl*/ `
- uniform mat4 camera_matrix;
- uniform vec2 camera_params;
-
- attribute vec2 vertex_position;
-
- varying vec3 worldFar;
-
- void main(void) {
- gl_Position = vec4(vertex_position, 0.0, 1.0);
-
- vec4 v = camera_matrix * vec4(vertex_position * camera_params, -1.0, 1.0);
-
- worldFar = v.xyz;
- }
-`;
-
-const fsCode = /*glsl*/ `
- uniform vec3 camera_position;
- uniform mat4 camera_viewProjection;
- uniform sampler2D blueNoiseTex32;
-
- varying vec3 worldFar;
-
- bool intersectPlane(inout float t, vec3 pos, vec3 dir, vec4 plane) {
- float d = dot(dir, plane.xyz);
- if (abs(d) < 1e-06) {
- return false;
- }
-
- float n = -(dot(pos, plane.xyz) + plane.w) / d;
- if (n < 0.0) {
- return false;
- }
-
- t = n;
-
- return true;
- }
-
- // https://bgolus.medium.com/the-best-darn-grid-shader-yet-727f9278b9d8#1e7c
- float pristineGrid(in vec2 uv, in vec2 ddx, in vec2 ddy, vec2 lineWidth) {
- vec2 uvDeriv = vec2(length(vec2(ddx.x, ddy.x)), length(vec2(ddx.y, ddy.y)));
- bvec2 invertLine = bvec2(lineWidth.x > 0.5, lineWidth.y > 0.5);
- vec2 targetWidth = vec2(
- invertLine.x ? 1.0 - lineWidth.x : lineWidth.x,
- invertLine.y ? 1.0 - lineWidth.y : lineWidth.y
- );
- vec2 drawWidth = clamp(targetWidth, uvDeriv, vec2(0.5));
- vec2 lineAA = uvDeriv * 1.5;
- vec2 gridUV = abs(fract(uv) * 2.0 - 1.0);
- gridUV.x = invertLine.x ? gridUV.x : 1.0 - gridUV.x;
- gridUV.y = invertLine.y ? gridUV.y : 1.0 - gridUV.y;
- vec2 grid2 = smoothstep(drawWidth + lineAA, drawWidth - lineAA, gridUV);
-
- grid2 *= clamp(targetWidth / drawWidth, 0.0, 1.0);
- grid2 = mix(grid2, targetWidth, clamp(uvDeriv * 2.0 - 1.0, 0.0, 1.0));
- grid2.x = invertLine.x ? 1.0 - grid2.x : grid2.x;
- grid2.y = invertLine.y ? 1.0 - grid2.y : grid2.y;
-
- return mix(grid2.x, 1.0, grid2.y);
- }
-
- float calcDepth(vec3 p) {
- vec4 v = camera_viewProjection * vec4(p, 1.0);
- return (v.z / v.w) * 0.5 + 0.5;
- }
-
- bool writeDepth(float alpha) {
- vec2 uv = fract(gl_FragCoord.xy / 32.0);
- float noise = texture2DLodEXT(blueNoiseTex32, uv, 0.0).y;
- return alpha > noise;
- }
-
- void main(void) {
- vec3 p = camera_position;
- vec3 v = normalize(worldFar - camera_position);
-
- // intersect ray with the world xz plane
- float t;
- if (!intersectPlane(t, p, v, vec4(0, 1, 0, 0))) {
- discard;
- }
-
- // calculate grid intersection
- vec3 pos = p + v * t;
- vec2 ddx = dFdx(pos.xz);
- vec2 ddy = dFdy(pos.xz);
-
- float epsilon = 1.0 / 255.0;
-
- // calculate fade
- float fade = 1.0 - smoothstep(400.0, 1000.0, length(pos - camera_position));
- if (fade < epsilon) {
- discard;
- }
-
- vec3 levelPos;
- float levelSize;
- float levelAlpha;
-
- // 10m grid with colored main axes
- levelPos = pos * 0.1;
- levelSize = 2.0 / 1000.0;
- levelAlpha = pristineGrid(levelPos.xz, ddx * 0.1, ddy * 0.1, vec2(levelSize)) * fade;
- if (levelAlpha > epsilon) {
- vec3 color;
- vec2 loc = max(vec2(0.0), abs(levelPos.xz) - abs(ddx * 0.1) - abs(ddy * 0.1));
- if (loc.x < levelSize) {
- if (loc.y < levelSize) {
- color = vec3(1.0);
- } else {
- color = vec3(0.2, 0.2, 1.0);
- }
- } else if (loc.y < levelSize) {
- color = vec3(1.0, 0.2, 0.2);
- } else {
- color = vec3(0.9);
- }
- gl_FragColor = vec4(color, levelAlpha);
- gl_FragDepth = writeDepth(levelAlpha) ? calcDepth(pos) : 1.0;
- return;
- }
-
- // 1m grid
- levelPos = pos;
- levelSize = 1.0 / 100.0;
- levelAlpha = pristineGrid(levelPos.xz, ddx, ddy, vec2(levelSize)) * fade;
- if (levelAlpha > epsilon) {
- gl_FragColor = vec4(vec3(0.7), levelAlpha);
- gl_FragDepth = writeDepth(levelAlpha) ? calcDepth(pos) : 1.0;
- return;
- }
-
- // 0.1m grid
- levelPos = pos * 10.0;
- levelSize = 1.0 / 100.0;
- levelAlpha = pristineGrid(levelPos.xz, ddx * 10.0, ddy * 10.0, vec2(levelSize)) * fade;
- if (levelAlpha > epsilon) {
- gl_FragColor = vec4(vec3(0.7), levelAlpha);
- gl_FragDepth = writeDepth(levelAlpha) ? calcDepth(pos) : 1.0;
- return;
- }
-
- discard;
- }
-`;
-
-const calcHalfSize = (fov: number, aspect: number, fovIsHorizontal: boolean) => {
- let x, y;
- if (fovIsHorizontal) {
- x = Math.tan(fov * Math.PI / 360);
- y = x / aspect;
- } else {
- y = Math.tan(fov * Math.PI / 360);
- x = y * aspect;
- }
- return [ x, y ];
-};
-
-const attributes = {
- vertex_position: SEMANTIC_POSITION
-};
-
-class InfiniteGrid extends Element {
- shader: Shader;
- quadRender: QuadRender;
- blendState = new BlendState(false);
- depthState = new DepthState(FUNC_LESSEQUAL, true);
-
- visible = true;
-
- constructor() {
- super(ElementType.debug);
- }
-
- add() {
- const device = this.scene.app.graphicsDevice;
-
- this.shader = createShaderFromCode(device, vsCode, fsCode, 'infinite-grid', attributes);
- this.quadRender = new QuadRender(this.shader);
-
- const cameraMatrixId = device.scope.resolve('camera_matrix');
- const cameraParamsId = device.scope.resolve('camera_params');
- const cameraPositionId = device.scope.resolve('camera_position');
- const cameraViewProjectionId = device.scope.resolve('camera_viewProjection');
-
- const blendState = new BlendState(
- true,
- BLENDEQUATION_ADD, BLENDMODE_SRC_ALPHA, BLENDMODE_ONE_MINUS_SRC_ALPHA,
- BLENDEQUATION_ADD, BLENDMODE_ONE, BLENDMODE_ONE_MINUS_SRC_ALPHA
- );
-
- this.scene.debugLayer.onPreRenderOpaque = () => {
- if (this.visible) {
- device.setBlendState(blendState);
- device.setCullMode(CULLFACE_NONE);
- device.setDepthState(DepthState.WRITEDEPTH);
- device.setStencilState(null, null);
-
- const cameraEntity = this.scene.camera.entity;
- const camera = cameraEntity.camera;
-
- // update viewProjectionInverse matrix
- const cameraMatrix = cameraEntity.getWorldTransform().clone();
- const cameraParams = calcHalfSize(camera.fov, camera.aspectRatio, camera.horizontalFov);
- const cameraPosition = cameraMatrix.getTranslation();
- const cameraViewProjection = new Mat4().mul2(camera.projectionMatrix, camera.viewMatrix);
-
- cameraMatrixId.setValue(cameraMatrix.data);
- cameraParamsId.setValue(cameraParams);
- cameraPositionId.setValue([cameraPosition.x, cameraPosition.y, cameraPosition.z]);
- cameraViewProjectionId.setValue(cameraViewProjection.data);
-
- this.quadRender.render();
- }
- };
- }
-
- remove() {
- this.scene.debugLayer.onPreRenderOpaque = null;
- }
-
- serialize(serializer: Serializer): void {
- serializer.pack(this.visible);
- }
-}
-
-export { InfiniteGrid };
diff --git a/mirror-2/splat/src/main.ts b/mirror-2/splat/src/main.ts
deleted file mode 100644
index cf7d013e..00000000
--- a/mirror-2/splat/src/main.ts
+++ /dev/null
@@ -1,184 +0,0 @@
-import { createGraphicsDevice } from 'playcanvas';
-import { Scene } from './scene';
-import { getSceneConfig } from './scene-config';
-import { initMaterials } from './material';
-import { EditHistory } from './edit-history';
-import { EditorUI } from './ui/editor';
-import { registerEditorEvents } from './editor';
-import { initFileHandler } from './file-handler';
-import { registerSelectionEvents } from './selection';
-import { registerTransformHandlerEvents } from './transform-handler';
-import { ToolManager } from './tools/tool-manager';
-import { RectSelection } from './tools/rect-selection';
-import { BrushSelection } from './tools/brush-selection';
-import { SphereSelection } from './tools/sphere-selection';
-import { MoveTool } from './tools/move-tool';
-import { RotateTool } from './tools/rotate-tool';
-import { ScaleTool } from './tools/scale-tool';
-import { Shortcuts } from './shortcuts';
-import { Events } from './events';
-
-declare global {
- interface LaunchParams {
- readonly files: FileSystemFileHandle[];
- }
-
- interface Window {
- launchQueue: {
- setConsumer: (callback: (launchParams: LaunchParams) => void) => void;
- };
- scene: Scene;
- }
-}
-
-const getURLArgs = () => {
- // extract settings from command line in non-prod builds only
- const config = {};
-
- const apply = (key: string, value: string) => {
- let obj: any = config;
- key.split('.').forEach((k, i, a) => {
- if (i === a.length - 1) {
- obj[k] = value;
- } else {
- if (!obj.hasOwnProperty(k)) {
- obj[k] = {};
- }
- obj = obj[k];
- }
- });
- };
-
- const params = new URLSearchParams(window.location.search.slice(1));
- params.forEach((value: string, key: string) => {
- apply(key, value);
- });
-
- return config;
-};
-
-const initShortcuts = (events: Events) => {
- const shortcuts = new Shortcuts(events);
-
- shortcuts.register(['Delete', 'Backspace'], { event: 'select.delete' });
- shortcuts.register(['Escape'], { event: 'tool.deactivate' });
- shortcuts.register(['Tab'], { event: 'selection.next' });
- shortcuts.register(['1'], { event: 'tool.move', sticky: true });
- shortcuts.register(['2'], { event: 'tool.rotate', sticky: true });
- shortcuts.register(['3'], { event: 'tool.scale', sticky: true });
- shortcuts.register(['G', 'g'], { event: 'grid.toggleVisible' });
- shortcuts.register(['C', 'c'], { event: 'tool.toggleCoordSpace' });
- shortcuts.register(['F', 'f'], { event: 'camera.focus' });
- shortcuts.register(['B', 'b'], { event: 'tool.brushSelection', sticky: true });
- shortcuts.register(['R', 'r'], { event: 'tool.rectSelection', sticky: true });
- shortcuts.register(['P', 'p'], { event: 'tool.rectSelection', sticky: true });
- shortcuts.register(['A', 'a'], { event: 'select.all' });
- shortcuts.register(['A', 'a'], { event: 'select.none', shift: true });
- shortcuts.register(['I', 'i'], { event: 'select.invert' });
- shortcuts.register(['H', 'h'], { event: 'select.hide' });
- shortcuts.register(['U', 'u'], { event: 'select.unhide' });
- shortcuts.register(['['], { event: 'tool.brushSelection.smaller' });
- shortcuts.register([']'], { event: 'tool.brushSelection.bigger' });
- shortcuts.register(['Z', 'z'], { event: 'edit.undo', ctrl: true });
- shortcuts.register(['Z', 'z'], { event: 'edit.redo', ctrl: true, shift: true });
- shortcuts.register(['M', 'm'], { event: 'camera.toggleMode' });
- shortcuts.register(['D', 'd'], { event: 'dataPanel.toggle' });
- shortcuts.register([' '], { event: 'camera.toggleOverlay' });
-
- return shortcuts;
-};
-
-const main = async () => {
- const url = new URL(window.location.href);
-
- // decode remote storage details
- let remoteStorageDetails;
- try {
- remoteStorageDetails = JSON.parse(decodeURIComponent(url.searchParams.get('remoteStorage')));
- } catch (e) {
-
- }
-
- // root events object
- const events = new Events();
-
- // edit history
- const editHistory = new EditHistory(events);
-
- // editor ui
- const editorUI = new EditorUI(events, !!remoteStorageDetails);
-
- // create the graphics device
- const graphicsDevice = await createGraphicsDevice(editorUI.canvas, {
- deviceTypes: ['webgl2'],
- antialias: false,
- depth: false,
- stencil: false,
- xrCompatible: false,
- powerPreference: 'high-performance'
- });
-
- // monkey-patch materials for premul alpha rendering
- initMaterials();
-
- const overrides = [
- getURLArgs()
- ];
-
- // resolve scene config
- const sceneConfig = getSceneConfig(overrides);
-
- // construct the manager
- const scene = new Scene(
- events,
- sceneConfig,
- editorUI.canvas,
- graphicsDevice
- );
-
- // configure body background color
- const clr = sceneConfig.bgClr;
- const cnv = (v: number) => `${Math.max(0, Math.min(255, (v * 255))).toFixed(0)}`
- document.body.style.backgroundColor = `rgba(${cnv(clr.r)},${cnv(clr.g)},${cnv(clr.b)},${clr.a.toFixed(2)})`;
-
- // tool manager
- const toolManager = new ToolManager(events);
- toolManager.register('rectSelection', new RectSelection(events, editorUI.toolsContainer.dom));
- toolManager.register('brushSelection', new BrushSelection(events, editorUI.toolsContainer.dom));
- toolManager.register('sphereSelection', new SphereSelection(events, scene, editorUI.canvasContainer));
- toolManager.register('move', new MoveTool(events, scene));
- toolManager.register('rotate', new RotateTool(events, scene));
- toolManager.register('scale', new ScaleTool(events, scene));
-
- window.scene = scene;
-
- registerEditorEvents(events, editHistory, scene);
- registerSelectionEvents(events, scene);
- registerTransformHandlerEvents(events);
- initShortcuts(events);
- await initFileHandler(scene, events, editorUI.appContainer.dom, remoteStorageDetails);
-
- // load async models
- await scene.load();
-
- // handle load params
- const loadList = url.searchParams.getAll('load');
- for (const value of loadList) {
- const loadUrl = decodeURIComponent(value);
- await events.invoke('load', loadUrl, loadUrl);
- }
-
- // handle OS-based file association in PWA mode
- if ("launchQueue" in window) {
- window.launchQueue.setConsumer(async (launchParams: LaunchParams) => {
- for (const file of launchParams.files) {
- const blob = await file.getFile();
- const url = URL.createObjectURL(blob);
- await events.invoke('load', url, file.name);
- URL.revokeObjectURL(url);
- }
- });
- }
-};
-
-export { main };
diff --git a/mirror-2/splat/src/manifest.json b/mirror-2/splat/src/manifest.json
deleted file mode 100644
index 7d1a88b0..00000000
--- a/mirror-2/splat/src/manifest.json
+++ /dev/null
@@ -1,43 +0,0 @@
-{
- "name": "SuperSplat",
- "short_name": "SuperSplat",
- "description": "SuperSplat is an advanced browser-based editor for manipulating and optimizing 3D Gaussian Splats. It is open source and engine agnostic.",
- "display": "fullscreen",
- "start_url": "./",
- "scope": "./",
- "background_color": "#ffffff",
- "icons": [
- {
- "src": "./static/icons/logo-192.png",
- "sizes": "192x192",
- "type": "image/png"
- },
- {
- "src": "./static/icons/logo-512.png",
- "sizes": "512x512",
- "type": "image/png"
- }
- ],
- "screenshots": [
- {
- "src": "./static/images/screenshot-narrow.jpg",
- "type": "image/jpeg",
- "sizes": "2160x3840",
- "form_factor": "narrow"
- },
- {
- "src": "./static/images/screenshot-wide.jpg",
- "type": "image/jpeg",
- "sizes": "3840x2160",
- "form_factor": "wide"
- }
- ],
- "file_handlers": [
- {
- "action": "./",
- "accept": {
- "application/ply": [".ply"]
- }
- }
- ]
-}
\ No newline at end of file
diff --git a/mirror-2/splat/src/material.ts b/mirror-2/splat/src/material.ts
deleted file mode 100644
index a40f9e02..00000000
--- a/mirror-2/splat/src/material.ts
+++ /dev/null
@@ -1,39 +0,0 @@
-import {Material, BLEND_NONE, BLENDEQUATION_ADD, BLENDMODE_ONE, BLENDMODE_ONE_MINUS_SRC_ALPHA} from 'playcanvas';
-
-let setBlendTypeOrig: any;
-
-function setBlendType(type: number) {
- // set engine function
- setBlendTypeOrig.call(this, type);
-
- // tweak alpha blending
- switch (type) {
- case BLEND_NONE:
- break;
- default:
- this._blendState.setAlphaBlend(BLENDEQUATION_ADD, BLENDMODE_ONE, BLENDMODE_ONE_MINUS_SRC_ALPHA);
- break;
- }
-}
-
-// here we patch the material set blendType function to blend
-// alpha correctly
-
-const initMaterials = () => {
- const blendTypeDescriptor = Object.getOwnPropertyDescriptor(Material.prototype, 'blendType');
-
- // store the original setter
- setBlendTypeOrig = blendTypeDescriptor.set;
-
- // update the setter function
- Object.defineProperty(Material.prototype, 'blendType', {
- set(type) {
- setBlendType.call(this, type);
- },
- get() {
- return blendTypeDescriptor.get.call(this);
- }
- });
-};
-
-export {initMaterials};
diff --git a/mirror-2/splat/src/model.ts b/mirror-2/splat/src/model.ts
deleted file mode 100644
index 84c3511d..00000000
--- a/mirror-2/splat/src/model.ts
+++ /dev/null
@@ -1,161 +0,0 @@
-import {
- Asset,
- BoundingBox,
- Entity,
- MeshInstance,
- RenderComponent,
- Vec3
-} from 'playcanvas';
-import { Element, ElementType } from './element';
-import { Serializer } from './serializer';
-
-const vec = new Vec3();
-
-// calculate mesh sort distance by node origin (instead of the default bounding box origin)
-const calculateSortDistance = (drawCall: any, cameraPosition: Vec3, cameraForward: Vec3) => {
- return vec.sub2(drawCall.node.getPosition(), cameraPosition).dot(cameraForward);
-};
-
-class Model extends Element {
- asset: Asset;
- entity: Entity;
- root: any;
- animTracks: string[] = [];
- changedCounter = 0;
- worldBoundStorage = new BoundingBox();
-
- constructor(asset: Asset) {
- super(ElementType.model);
-
- this.asset = asset;
- this.entity = new Entity('modelRoot');
- }
-
- play(track?: number) {
- const anim = this.root.anim;
- if (anim) {
- if (track) {
- anim.baseLayer.transition(`track_${track}`);
- }
- anim.playing = true;
- anim.baseLayer.play();
- }
- }
-
- pause() {
- const anim = this.root.anim;
- if (anim) {
- anim.playing = false;
- anim.baseLayer.pause();
- }
- }
-
- destroy() {
- super.destroy();
- this.entity.destroy();
- this.asset.registry.remove(this.asset);
- this.asset.unload();
- }
-
- add() {
- const config = this.scene.config;
-
- this.root = this.asset.resource.instantiateRenderEntity({
- app: this.scene.app,
- camera: this.scene.camera.entity,
- onChanged: () => { this.changedCounter++; }
- });
- this.entity.addChild(this.root);
-
- // initialize animations
- if (this.asset.resource.animations?.length > 0) {
- const anim = this.root.addComponent('anim', {
- activate: false,
- speed: 1.0
- });
-
- anim.rootBone = this.root;
- this.asset.resource.animations.forEach((animTrack: any, i: number) => {
- anim.assignAnimation(`track_${i}`, animTrack.resource);
- this.animTracks.push(animTrack.resource.name);
- });
-
- // automatically play the first animation
- this.play(0);
- }
-
- // add the entity to the scene
- this.scene.contentRoot.addChild(this.entity);
-
- // manually add shadow casters to shadow layer
- this.entity.findComponents('render').forEach((component: RenderComponent) => {
- if (component.entity.enabled) {
- this.scene.shadowLayer.shadowCasters = this.scene.shadowLayer.shadowCasters.concat(
- component.meshInstances
- );
- }
-
- // override default sort distance calculation
- component.meshInstances.forEach((meshInstance: MeshInstance) => {
- meshInstance.calculateSortDistance = calculateSortDistance;
- });
- });
-
- vec.copy(Vec3.ZERO);
-
- // apply model settings
- const p = config.model.position;
- const r = config.model.rotation;
- const s = config.model.scale;
-
- if (p) {
- vec.x += p.x;
- vec.y += p.y;
- vec.z += p.z;
- }
- this.entity.setLocalPosition(vec.x, vec.y, vec.z);
- if (r) this.entity.setLocalEulerAngles(r.x, r.y, r.z);
- if (s) this.entity.setLocalScale(s, s, s);
-
- this.scene.boundDirty = true;
- }
-
- remove() {
- this.entity.findComponents('render').forEach((component: RenderComponent) => {
- this.scene.shadowLayer.shadowCasters = this.scene.shadowLayer.shadowCasters.filter(
- (meshInstance: MeshInstance) => {
- return component.meshInstances.indexOf(meshInstance) === -1;
- }
- );
- });
- this.scene.contentRoot.removeChild(this.entity);
- }
-
- serialize(serializer: Serializer) {
- serializer.packa(this.entity.getWorldTransform().data);
- serializer.pack(this.root?.anim?.baseLayer?.activeStateCurrentTime);
- serializer.pack(this.changedCounter);
- }
-
- get worldBound() {
- const bound = this.worldBoundStorage;
-
- let valid = false;
- this.entity.findComponents('render').forEach((r: RenderComponent) => {
- if (r.entity.enabled) {
- r.meshInstances.forEach((meshInstance: MeshInstance) => {
- if (!valid) {
- valid = true;
- bound.copy(meshInstance.aabb);
- } else {
- bound.add(meshInstance.aabb);
- }
- });
- }
- });
-
- return valid ? bound : null;
- }
-}
-
-export { Model };
diff --git a/mirror-2/splat/src/pc-app.ts b/mirror-2/splat/src/pc-app.ts
deleted file mode 100644
index 19f6f0c3..00000000
--- a/mirror-2/splat/src/pc-app.ts
+++ /dev/null
@@ -1,198 +0,0 @@
-import {
- // platform,
- WebglGraphicsDevice,
- // SoundManager,
- // Lightmapper,
- // BatchManager,
- AppBase,
- AppOptions,
- // script,
- // AnimationComponentSystem,
- AnimComponentSystem,
- // AudioListenerComponentSystem,
- // AudioSourceComponentSystem,
- // ButtonComponentSystem,
- // CollisionComponentSystem,
- // ElementComponentSystem,
- // JointComponentSystem,
- // LayoutChildComponentSystem,
- // LayoutGroupComponentSystem,
- ModelComponentSystem,
- // ParticleSystemComponentSystem,
- RenderComponentSystem,
- // RigidBodyComponentSystem,
- // ScreenComponentSystem,
- // ScriptLegacyComponentSystem,
- // ScrollViewComponentSystem,
- // ScrollbarComponentSystem,
- // SoundComponentSystem,
- // SpriteComponentSystem,
- // ZoneComponentSystem,
- CameraComponentSystem,
- LightComponentSystem,
- GSplatComponentSystem,
- // ScriptComponentSystem,
- RenderHandler,
- // AnimationHandler,
- AnimClipHandler,
- AnimStateGraphHandler,
- // AudioHandler,
- // BinaryHandler,
- ContainerHandler,
- // CssHandler,
- CubemapHandler,
- // FolderHandler,
- // FontHandler,
- GSplatHandler,
- // HierarchyHandler,
- // HtmlHandler,
- // JsonHandler,
- // MaterialHandler,
- // ModelHandler,
- // SceneHandler,
- // ScriptHandler,
- // ShaderHandler,
- // SpriteHandler,
- // TemplateHandler,
- // TextHandler,
- // TextureAtlasHandler,
- TextureHandler,
- CollisionComponentSystem,
- AnimationComponentSystem,
- AudioListenerComponentSystem,
- AudioSourceComponentSystem,
- ButtonComponentSystem,
- ElementComponentSystem,
- JointComponentSystem,
- LayoutChildComponentSystem,
- LayoutGroupComponentSystem,
- ParticleSystemComponentSystem,
- RigidBodyComponentSystem,
- ScreenComponentSystem,
- ScrollbarComponentSystem,
- ScrollViewComponentSystem,
- SoundComponentSystem,
- SpriteComponentSystem,
- ZoneComponentSystem,
- ShaderHandler,
- AnimationHandler,
- AudioHandler,
- BinaryHandler,
- CssHandler,
- FolderHandler,
- FontHandler,
- HierarchyHandler,
- HtmlHandler,
- JsonHandler,
- MaterialHandler,
- ModelHandler,
- SceneHandler,
- ScriptHandler,
- SpriteHandler,
- TemplateHandler,
- TextHandler,
- TextureAtlasHandler
- // XrManager
-} from 'playcanvas'
-
-class PCApp extends AppBase {
- constructor(canvas: HTMLCanvasElement, options: any) {
- super(canvas)
-
- const appOptions = new AppOptions()
-
- appOptions.graphicsDevice = options.graphicsDevice
- this.addComponentSystems(appOptions)
- this.addResourceHandles(appOptions)
-
- appOptions.elementInput = options.elementInput
- appOptions.keyboard = options.keyboard
- appOptions.mouse = options.mouse
- appOptions.touch = options.touch
- appOptions.gamepads = options.gamepads
-
- appOptions.scriptPrefix = options.scriptPrefix
- appOptions.assetPrefix = options.assetPrefix
- appOptions.scriptsOrder = options.scriptsOrder
-
- // appOptions.soundManager = new SoundManager(options);
- // @ts-ignore
- // appOptions.lightmapper = Lightmapper;
- // appOptions.batchManager = BatchManager;
- // @ts-ignore
- // appOptions.xr = XrManager;
-
- this.init(appOptions)
- }
-
- addComponentSystems(appOptions: AppOptions) {
- appOptions.componentSystems = [
- RigidBodyComponentSystem,
- CollisionComponentSystem,
- JointComponentSystem,
- AnimationComponentSystem,
- // @ts-ignore
- AnimComponentSystem,
- ModelComponentSystem,
- // @ts-ignore
- RenderComponentSystem,
- // @ts-ignore
- CameraComponentSystem,
- // @ts-ignore
- LightComponentSystem,
- // script.legacy ? ScriptLegacyComponentSystem : ScriptComponentSystem,
- AudioSourceComponentSystem,
- SoundComponentSystem,
- AudioListenerComponentSystem,
- ParticleSystemComponentSystem,
- ScreenComponentSystem,
- ElementComponentSystem,
- ButtonComponentSystem,
- ScrollViewComponentSystem,
- ScrollbarComponentSystem,
- SpriteComponentSystem,
- LayoutGroupComponentSystem,
- LayoutChildComponentSystem,
- ZoneComponentSystem,
- GSplatComponentSystem
- ]
- }
-
- addResourceHandles(appOptions: AppOptions) {
- appOptions.resourceHandlers = [
- // @ts-ignore
- RenderHandler,
- AnimationHandler,
- // @ts-ignore
- AnimClipHandler,
- // @ts-ignore
- AnimStateGraphHandler,
- ModelHandler,
- MaterialHandler,
- // @ts-ignore
- TextureHandler,
- TextHandler,
- JsonHandler,
- AudioHandler,
- ScriptHandler,
- SceneHandler,
- // @ts-ignore
- CubemapHandler,
- HtmlHandler,
- CssHandler,
- ShaderHandler,
- HierarchyHandler,
- FolderHandler,
- FontHandler,
- BinaryHandler,
- TextureAtlasHandler,
- SpriteHandler,
- TemplateHandler,
- // @ts-ignore
- ContainerHandler,
- GSplatHandler
- ]
- }
-}
-
-export { PCApp }
diff --git a/mirror-2/splat/src/pivot.ts b/mirror-2/splat/src/pivot.ts
deleted file mode 100644
index c4e911b7..00000000
--- a/mirror-2/splat/src/pivot.ts
+++ /dev/null
@@ -1,66 +0,0 @@
-import { Vec3, Quat } from 'playcanvas';
-import { Events } from './events';
-import { Transform } from './transform';
-
-// stores the transform pivot location in world space
-// the transform tools (translate, rotate, scale) and transform panel modify this pivot
-// then the active transform handler applies the changes to the current selection.
-class Pivot {
- transform = new Transform();
-
- place: (transform: Transform) => void;
- start: () => void;
- move: (transform: Transform) => void;
- moveTRS: (position: Vec3, rotation: Quat, scale: Vec3) => void;
- end: () => void;
-
- constructor(events: Events) {
-
- this.place = (transform: Transform) => {
- if (!this.transform.equals(transform)) {
- this.transform.copy(transform);
-
- events.fire('pivot.placed', this);
- }
- };
-
- this.start = () => {
- events.fire('pivot.started', this);
- };
-
- this.move = (transform: Transform) => {
- if (!this.transform.equals(transform)) {
- this.transform.copy(transform);
-
- events.fire('pivot.moved', this);
- }
- };
-
- this.moveTRS = (position: Vec3, rotation: Quat, scale: Vec3) => {
- if (!this.transform.equalsTRS(position, rotation, scale)) {
- this.transform.set(position, rotation, scale);
-
- events.fire('pivot.moved', this);
- }
- };
-
- this.end = () => {
- events.fire('pivot.ended', this);
- };
-
- events.on('pivot.place', this.place);
- events.on('pivot.start', this.start);
- events.on('pivot.moveTRS', this.moveTRS);
- events.on('pivot.end', this.end);
- }
-}
-
-const registerPivotEvents = (events: Events) => {
- const pivot = new Pivot(events);
-
- events.function('pivot', () => {
- return pivot;
- });
-};
-
-export { registerPivotEvents, Pivot };
diff --git a/mirror-2/splat/src/scene-config.ts b/mirror-2/splat/src/scene-config.ts
deleted file mode 100644
index d675bd4d..00000000
--- a/mirror-2/splat/src/scene-config.ts
+++ /dev/null
@@ -1,179 +0,0 @@
-
-type Color = { r: number, g: number, b: number, a: number };
-
-const DEFAULT: Color = { r: 0.4, g: 0.4, b: 0.4, a: 1 };
-
-// default config
-const sceneConfig = {
- model: {
- url: '',
- filename: '',
- position: { x: 0, y: 0, z: 0 },
- rotation: { x: 0, y: 0, z: 0 },
- scale: 1.0,
- hideLeftShoe: true
- },
- env: {
- url: '',
- intensity: 1.0,
- rotation: 0.0
- },
- bgClr: DEFAULT,
- camera: {
- pixelScale: 1,
- multisample: false,
- fov: 50,
- exposure: 1.0,
- toneMapping: 'linear',
- debug_render: '',
- overlay: true
- },
- show: {
- grid: true,
- bound: true,
- shBands: 3
- },
- shadow: {
- intensity: 0.25,
- fade: true
- },
- controls: {
- dampingFactor: 0.2,
- minPolarAngle: 0,
- maxPolarAngle: Math.PI,
- minZoom: 1e-6,
- maxZoom: 10.0,
- initialAzim: -45,
- initialElev: -10,
- initialZoom: 1.0,
- orbitSensitivity: 0.3,
- zoomSensitivity: 0.4
- },
- debug: {
- showBound: false
- }
-};
-
-type SceneConfig = typeof sceneConfig;
-
-class Params {
- sources: any[];
-
- constructor(sources: any[]) {
- this.sources = sources;
- }
-
- private resolve(configs: any[], path: string[]): any {
- const get = (obj: any): any => {
- for (const name of path) {
- if (!obj.hasOwnProperty(name)) {
- return undefined;
- }
- obj = obj[name];
- }
- return obj;
- };
-
- for (const config of configs) {
- const value = get(config);
- if (value !== undefined) {
- return value;
- }
- }
- return undefined;
- }
-
- get(path: string): any {
- return this.resolve(this.sources, path.split('.'));
- }
-
- getBool(path: string): boolean | undefined {
- const value = this.get(path);
- return typeof value === 'string' ? value.toLowerCase() === 'true' : value === undefined ? undefined : !!value;
- }
-
- getNumber(path: string) {
- const value = this.get(path);
- return typeof value === 'string' ? parseFloat(value) : value;
- }
-
- getVec(path: string) {
- const value = this.get(path);
- return typeof value === 'string' ? value.split(',') : undefined;
- }
-
- getVec3(path: string) {
- const value = this.getVec(path);
- if (value) {
- const numbers = value.map(v => parseFloat(v));
- if (value.length === 1) {
- return { x: numbers[0], y: numbers[0], z: numbers[0] };
- } else if (value.length === 3) {
- return { x: numbers[0], y: numbers[1], z: numbers[2] };
- }
- }
- return undefined;
- }
-
- getColor(path: string) {
- const value = this.getVec(path);
- if (value) {
- const numbers = value.map(v => parseFloat(v));
- if (value.length === 1) {
- return { r: numbers[0], g: numbers[0], b: numbers[0], a: 1 };
- } else if (value.length === 3) {
- return { r: numbers[0], g: numbers[1], b: numbers[2], a: 1 };
- } else if (value.length === 4) {
- return { r: numbers[0], g: numbers[1], b: numbers[2], a: numbers[3] };
- }
- }
- return undefined;
- }
-}
-
-const getSceneConfig = (overrides: any[]) => {
- const params = new Params(overrides);
-
- const cmp = (a: any[], b: any[]) => {
- return a.length === b.length && a.every((v, i) => v === b[i]);
- };
-
- // recurse the object and replace concrete leaf values with overrides
- const rec = (obj: any, path: string) => {
- for (const child in obj) {
- const childPath = `${path}${path.length ? '.' : ''}${child}`;
- const childValue = obj[child];
- switch (typeof childValue) {
- case 'number':
- obj[child] = params.getNumber(childPath) ?? childValue;
- break;
- case 'boolean':
- obj[child] = params.getBool(childPath) ?? childValue;
- break;
- case 'string':
- obj[child] = params.get(childPath) ?? childValue;
- break;
- case 'object': {
- const keys = Object.keys(childValue).sort();
- if (cmp(keys, ['a', 'b', 'g', 'r'])) {
- obj[child] = params.getColor(childPath) ?? childValue;
- } else if (cmp(keys, ['x', 'y', 'z'])) {
- obj[child] = params.getVec3(childPath) ?? childValue;
- } else {
- rec(childValue, childPath);
- }
- break;
- }
- default:
- rec(childValue, childPath);
- break;
- }
- }
- };
-
- rec(sceneConfig, '');
-
- return sceneConfig;
-};
-
-export {SceneConfig, getSceneConfig };
diff --git a/mirror-2/splat/src/scene-state.ts b/mirror-2/splat/src/scene-state.ts
deleted file mode 100644
index 886fd209..00000000
--- a/mirror-2/splat/src/scene-state.ts
+++ /dev/null
@@ -1,151 +0,0 @@
-import { Serializer } from './serializer';
-import { Element, ElementType, ElementTypeList } from './element';
-
-const common = new Set();
-
-// this class tracks the state of scene elements and determines what
-// type of objects have changed in a frame. this allows the rest of
-// the application to respond to changes like re-rendering
-// the scene or recalculating the scene bounding box.
-class SceneState {
- states: any = {};
- activeValues: any[];
-
- serializer = new Serializer((value: any) => {
- this.activeValues.push(value);
- });
-
- constructor() {
- for (let i = 0; i < ElementTypeList.length; ++i) {
- this.states[ElementTypeList[i]] = {
- elements: new Map(),
- valueStart: [],
- valueCount: [],
- values: []
- };
- }
- }
-
- reset() {
- ElementTypeList.forEach(type => {
- const state = this.states[type];
- state.elements.clear();
- state.valueStart.length = 0;
- state.valueCount.length = 0;
- state.values.length = 0;
- });
- }
-
- pack(element: Element) {
- const state = this.states[element.type];
- const start = state.values.length;
-
- // let element store its values
- this.activeValues = state.values;
- element.serialize(this.serializer);
-
- state.elements.set(element, state.elements.size);
- state.valueStart.push(start);
- state.valueCount.push(state.values.length - start);
- }
-
- compare(other: SceneState) {
- function intersection(result: Set, a: Map, b: Map) {
- result.clear();
- for (const e of a.keys()) {
- if (b.has(e)) {
- result.add(e);
- }
- }
- }
-
- function diff(a: Map, b: Set) {
- for (const e of a.keys()) {
- if (!b.has(e)) {
- return true;
- }
- }
- }
-
- function some(it: IterableIterator, predicate: (t: T) => boolean) {
- for (const e of it) {
- if (predicate(e)) {
- return true;
- }
- }
- return false;
- }
-
- const result = {
- added: new Array(),
- removed: new Array(),
- moved: new Array(),
- changed: new Array()
- };
-
- ElementTypeList.forEach(type => {
- const prevState = other.states[type];
- const currState = this.states[type];
-
- // generate map of element to index
- const prev = prevState.elements;
- const curr = currState.elements;
-
- // make a set containing the elements present in both the previous and current frame
- intersection(common, prev, curr);
-
- // determine if any elements were added
- if (diff(curr, common)) {
- result.added.push(type);
- }
-
- // determine if any elements were removed
- if (diff(prev, common)) {
- result.removed.push(type);
- }
-
- // determine if any element moved order
- if (
- some(common.values(), (e: Element) => {
- return prev.get(e) !== curr.get(e);
- })
- ) {
- result.moved.push(type);
- }
-
- // determine if any element's state changed
- if (
- some(common.values(), (e: Element) => {
- const prevIdx = prev.get(e);
- const currIdx = curr.get(e);
- const count = prevState.valueCount[prevIdx];
-
- if (count !== currState.valueCount[currIdx]) {
- // number of state values changed
- return true;
- }
-
- const prevStart = prevState.valueStart[prevIdx];
- const currStart = currState.valueStart[currIdx];
- const prevValues = prevState.values;
- const currValues = currState.values;
-
- for (let i = 0; i < count; ++i) {
- if (prevValues[prevStart + i] !== currValues[currStart + i]) {
- // state value changed
- return true;
- }
- }
-
- return false;
- })
- ) {
- result.changed.push(type);
- }
- });
-
- return result;
- }
-}
-
-export { SceneState };
diff --git a/mirror-2/splat/src/scene.ts b/mirror-2/splat/src/scene.ts
deleted file mode 100644
index 8de0d617..00000000
--- a/mirror-2/splat/src/scene.ts
+++ /dev/null
@@ -1,384 +0,0 @@
-import {
- LAYERID_DEPTH,
- SORTMODE_NONE,
- BoundingBox,
- Color,
- Entity,
- Layer,
- GraphicsDevice
-} from 'playcanvas';
-import { PCApp } from './pc-app';
-import { Events } from './events';
-import { Element, ElementType, ElementTypeList } from './element';
-import { SceneState } from './scene-state';
-import { SceneConfig } from './scene-config';
-import { AssetLoader } from './asset-loader';
-import { Model } from './model';
-import { Splat } from './splat';
-import { SplatOverlay } from './splat-overlay';
-import { Camera } from './camera';
-import { CustomShadow as Shadow } from './custom-shadow';
-import { InfiniteGrid as Grid } from './infinite-grid';
-import { localize } from './ui/localization';
-import { DataProcessor } from './data-processor';
-
-class Scene {
- events: Events;
- config: SceneConfig;
- canvas: HTMLCanvasElement;
- app: PCApp;
- backgroundLayer: Layer;
- shadowLayer: Layer;
- debugLayer: Layer;
- gizmoLayer: Layer;
- sceneState = [new SceneState(), new SceneState()];
- elements: Element[] = [];
- boundStorage = new BoundingBox();
- boundDirty = true;
- forceRender = false;
-
- canvasResize: {width: number; height: number} | null = null;
- targetSize = {
- width: 0,
- height: 0
- };
-
- dataProcessor: DataProcessor;
- assetLoader: AssetLoader;
- camera: Camera;
- splatOverlay: SplatOverlay;
- shadow: Shadow;
- grid: Grid;
-
- contentRoot: Entity;
- cameraRoot: Entity;
-
- constructor(
- events: Events,
- config: SceneConfig,
- canvas: HTMLCanvasElement,
- graphicsDevice: GraphicsDevice
- ) {
- this.events = events;
- this.config = config;
- this.canvas = canvas;
-
- // configure the playcanvas application. we render to an offscreen buffer so require
- // only the simplest of backbuffers.
- this.app = new PCApp(canvas, { graphicsDevice });
-
- // only render the scene when instructed
- this.app.autoRender = false;
- this.app._allowResize = false;
- this.app.scene.clusteredLightingEnabled = false;
-
- // hack: disable lightmapper first bake until we expose option for this
- // @ts-ignore
- this.app.off('prerender', this.app._firstBake, this.app);
-
- // @ts-ignore
- this.app.loader.getHandler('texture').imgParser.crossOrigin = 'anonymous';
-
- // this is required to get full res AR mode backbuffer
- this.app.graphicsDevice.maxPixelRatio = window.devicePixelRatio;
-
- // configure application canvas
- const observer = new ResizeObserver((entries: ResizeObserverEntry[]) => {
- if (entries.length > 0) {
- const entry = entries[0];
- if (entry) {
- if (entry.devicePixelContentBoxSize) {
- // on non-safari browsers, we are given the pixel-perfect canvas size
- this.canvasResize = {
- width: entry.devicePixelContentBoxSize[0].inlineSize,
- height: entry.devicePixelContentBoxSize[0].blockSize
- };
- } else if (entry.contentBoxSize.length > 0) {
- // on safari browsers we must calculate pixel size from CSS size ourselves
- // and hope the browser performs the same calculation.
- const pixelRatio = window.devicePixelRatio;
- this.canvasResize = {
- width: Math.ceil(entry.contentBoxSize[0].inlineSize * pixelRatio),
- height: Math.ceil(entry.contentBoxSize[0].blockSize * pixelRatio)
- };
- }
- }
- this.forceRender = true;
- }
- });
-
- observer.observe(window.document.getElementById('canvas-container'));
-
- // configure depth layers to handle dynamic refraction
- const depthLayer = this.app.scene.layers.getLayerById(LAYERID_DEPTH);
- this.app.scene.layers.remove(depthLayer);
- this.app.scene.layers.insertOpaque(depthLayer, 2);
-
- // register application callbacks
- this.app.on('update', (deltaTime: number) => this.onUpdate(deltaTime));
- this.app.on('prerender', () => this.onPreRender());
- this.app.on('postrender', () => this.onPostRender());
-
- // force render on device restored
- this.app.graphicsDevice.on('devicerestored', () => {
- this.forceRender = true;
- });
-
- // background layer
- this.backgroundLayer = new Layer({
- enabled: true,
- name: 'Background Layer',
- opaqueSortMode: SORTMODE_NONE,
- transparentSortMode: SORTMODE_NONE
- });
-
- // shadow layer
- // this layer contains shadow caster scene mesh instances, shadow-casting
- // virtual light, shadow catching plane geometry and the main camera.
- this.shadowLayer = new Layer({
- name: 'Shadow Layer'
- });
-
- this.debugLayer = new Layer({
- enabled: true,
- name: 'Debug Layer',
- opaqueSortMode: SORTMODE_NONE,
- transparentSortMode: SORTMODE_NONE
- });
-
- // gizmo layer
- this.gizmoLayer = new Layer({
- name: 'Gizmo',
- clearDepthBuffer: true,
- opaqueSortMode: SORTMODE_NONE,
- transparentSortMode: SORTMODE_NONE
- });
-
- const layers = this.app.scene.layers;
- const worldLayer = layers.getLayerByName('World');
- const idx = layers.getOpaqueIndex(worldLayer);
- layers.insert(this.backgroundLayer, idx);
- layers.insert(this.shadowLayer, idx + 1);
- layers.insert(this.debugLayer, idx + 1);
- layers.push(this.gizmoLayer);
-
- this.dataProcessor = new DataProcessor(this.app.graphicsDevice);
- this.assetLoader = new AssetLoader(graphicsDevice, this.app.assets, this.app.graphicsDevice.maxAnisotropy);
-
- // create root entities
- this.contentRoot = new Entity('contentRoot');
- this.app.root.addChild(this.contentRoot);
-
- this.cameraRoot = new Entity('cameraRoot');
- this.app.root.addChild(this.cameraRoot);
-
- // create elements
- this.camera = new Camera();
- this.add(this.camera);
-
- this.splatOverlay = new SplatOverlay();
- this.add(this.splatOverlay);
-
- // this.shadow = new Shadow();
- // this.add(this.shadow);
-
- this.grid = new Grid();
- this.add(this.grid);
- }
-
- async load() {
- const config = this.config;
-
- // load scene assets
- const promises: Promise[] = [];
-
- // load model
- if (config.model.url) {
- promises.push(this.assetLoader.loadModel({
- url: config.model.url,
- filename: config.model.filename
- }));
- }
-
- // load env
- if (config.env.url) {
- promises.push(this.assetLoader.loadEnv({url: config.env.url}));
- }
-
- const elements = await Promise.all(promises);
-
- // add them to the scene
- elements.forEach(e => this.add(e));
-
- this.camera.focus();
-
- // start the app
- this.app.start();
- }
-
- clear() {
- const models = this.getElementsByType(ElementType.model);
- models.forEach((model) => {
- this.remove(model);
- (model as Model).destroy();
- });
-
- const splats = this.getElementsByType(ElementType.splat);
- splats.forEach((splat) => {
- this.remove(splat);
- (splat as Splat).destroy();
- });
- }
-
- // add a scene element
- add(element: Element) {
- if (!element.scene) {
- // add the new element
- element.scene = this;
- element.add();
- this.elements.push(element);
-
- // notify all elements of scene addition
- this.forEachElement(e => e !== element && e.onAdded(element));
-
- // notify listeners
- this.events.fire('scene.elementAdded', element);
- }
- }
-
- // remove an element from the scene
- remove(element: Element) {
- if (element.scene === this) {
- // remove from list
- this.elements.splice(this.elements.indexOf(element), 1);
-
- // notify listeners
- this.events.fire('scene.elementRemoved', element);
-
- // notify all elements of scene removal
- this.forEachElement(e => e.onRemoved(element));
-
- element.remove();
- element.scene = null;
- }
- }
-
- // get the scene bound
- get bound() {
- if (this.boundDirty) {
- let valid = false;
- this.forEachElement(e => {
- const bound = e.worldBound;
- if (bound) {
- if (!valid) {
- valid = true;
- this.boundStorage.copy(bound);
- } else {
- this.boundStorage.add(bound);
- }
- }
- });
-
- this.boundDirty = false;
- this.events.fire('scene.boundChanged', this.boundStorage);
- }
-
- return this.boundStorage;
- }
-
- getElementsByType(elementType: ElementType) {
- return this.elements.filter(e => e.type === elementType);
- }
-
- get graphicsDevice() {
- return this.app.graphicsDevice;
- }
-
- private forEachElement(action: (e: Element) => void) {
- this.elements.forEach(action);
- }
-
- private onUpdate(deltaTime: number) {
- // allow elements to update
- this.forEachElement(e => e.onUpdate(deltaTime));
-
- // fire a 'serialize' event which listers will use to store their state. we'll use
- // this to decide if the view has changed and so requires rendering.
- const i = this.app.frame % 2;
- const state = this.sceneState[i];
- state.reset();
- this.forEachElement(e => state.pack(e));
-
- // diff with previous state
- const result = state.compare(this.sceneState[1 - i]);
-
- // generate the set of all element types that changed
- const all = new Set([...result.added, ...result.removed, ...result.moved, ...result.changed]);
-
- // compare with previously serialized
- if (!this.app.renderNextFrame) {
- this.app.renderNextFrame = this.forceRender || all.size > 0;
- }
- this.forceRender = false;
-
- // raise per-type update events
- ElementTypeList.forEach(type => {
- if (all.has(type)) {
- this.events.fire(`updated:${type}`);
- }
- });
-
- // allow elements to postupdate
- this.forEachElement(e => e.onPostUpdate());
- }
-
- private onPreRender() {
- if (this.canvasResize) {
- this.canvas.width = this.canvasResize.width;
- this.canvas.height = this.canvasResize.height;
- this.canvasResize = null;
- }
-
- // update render target size
- this.targetSize.width = Math.ceil(this.app.graphicsDevice.width / this.config.camera.pixelScale);
- this.targetSize.height = Math.ceil(this.app.graphicsDevice.height / this.config.camera.pixelScale);
-
- this.forEachElement(e => e.onPreRender());
-
- this.events.fire('prerender', this.camera.entity.getWorldTransform());
-
- // debug - display scene bound
- if (this.config.debug.showBound) {
- // draw element bounds
- this.forEachElement((e: Element) => {
- if (e.type === ElementType.splat) {
- const splat = e as Splat;
-
- const local = splat.localBound;
- this.app.drawWireAlignedBox(
- local.getMin(),
- local.getMax(),
- Color.RED,
- true,
- undefined,
- splat.entity.getWorldTransform());
-
- const world = splat.worldBound;
- this.app.drawWireAlignedBox(
- world.getMin(),
- world.getMax(),
- Color.GREEN);
- }
- });
-
- // draw scene bound
- this.app.drawWireAlignedBox(this.bound.getMin(), this.bound.getMax(), Color.BLUE);
- }
- }
-
- private onPostRender() {
- this.forEachElement(e => e.onPostRender());
- }
-}
-
-export {SceneConfig, Scene};
diff --git a/mirror-2/splat/src/selection.ts b/mirror-2/splat/src/selection.ts
deleted file mode 100644
index 64446081..00000000
--- a/mirror-2/splat/src/selection.ts
+++ /dev/null
@@ -1,55 +0,0 @@
-import { Element, ElementType } from './element';
-import { Splat } from './splat';
-import { Events } from './events';
-import { Scene } from './scene';
-
-const registerSelectionEvents = (events: Events, scene: Scene) => {
- let selection: Element = null;
-
- events.on('scene.elementAdded', (element: Element) => {
- if (element.type === ElementType.splat) {
- setTimeout(() => {
- events.fire('selection', element);
- });
- }
- });
-
- events.on('scene.elementRemoved', (element: Element) => {
- if (element === selection) {
- const splats = scene.getElementsByType(ElementType.splat);
- events.fire('selection', splats.length === 1 ? null : splats.find(v => v !== element));
- }
- });
-
- events.on('selection', (element: Element) => {
- if (element !== selection && (!element || (element as Splat).visible)) {
- selection = element;
- events.fire('selection.changed', selection);
- scene.forceRender = true;
- }
- });
-
- events.function('selection', () => {
- return selection;
- });
-
- events.on('selection.next', () => {
- const splats = scene.getElementsByType(ElementType.splat);
- if (splats.length > 1) {
- const idx = splats.indexOf(selection);
- events.fire('selection', splats[(idx + 1) % splats.length]);
- }
- });
-
- events.on('splat.visibility', (splat: Splat) => {
- if (splat === selection && !splat.visible) {
- events.fire('selection', null);
- }
- });
-
- events.on('camera.focalPointPicked', (details: { splat: Splat }) => {
- events.fire('selection', details.splat);
- });
-};
-
-export { registerSelectionEvents };
diff --git a/mirror-2/splat/src/serializer.ts b/mirror-2/splat/src/serializer.ts
deleted file mode 100644
index f1089761..00000000
--- a/mirror-2/splat/src/serializer.ts
+++ /dev/null
@@ -1,34 +0,0 @@
-import {Color, Vec3} from 'playcanvas';
-
-// this class is used by elements to store their pertinent state
-// every frame. the data is then compared with the previous frame's
-// values in order to determine if any changes happened.
-class Serializer {
- constructor(packValue: (value: any) => void) {
- this.packValue = packValue;
- }
-
- packValue: (value: any) => void;
-
- pack(...args: any[]) {
- for (let j = 0; j < args.length; ++j) {
- this.packValue(args[j]);
- }
- }
-
- packa(a: any[] | Float32Array) {
- for (let j = 0; j < a.length; ++j) {
- this.packValue(a[j]);
- }
- }
-
- packVec3(v: Vec3) {
- this.pack(v.x, v.y, v.z);
- }
-
- packColor(c: Color) {
- this.pack(c.r, c.g, c.b, c.a);
- }
-}
-
-export {Serializer};
diff --git a/mirror-2/splat/src/sh-utils.ts b/mirror-2/splat/src/sh-utils.ts
deleted file mode 100644
index 2c96efd6..00000000
--- a/mirror-2/splat/src/sh-utils.ts
+++ /dev/null
@@ -1,190 +0,0 @@
-import { Mat3 } from 'playcanvas';
-
-const kSqrt03_02 = Math.sqrt( 3.0 / 2.0);
-const kSqrt01_03 = Math.sqrt( 1.0 / 3.0);
-const kSqrt02_03 = Math.sqrt( 2.0 / 3.0);
-const kSqrt04_03 = Math.sqrt( 4.0 / 3.0);
-const kSqrt01_04 = Math.sqrt( 1.0 / 4.0);
-const kSqrt03_04 = Math.sqrt( 3.0 / 4.0);
-const kSqrt01_05 = Math.sqrt( 1.0 / 5.0);
-const kSqrt03_05 = Math.sqrt( 3.0 / 5.0);
-const kSqrt06_05 = Math.sqrt( 6.0 / 5.0);
-const kSqrt08_05 = Math.sqrt( 8.0 / 5.0);
-const kSqrt09_05 = Math.sqrt( 9.0 / 5.0);
-const kSqrt01_06 = Math.sqrt( 1.0 / 6.0);
-const kSqrt05_06 = Math.sqrt( 5.0 / 6.0);
-const kSqrt03_08 = Math.sqrt( 3.0 / 8.0);
-const kSqrt05_08 = Math.sqrt( 5.0 / 8.0);
-const kSqrt09_08 = Math.sqrt( 9.0 / 8.0);
-const kSqrt05_09 = Math.sqrt( 5.0 / 9.0);
-const kSqrt08_09 = Math.sqrt( 8.0 / 9.0);
-const kSqrt01_10 = Math.sqrt( 1.0 / 10.0);
-const kSqrt03_10 = Math.sqrt( 3.0 / 10.0);
-const kSqrt01_12 = Math.sqrt( 1.0 / 12.0);
-const kSqrt04_15 = Math.sqrt( 4.0 / 15.0);
-const kSqrt01_16 = Math.sqrt( 1.0 / 16.0);
-const kSqrt15_16 = Math.sqrt(15.0 / 16.0);
-const kSqrt01_18 = Math.sqrt( 1.0 / 18.0);
-const kSqrt01_60 = Math.sqrt( 1.0 / 60.0);
-
-const dp = (n: number, start: number, a: number[] | Float32Array, b: number[] | Float32Array) => {
- let sum = 0;
- for (let i = 0; i < n; i++) {
- sum += a[start + i] * b[i];
- }
- return sum;
-}
-
-const coeffsIn = new Float32Array(16);
-
-// Rotate spherical harmonics up to band 3 based on https://github.com/andrewwillmott/sh-lib
-//
-// This implementation calculates the rotation factors during construction which can then
-// be used to rotate multiple spherical harmonics cheaply.
-class SHRotation {
- apply: (result: Float32Array | number[], src?: Float32Array | number[]) => void;
-
- constructor(mat: Mat3) {
- const rot = mat.data;
-
- // band 1
- const sh1 = [
- [ rot[4],-rot[7], rot[1] ],
- [-rot[5], rot[8],-rot[2] ],
- [ rot[3],-rot[6], rot[0] ]
- ];
-
- // band 2
- const sh2 = [[
- kSqrt01_04 * ((sh1[2][2] * sh1[0][0] + sh1[2][0] * sh1[0][2]) + (sh1[0][2] * sh1[2][0] + sh1[0][0] * sh1[2][2])),
- (sh1[2][1] * sh1[0][0] + sh1[0][1] * sh1[2][0]),
- kSqrt03_04 * (sh1[2][1] * sh1[0][1] + sh1[0][1] * sh1[2][1]),
- (sh1[2][1] * sh1[0][2] + sh1[0][1] * sh1[2][2]),
- kSqrt01_04 * ((sh1[2][2] * sh1[0][2] - sh1[2][0] * sh1[0][0]) + (sh1[0][2] * sh1[2][2] - sh1[0][0] * sh1[2][0]))
- ], [
- kSqrt01_04 * ((sh1[1][2] * sh1[0][0] + sh1[1][0] * sh1[0][2]) + (sh1[0][2] * sh1[1][0] + sh1[0][0] * sh1[1][2])),
- sh1[1][1] * sh1[0][0] + sh1[0][1] * sh1[1][0],
- kSqrt03_04 * (sh1[1][1] * sh1[0][1] + sh1[0][1] * sh1[1][1]),
- sh1[1][1] * sh1[0][2] + sh1[0][1] * sh1[1][2],
- kSqrt01_04 * ((sh1[1][2] * sh1[0][2] - sh1[1][0] * sh1[0][0]) + (sh1[0][2] * sh1[1][2] - sh1[0][0] * sh1[1][0])),
- ], [
- kSqrt01_03 * (sh1[1][2] * sh1[1][0] + sh1[1][0] * sh1[1][2]) - kSqrt01_12 * ((sh1[2][2] * sh1[2][0] + sh1[2][0] * sh1[2][2]) + (sh1[0][2] * sh1[0][0] + sh1[0][0] * sh1[0][2])),
- kSqrt04_03 * sh1[1][1] * sh1[1][0] - kSqrt01_03 * (sh1[2][1] * sh1[2][0] + sh1[0][1] * sh1[0][0]),
- sh1[1][1] * sh1[1][1] - kSqrt01_04 * (sh1[2][1] * sh1[2][1] + sh1[0][1] * sh1[0][1]),
- kSqrt04_03 * sh1[1][1] * sh1[1][2] - kSqrt01_03 * (sh1[2][1] * sh1[2][2] + sh1[0][1] * sh1[0][2]),
- kSqrt01_03 * (sh1[1][2] * sh1[1][2] - sh1[1][0] * sh1[1][0]) - kSqrt01_12 * ((sh1[2][2] * sh1[2][2] - sh1[2][0] * sh1[2][0]) + (sh1[0][2] * sh1[0][2] - sh1[0][0] * sh1[0][0])),
- ], [
- kSqrt01_04 * ((sh1[1][2] * sh1[2][0] + sh1[1][0] * sh1[2][2]) + (sh1[2][2] * sh1[1][0] + sh1[2][0] * sh1[1][2])),
- sh1[1][1] * sh1[2][0] + sh1[2][1] * sh1[1][0],
- kSqrt03_04 * (sh1[1][1] * sh1[2][1] + sh1[2][1] * sh1[1][1]),
- sh1[1][1] * sh1[2][2] + sh1[2][1] * sh1[1][2],
- kSqrt01_04 * ((sh1[1][2] * sh1[2][2] - sh1[1][0] * sh1[2][0]) + (sh1[2][2] * sh1[1][2] - sh1[2][0] * sh1[1][0])),
- ], [
- kSqrt01_04 * ((sh1[2][2] * sh1[2][0] + sh1[2][0] * sh1[2][2]) - (sh1[0][2] * sh1[0][0] + sh1[0][0] * sh1[0][2])),
- (sh1[2][1] * sh1[2][0] - sh1[0][1] * sh1[0][0]),
- kSqrt03_04 * (sh1[2][1] * sh1[2][1] - sh1[0][1] * sh1[0][1]),
- (sh1[2][1] * sh1[2][2] - sh1[0][1] * sh1[0][2]),
- kSqrt01_04 * ((sh1[2][2] * sh1[2][2] - sh1[2][0] * sh1[2][0]) - (sh1[0][2] * sh1[0][2] - sh1[0][0] * sh1[0][0])),
- ]];
-
- // band 3
- const sh3 = [[
- kSqrt01_04 * ((sh1[2][2] * sh2[0][0] + sh1[2][0] * sh2[0][4]) + (sh1[0][2] * sh2[4][0] + sh1[0][0] * sh2[4][4])),
- kSqrt03_02 * (sh1[2][1] * sh2[0][0] + sh1[0][1] * sh2[4][0]),
- kSqrt15_16 * (sh1[2][1] * sh2[0][1] + sh1[0][1] * sh2[4][1]),
- kSqrt05_06 * (sh1[2][1] * sh2[0][2] + sh1[0][1] * sh2[4][2]),
- kSqrt15_16 * (sh1[2][1] * sh2[0][3] + sh1[0][1] * sh2[4][3]),
- kSqrt03_02 * (sh1[2][1] * sh2[0][4] + sh1[0][1] * sh2[4][4]),
- kSqrt01_04 * ((sh1[2][2] * sh2[0][4] - sh1[2][0] * sh2[0][0]) + (sh1[0][2] * sh2[4][4] - sh1[0][0] * sh2[4][0])),
- ], [
- kSqrt01_06 * (sh1[1][2] * sh2[0][0] + sh1[1][0] * sh2[0][4]) + kSqrt01_06 * ((sh1[2][2] * sh2[1][0] + sh1[2][0] * sh2[1][4]) + (sh1[0][2] * sh2[3][0] + sh1[0][0] * sh2[3][4])),
- sh1[1][1] * sh2[0][0] + (sh1[2][1] * sh2[1][0] + sh1[0][1] * sh2[3][0]),
- kSqrt05_08 * sh1[1][1] * sh2[0][1] + kSqrt05_08 * (sh1[2][1] * sh2[1][1] + sh1[0][1] * sh2[3][1]),
- kSqrt05_09 * sh1[1][1] * sh2[0][2] + kSqrt05_09 * (sh1[2][1] * sh2[1][2] + sh1[0][1] * sh2[3][2]),
- kSqrt05_08 * sh1[1][1] * sh2[0][3] + kSqrt05_08 * (sh1[2][1] * sh2[1][3] + sh1[0][1] * sh2[3][3]),
- sh1[1][1] * sh2[0][4] + (sh1[2][1] * sh2[1][4] + sh1[0][1] * sh2[3][4]),
- kSqrt01_06 * (sh1[1][2] * sh2[0][4] - sh1[1][0] * sh2[0][0]) + kSqrt01_06 * ((sh1[2][2] * sh2[1][4] - sh1[2][0] * sh2[1][0]) + (sh1[0][2] * sh2[3][4] - sh1[0][0] * sh2[3][0])),
- ], [
- kSqrt04_15 * (sh1[1][2] * sh2[1][0] + sh1[1][0] * sh2[1][4]) + kSqrt01_05 * (sh1[0][2] * sh2[2][0] + sh1[0][0] * sh2[2][4]) - kSqrt01_60 * ((sh1[2][2] * sh2[0][0] + sh1[2][0] * sh2[0][4]) - (sh1[0][2] * sh2[4][0] + sh1[0][0] * sh2[4][4])),
- kSqrt08_05 * sh1[1][1] * sh2[1][0] + kSqrt06_05 * sh1[0][1] * sh2[2][0] - kSqrt01_10 * (sh1[2][1] * sh2[0][0] - sh1[0][1] * sh2[4][0]),
- sh1[1][1] * sh2[1][1] + kSqrt03_04 * sh1[0][1] * sh2[2][1] - kSqrt01_16 * (sh1[2][1] * sh2[0][1] - sh1[0][1] * sh2[4][1]),
- kSqrt08_09 * sh1[1][1] * sh2[1][2] + kSqrt02_03 * sh1[0][1] * sh2[2][2] - kSqrt01_18 * (sh1[2][1] * sh2[0][2] - sh1[0][1] * sh2[4][2]),
- sh1[1][1] * sh2[1][3] + kSqrt03_04 * sh1[0][1] * sh2[2][3] - kSqrt01_16 * (sh1[2][1] * sh2[0][3] - sh1[0][1] * sh2[4][3]),
- kSqrt08_05 * sh1[1][1] * sh2[1][4] + kSqrt06_05 * sh1[0][1] * sh2[2][4] - kSqrt01_10 * (sh1[2][1] * sh2[0][4] - sh1[0][1] * sh2[4][4]),
- kSqrt04_15 * (sh1[1][2] * sh2[1][4] - sh1[1][0] * sh2[1][0]) + kSqrt01_05 * (sh1[0][2] * sh2[2][4] - sh1[0][0] * sh2[2][0]) - kSqrt01_60 * ((sh1[2][2] * sh2[0][4] - sh1[2][0] * sh2[0][0]) - (sh1[0][2] * sh2[4][4] - sh1[0][0] * sh2[4][0])),
- ], [
- kSqrt03_10 * (sh1[1][2] * sh2[2][0] + sh1[1][0] * sh2[2][4]) - kSqrt01_10 * ((sh1[2][2] * sh2[3][0] + sh1[2][0] * sh2[3][4]) + (sh1[0][2] * sh2[1][0] + sh1[0][0] * sh2[1][4])),
- kSqrt09_05 * sh1[1][1] * sh2[2][0] - kSqrt03_05 * (sh1[2][1] * sh2[3][0] + sh1[0][1] * sh2[1][0]),
- kSqrt09_08 * sh1[1][1] * sh2[2][1] - kSqrt03_08 * (sh1[2][1] * sh2[3][1] + sh1[0][1] * sh2[1][1]),
- sh1[1][1] * sh2[2][2] - kSqrt01_03 * (sh1[2][1] * sh2[3][2] + sh1[0][1] * sh2[1][2]),
- kSqrt09_08 * sh1[1][1] * sh2[2][3] - kSqrt03_08 * (sh1[2][1] * sh2[3][3] + sh1[0][1] * sh2[1][3]),
- kSqrt09_05 * sh1[1][1] * sh2[2][4] - kSqrt03_05 * (sh1[2][1] * sh2[3][4] + sh1[0][1] * sh2[1][4]),
- kSqrt03_10 * (sh1[1][2] * sh2[2][4] - sh1[1][0] * sh2[2][0]) - kSqrt01_10 * ((sh1[2][2] * sh2[3][4] - sh1[2][0] * sh2[3][0]) + (sh1[0][2] * sh2[1][4] - sh1[0][0] * sh2[1][0])),
- ], [
- kSqrt04_15 * (sh1[1][2] * sh2[3][0] + sh1[1][0] * sh2[3][4]) + kSqrt01_05 * (sh1[2][2] * sh2[2][0] + sh1[2][0] * sh2[2][4]) - kSqrt01_60 * ((sh1[2][2] * sh2[4][0] + sh1[2][0] * sh2[4][4]) + (sh1[0][2] * sh2[0][0] + sh1[0][0] * sh2[0][4])),
- kSqrt08_05 * sh1[1][1] * sh2[3][0] + kSqrt06_05 * sh1[2][1] * sh2[2][0] - kSqrt01_10 * (sh1[2][1] * sh2[4][0] + sh1[0][1] * sh2[0][0]),
- sh1[1][1] * sh2[3][1] + kSqrt03_04 * sh1[2][1] * sh2[2][1] - kSqrt01_16 * (sh1[2][1] * sh2[4][1] + sh1[0][1] * sh2[0][1]),
- kSqrt08_09 * sh1[1][1] * sh2[3][2] + kSqrt02_03 * sh1[2][1] * sh2[2][2] - kSqrt01_18 * (sh1[2][1] * sh2[4][2] + sh1[0][1] * sh2[0][2]),
- sh1[1][1] * sh2[3][3] + kSqrt03_04 * sh1[2][1] * sh2[2][3] - kSqrt01_16 * (sh1[2][1] * sh2[4][3] + sh1[0][1] * sh2[0][3]),
- kSqrt08_05 * sh1[1][1] * sh2[3][4] + kSqrt06_05 * sh1[2][1] * sh2[2][4] - kSqrt01_10 * (sh1[2][1] * sh2[4][4] + sh1[0][1] * sh2[0][4]),
- kSqrt04_15 * (sh1[1][2] * sh2[3][4] - sh1[1][0] * sh2[3][0]) + kSqrt01_05 * (sh1[2][2] * sh2[2][4] - sh1[2][0] * sh2[2][0]) - kSqrt01_60 * ((sh1[2][2] * sh2[4][4] - sh1[2][0] * sh2[4][0]) + (sh1[0][2] * sh2[0][4] - sh1[0][0] * sh2[0][0])),
- ], [
- kSqrt01_06 * (sh1[1][2] * sh2[4][0] + sh1[1][0] * sh2[4][4]) + kSqrt01_06 * ((sh1[2][2] * sh2[3][0] + sh1[2][0] * sh2[3][4]) - (sh1[0][2] * sh2[1][0] + sh1[0][0] * sh2[1][4])),
- sh1[1][1] * sh2[4][0] + (sh1[2][1] * sh2[3][0] - sh1[0][1] * sh2[1][0]),
- kSqrt05_08 * sh1[1][1] * sh2[4][1] + kSqrt05_08 * (sh1[2][1] * sh2[3][1] - sh1[0][1] * sh2[1][1]),
- kSqrt05_09 * sh1[1][1] * sh2[4][2] + kSqrt05_09 * (sh1[2][1] * sh2[3][2] - sh1[0][1] * sh2[1][2]),
- kSqrt05_08 * sh1[1][1] * sh2[4][3] + kSqrt05_08 * (sh1[2][1] * sh2[3][3] - sh1[0][1] * sh2[1][3]),
- sh1[1][1] * sh2[4][4] + (sh1[2][1] * sh2[3][4] - sh1[0][1] * sh2[1][4]),
- kSqrt01_06 * (sh1[1][2] * sh2[4][4] - sh1[1][0] * sh2[4][0]) + kSqrt01_06 * ((sh1[2][2] * sh2[3][4] - sh1[2][0] * sh2[3][0]) - (sh1[0][2] * sh2[1][4] - sh1[0][0] * sh2[1][0])),
- ], [
- kSqrt01_04 * ((sh1[2][2] * sh2[4][0] + sh1[2][0] * sh2[4][4]) - (sh1[0][2] * sh2[0][0] + sh1[0][0] * sh2[0][4])),
- kSqrt03_02 * (sh1[2][1] * sh2[4][0] - sh1[0][1] * sh2[0][0]),
- kSqrt15_16 * (sh1[2][1] * sh2[4][1] - sh1[0][1] * sh2[0][1]),
- kSqrt05_06 * (sh1[2][1] * sh2[4][2] - sh1[0][1] * sh2[0][2]),
- kSqrt15_16 * (sh1[2][1] * sh2[4][3] - sh1[0][1] * sh2[0][3]),
- kSqrt03_02 * (sh1[2][1] * sh2[4][4] - sh1[0][1] * sh2[0][4]),
- kSqrt01_04 * ((sh1[2][2] * sh2[4][4] - sh1[2][0] * sh2[4][0]) - (sh1[0][2] * sh2[0][4] - sh1[0][0] * sh2[0][0])),
- ]];
-
- // rotate spherical harmonic coefficients, up to band 3
- this.apply = (result: Float32Array | number[], src?: Float32Array | number[]) => {
- if (!src || src == result) {
- coeffsIn.set(result);
- src = coeffsIn;
- }
-
- // band 0
- result[0] = src[0];
-
- // band 1
- if (result.length < 4) {
- return;
- }
- result[1] = dp(3, 1, src, sh1[0]);
- result[2] = dp(3, 1, src, sh1[1]);
- result[3] = dp(3, 1, src, sh1[2]);
-
- // band 2
- if (result.length < 9)
- return;
- result[4] = dp(5, 4, src, sh2[0]);
- result[5] = dp(5, 4, src, sh2[1]);
- result[6] = dp(5, 4, src, sh2[2]);
- result[7] = dp(5, 4, src, sh2[3]);
- result[8] = dp(5, 4, src, sh2[4]);
-
- // band 3
- if (result.length < 16)
- return;
- result[9] = dp(7, 9, src, sh3[0]);
- result[10] = dp(7, 9, src, sh3[1]);
- result[11] = dp(7, 9, src, sh3[2]);
- result[12] = dp(7, 9, src, sh3[3]);
- result[13] = dp(7, 9, src, sh3[4]);
- result[14] = dp(7, 9, src, sh3[5]);
- result[15] = dp(7, 9, src, sh3[6]);
- };
- }
-}
-
-export { SHRotation };
diff --git a/mirror-2/splat/src/shaders/bound-shader.ts b/mirror-2/splat/src/shaders/bound-shader.ts
deleted file mode 100644
index 7722002f..00000000
--- a/mirror-2/splat/src/shaders/bound-shader.ts
+++ /dev/null
@@ -1,66 +0,0 @@
-const vertexShader = /* glsl */ `
- attribute vec2 vertex_position;
- void main(void) {
- gl_Position = vec4(vertex_position, 0.0, 1.0);
- }
-`;
-
-const fragmentShader = /* glsl */ `
- uniform highp usampler2D transformA; // splat center x, y, z
- uniform highp usampler2D splatTransform; // transform palette index
- uniform sampler2D transformPalette; // palette of transforms
- uniform sampler2D splatState; // per-splat state
- uniform highp ivec3 splat_params; // texture width, texture height, num splats
- uniform highp uint mode; // 0: selected, 1: visible
-
- // calculate min and max for a single column of splats
- void main(void) {
-
- vec3 boundMin = vec3(100000.0);
- vec3 boundMax = vec3(-100000.0);
-
- for (int id = 0; id < splat_params.y; id++) {
- // calculate splatUV
- ivec2 splatUV = ivec2(gl_FragCoord.x, id);
-
- // skip out-of-range splats
- if (splatUV.x + splatUV.y * splat_params.x > splat_params.z) {
- continue;
- }
-
- // read splat state
- uint state = uint(texelFetch(splatState, splatUV, 0).r * 255.0);
-
- // skip deleted or hidden splats
- if (((mode == 0u) && (state != 1u)) || ((mode == 1u) && ((state & 4u) != 0u))) {
- continue;
- }
-
- // read splat center
- vec3 center = uintBitsToFloat(texelFetch(transformA, splatUV, 0).xyz);
-
- // apply optional per-splat transform
- uint transformIndex = texelFetch(splatTransform, splatUV, 0).r;
- if (transformIndex > 0u) {
- // read transform matrix
- int u = int(transformIndex % 512u) * 3;
- int v = int(transformIndex / 512u);
-
- mat3x4 t;
- t[0] = texelFetch(transformPalette, ivec2(u, v), 0);
- t[1] = texelFetch(transformPalette, ivec2(u + 1, v), 0);
- t[2] = texelFetch(transformPalette, ivec2(u + 2, v), 0);
-
- center = vec4(center, 1.0) * t;
- }
-
- boundMin = min(boundMin, center);
- boundMax = max(boundMax, center);
- }
-
- pcFragColor0 = vec4(boundMin, 0.0);
- pcFragColor1 = vec4(boundMax, 0.0);
- }
-`;
-
-export { vertexShader, fragmentShader };
diff --git a/mirror-2/splat/src/shaders/intersection-shader.ts b/mirror-2/splat/src/shaders/intersection-shader.ts
deleted file mode 100644
index f31c789d..00000000
--- a/mirror-2/splat/src/shaders/intersection-shader.ts
+++ /dev/null
@@ -1,95 +0,0 @@
-const vertexShader = /* glsl */ `
- attribute vec2 vertex_position;
- void main(void) {
- gl_Position = vec4(vertex_position, 0.0, 1.0);
- }
-`;
-
-const fragmentShader = /* glsl */ `
- uniform highp usampler2D transformA; // splat center x, y, z
- uniform highp usampler2D splatTransform; // transform palette index
- uniform sampler2D transformPalette; // palette of transforms
- uniform uvec2 splat_params; // splat texture width, num splats
-
- uniform mat4 matrix_model;
- uniform mat4 matrix_viewProjection;
-
- uniform uvec2 output_params; // output width, height
-
- // 0: mask, 1: rect, 2: sphere
- uniform int mode;
-
- // mask params
- uniform sampler2D mask; // mask in alpha channel
- uniform vec2 mask_params; // mask width, height
-
- // rect params
- uniform vec4 rect_params; // rect x, y, width, height
-
- // sphere params
- uniform vec4 sphere_params; // sphere x, y, z, radius
-
- void main(void) {
- // calculate output id
- uvec2 outputUV = uvec2(gl_FragCoord);
- uint outputId = (outputUV.x + outputUV.y * output_params.x) * 4u;
-
- vec4 clr = vec4(0.0);
-
- for (uint i = 0u; i < 4u; i++) {
- uint id = outputId + i;
-
- if (id >= splat_params.y) {
- continue;
- }
-
- // calculate splatUV
- ivec2 splatUV = ivec2(
- int(id % splat_params.x),
- int(id / splat_params.x)
- );
-
- // read splat center
- vec3 center = uintBitsToFloat(texelFetch(transformA, splatUV, 0).xyz);
-
- // apply optional per-splat transform
- uint transformIndex = texelFetch(splatTransform, splatUV, 0).r;
- if (transformIndex > 0u) {
- // read transform matrix
- int u = int(transformIndex % 512u) * 3;
- int v = int(transformIndex / 512u);
-
- mat3x4 t;
- t[0] = texelFetch(transformPalette, ivec2(u, v), 0);
- t[1] = texelFetch(transformPalette, ivec2(u + 1, v), 0);
- t[2] = texelFetch(transformPalette, ivec2(u + 2, v), 0);
-
- center = vec4(center, 1.0) * t;
- }
-
- // transform to clip space and discard if outside
- vec3 world = (matrix_model * vec4(center, 1.0)).xyz;
- vec4 clip = matrix_viewProjection * vec4(world, 1.0);
- vec3 ndc = clip.xyz / clip.w;
-
- // skip offscreen fragments
- if (!any(greaterThan(abs(ndc), vec3(1.0)))) {
- if (mode == 0) {
- // select by mask
- ivec2 maskUV = ivec2((ndc.xy * vec2(0.5, -0.5) + 0.5) * mask_params);
- clr[i] = texelFetch(mask, maskUV, 0).a < 1.0 ? 0.0 : 1.0;
- } else if (mode == 1) {
- // select by rect
- clr[i] = all(greaterThan(ndc.xy * vec2(1.0, -1.0), rect_params.xy)) && all(lessThan(ndc.xy * vec2(1.0, -1.0), rect_params.zw)) ? 1.0 : 0.0;
- } else if (mode == 2) {
- // select by sphere
- clr[i] = length(world - sphere_params.xyz) < sphere_params.w ? 1.0 : 0.0;
- }
- }
- }
-
- gl_FragColor = clr;
- }
-`;
-
-export { vertexShader, fragmentShader };
diff --git a/mirror-2/splat/src/shaders/position-shader.ts b/mirror-2/splat/src/shaders/position-shader.ts
deleted file mode 100644
index 45f4298f..00000000
--- a/mirror-2/splat/src/shaders/position-shader.ts
+++ /dev/null
@@ -1,45 +0,0 @@
-const vertexShader = /* glsl */ `
- attribute vec2 vertex_position;
- void main(void) {
- gl_Position = vec4(vertex_position, 0.0, 1.0);
- }
-`;
-
-const fragmentShader = /* glsl */ `
- uniform highp usampler2D transformA; // splat center x, y, z
- uniform highp usampler2D splatTransform; // transform palette index
- uniform sampler2D transformPalette; // palette of transforms
- uniform ivec2 splat_params; // splat texture width, num splats
-
- void main(void) {
- // calculate output id
- ivec2 splatUV = ivec2(gl_FragCoord);
-
- // skip if splat index is out of bounds
- if (splatUV.x + splatUV.y * splat_params.x >= splat_params.y) {
- discard;
- }
-
- // read splat center
- vec3 center = uintBitsToFloat(texelFetch(transformA, splatUV, 0).xyz);
-
- // apply optional per-splat transform
- uint transformIndex = texelFetch(splatTransform, splatUV, 0).r;
- if (transformIndex > 0u) {
- // read transform matrix
- int u = int(transformIndex % 512u) * 3;
- int v = int(transformIndex / 512u);
-
- mat3x4 t;
- t[0] = texelFetch(transformPalette, ivec2(u, v), 0);
- t[1] = texelFetch(transformPalette, ivec2(u + 1, v), 0);
- t[2] = texelFetch(transformPalette, ivec2(u + 2, v), 0);
-
- center = vec4(center, 1.0) * t;
- }
-
- gl_FragColor = vec4(center, 0.0);
- }
-`;
-
-export { vertexShader, fragmentShader };
diff --git a/mirror-2/splat/src/shaders/splat-overlay-shader.ts b/mirror-2/splat/src/shaders/splat-overlay-shader.ts
deleted file mode 100644
index 04407d6f..00000000
--- a/mirror-2/splat/src/shaders/splat-overlay-shader.ts
+++ /dev/null
@@ -1,72 +0,0 @@
-const vertexShader = /* glsl */ `
- attribute uint vertex_id;
-
- uniform mat4 matrix_model;
- uniform mat4 matrix_viewProjection;
-
- uniform sampler2D splatState;
- uniform highp usampler2D splatPosition;
- uniform highp usampler2D splatTransform; // per-splat index into transform palette
- uniform sampler2D transformPalette; // palette of transform matrices
-
- uniform float splatSize;
- uniform uvec2 texParams;
-
- varying vec4 varying_color;
-
- // calculate the current splat index and uv
- ivec2 calcSplatUV(uint index, uint width) {
- return ivec2(int(index % width), int(index / width));
- }
-
- void main(void) {
- ivec2 splatUV = calcSplatUV(vertex_id, texParams.x);
- uint splatState = uint(texelFetch(splatState, splatUV, 0).r * 255.0);
-
- if ((splatState & 6u) != 0u) {
- // deleted or hidden (4 or 2)
- gl_Position = vec4(0.0, 0.0, 2.0, 1.0);
- gl_PointSize = 0.0;
- } else {
- mat4 model = matrix_model;
-
- // handle per-splat transform
- uint transformIndex = texelFetch(splatTransform, splatUV, 0).r;
- if (transformIndex > 0u) {
- // read transform matrix
- int u = int(transformIndex % 512u) * 3;
- int v = int(transformIndex / 512u);
-
- mat4 t;
- t[0] = texelFetch(transformPalette, ivec2(u, v), 0);
- t[1] = texelFetch(transformPalette, ivec2(u + 1, v), 0);
- t[2] = texelFetch(transformPalette, ivec2(u + 2, v), 0);
- t[3] = vec4(0.0, 0.0, 0.0, 1.0);
-
- model = matrix_model * transpose(t);
- }
-
- if ((splatState & 1u) != 0u) {
- // selected
- varying_color = vec4(1.0, 1.0, 0.0, 0.5);
- } else {
- varying_color = vec4(0.0, 0.0, 1.0, 0.5);
- }
-
- vec3 center = uintBitsToFloat(texelFetch(splatPosition, splatUV, 0).xyz);
-
- gl_Position = matrix_viewProjection * model * vec4(center, 1.0);
- gl_PointSize = splatSize;
- }
- }
-`;
-
-const fragmentShader = /* glsl */ `
- varying vec4 varying_color;
-
- void main(void) {
- gl_FragColor = varying_color;
- }
-`;
-
-export { vertexShader, fragmentShader };
diff --git a/mirror-2/splat/src/shaders/splat-shader.ts b/mirror-2/splat/src/shaders/splat-shader.ts
deleted file mode 100644
index 188af022..00000000
--- a/mirror-2/splat/src/shaders/splat-shader.ts
+++ /dev/null
@@ -1,170 +0,0 @@
-
-const vertexShader = /*glsl*/`
-uniform vec3 view_position;
-
-uniform sampler2D splatColor;
-uniform sampler2D splatState;
-uniform highp usampler2D splatTransform; // per-splat index into transform palette
-uniform sampler2D transformPalette; // palette of transform matrices
-
-varying mediump vec2 texCoord;
-varying mediump vec4 color;
-flat varying highp uint vertexState;
-#ifdef PICK_PASS
- flat varying highp uint vertexId;
-#endif
-
-mediump vec4 discardVec = vec4(0.0, 0.0, 2.0, 1.0);
-
-void main(void)
-{
- // calculate splat uv
- if (!calcSplatUV()) {
- gl_Position = discardVec;
- return;
- }
-
- // get center
- vec3 center = getCenter();
-
- // get vertex state
- vertexState = uint(texelFetch(splatState, splatUV, 0).r * 255.0);
-
- mat4 model = matrix_model;
-
- // handle per-splat transform
- uint transformIndex = texelFetch(splatTransform, splatUV, 0).r;
- if (transformIndex > 0u) {
- // read transform matrix
- int u = int(transformIndex % 512u) * 3;
- int v = int(transformIndex / 512u);
-
- mat4 t;
- t[0] = texelFetch(transformPalette, ivec2(u, v), 0);
- t[1] = texelFetch(transformPalette, ivec2(u + 1, v), 0);
- t[2] = texelFetch(transformPalette, ivec2(u + 2, v), 0);
- t[3] = vec4(0.0, 0.0, 0.0, 1.0);
-
- model = matrix_model * transpose(t);
- }
-
- // handle transforms
- mat4 model_view = matrix_view * model;
- vec4 splat_cam = model_view * vec4(center, 1.0);
- vec4 splat_proj = matrix_projection * splat_cam;
-
- // cull behind camera
- if (splat_proj.z < -splat_proj.w) {
- gl_Position = discardVec;
- return;
- }
-
- // get covariance
- vec3 covA, covB;
- getCovariance(covA, covB);
-
- vec4 v1v2 = calcV1V2(splat_cam.xyz, covA, covB, transpose(mat3(model_view)));
-
- // get color
- color = texelFetch(splatColor, splatUV, 0);
-
- // calculate scale based on alpha
- // float scale = min(1.0, sqrt(-log(1.0 / 255.0 / color.a)) / 2.0);
-
- // v1v2 *= scale;
-
- // early out tiny splats
- if (dot(v1v2.xy, v1v2.xy) < 4.0 && dot(v1v2.zw, v1v2.zw) < 4.0) {
- gl_Position = discardVec;
- return;
- }
-
- gl_Position = splat_proj + vec4((vertex_position.x * v1v2.xy + vertex_position.y * v1v2.zw) / viewport * splat_proj.w, 0, 0);
-
- texCoord = vertex_position.xy * 0.5; // * scale;
-
- #ifdef USE_SH1
- vec4 worldCenter = model * vec4(center, 1.0);
- vec3 viewDir = normalize((worldCenter.xyz / worldCenter.w - view_position) * mat3(model));
- color.xyz = max(color.xyz + evalSH(viewDir), 0.0);
- #endif
-
- #ifndef DITHER_NONE
- id = float(splatId);
- #endif
-
- #ifdef PICK_PASS
- vertexId = splatId;
- #endif
-}
-`;
-
-const fragmentShader = /*glsl*/`
-varying mediump vec2 texCoord;
-varying mediump vec4 color;
-
-flat varying highp uint vertexState;
-#ifdef PICK_PASS
- flat varying highp uint vertexId;
-#endif
-
-uniform float pickerAlpha;
-uniform float ringSize;
-uniform float selectionAlpha;
-
-void main(void)
-{
- mediump float A = dot(texCoord, texCoord);
- if (A > 1.0) {
- discard;
- }
-
- mediump float B = exp(-A * 4.0) * color.a;
-
- #ifdef PICK_PASS
- if (B < pickerAlpha || (vertexState & 2u) == 2u) {
- // hidden
- discard;
- }
- gl_FragColor = vec4(
- float(vertexId & 255u) / 255.0,
- float((vertexId >> 8) & 255u) / 255.0,
- float((vertexId >> 16) & 255u) / 255.0,
- float((vertexId >> 24) & 255u) / 255.0
- );
- #else
- vec3 c;
- float alpha;
-
- if ((vertexState & 2u) == 2u) {
- // frozen/hidden
- c = vec3(0.0, 0.0, 0.0);
- alpha = B * 0.05;
- } else {
- if ((vertexState & 1u) == 1u) {
- // selected
- c = mix(color.xyz, vec3(1.0, 1.0, 0.0), selectionAlpha);
- } else {
- // normal
- c = color.xyz;
- }
-
- if (ringSize > 0.0) {
- // rings mode
- if (A < 1.0 - ringSize) {
- alpha = max(0.05, B);
- } else {
- alpha = 0.6;
- }
- } else {
- // centers mode
- alpha = B;
- }
- }
-
- gl_FragColor = vec4(c, alpha);
- #endif
-}
-`;
-
-export { vertexShader, fragmentShader };
diff --git a/mirror-2/splat/src/shortcuts.ts b/mirror-2/splat/src/shortcuts.ts
deleted file mode 100644
index 57b81683..00000000
--- a/mirror-2/splat/src/shortcuts.ts
+++ /dev/null
@@ -1,71 +0,0 @@
-import { Events } from "./events";
-
-interface ShortcutOptions {
- ctrl?: boolean;
- shift?: boolean;
- sticky?: boolean;
- func?: () => void;
- event?: string;
-}
-
-class Shortcuts {
- shortcuts: { keys: string[], options: ShortcutOptions, toggled: boolean }[] = [];
-
- constructor(events: Events) {
- const shortcuts = this.shortcuts;
-
- const handleEvent = (e: KeyboardEvent, down: boolean) => {
- // skip keys in input fields
- if (e.target !== document.body) return;
-
- for (let i = 0; i < shortcuts.length; i++) {
- const shortcut = shortcuts[i];
- const options = shortcut.options;
-
- if (shortcut.keys.includes(e.key) &&
- !!options.ctrl === !!(e.ctrlKey || e.metaKey) &&
- !!options.shift === !!e.shiftKey) {
-
- // handle sticky shortcuts
- if (options.sticky) {
- if (down) {
- shortcut.toggled = e.repeat;
- }
-
- if (down === shortcut.toggled) {
- return;
- }
- } else {
- // ignore up events on non-sticky shortcuts
- if (!down) return;
- }
-
- if (shortcuts[i].options.event) {
- events.fire(shortcuts[i].options.event);
- } else {
- shortcuts[i].options.func();
- }
-
- break;
- }
- }
- };
-
- // register keyboard handler
- document.addEventListener('keydown', (e) => {
- handleEvent(e, true);
- });
-
- document.addEventListener('keyup', (e) => {
- handleEvent(e, false);
- });
- }
-
- register(keys: string[], options: ShortcutOptions) {
- this.shortcuts.push({ keys, options, toggled: false });
- }
-}
-
-export {
- Shortcuts
-};
diff --git a/mirror-2/splat/src/sphere-shape.ts b/mirror-2/splat/src/sphere-shape.ts
deleted file mode 100644
index 012120e1..00000000
--- a/mirror-2/splat/src/sphere-shape.ts
+++ /dev/null
@@ -1,205 +0,0 @@
-import {
- createShaderFromCode,
- CULLFACE_NONE,
- BoundingBox,
- Entity,
- Material,
- Vec3
-} from 'playcanvas';
-import { Element, ElementType } from './element';
-import { Serializer } from './serializer';
-
-const vsCode = /* glsl */ `
- attribute vec3 vertex_position;
-
- uniform mat4 matrix_model;
- uniform mat4 matrix_viewProjection;
-
- varying vec3 fragWorld;
-
- void main() {
- vec4 world = matrix_model * vec4(vertex_position, 1.0);
- gl_Position = matrix_viewProjection * world;
- fragWorld = world.xyz;
- }
-`;
-
-const fsCode = /* glsl */ `
- bool intersectSphere(out float t0, out float t1, vec3 pos, vec3 dir, vec4 sphere) {
- vec3 L = sphere.xyz - pos;
- float tca = dot(L, dir);
-
- float d2 = sphere.w * sphere.w - (dot(L, L) - tca * tca);
- if (d2 < 0.0) {
- return false;
- }
-
- float thc = sqrt(d2);
- t0 = tca - thc;
- t1 = tca + thc;
- if (t1 < 0.0) {
- return false;
- }
-
- return true;
- }
-
- float calcDepth(in vec3 pos, in mat4 viewProjection) {
- vec4 v = viewProjection * vec4(pos, 1.0);
- return (v.z / v.w) * 0.5 + 0.5;
- }
-
- float noise(vec2 fragCoord, sampler2D noiseTex) {
- vec2 uv = fract(fragCoord / 32.0);
- return texture2DLodEXT(noiseTex, uv, 0.0).y;
- }
-
- vec2 calcAzimuthElev(in vec3 dir) {
- float azimuth = atan(dir.z, dir.x);
- float elev = asin(dir.y);
- return vec2(azimuth, elev) * 180.0 / 3.14159;
- }
-
- uniform sampler2D blueNoiseTex32;
- uniform vec3 view_position;
- uniform mat4 matrix_viewProjection;
- uniform vec4 sphere;
-
- varying vec3 fragWorld;
-
- bool strips(vec3 lp) {
- vec2 ae = calcAzimuthElev(normalize(lp));
-
- float spacing = 180.0 / (2.0 * 3.14159 * sphere.w);
- float size = 0.03;
- return fract(ae.x / spacing) > size &&
- fract(ae.y / spacing) > size;
- }
-
- void behind(vec3 ray, float t) {
- vec3 wp = view_position + ray * t;
- if (strips(wp - sphere.xyz) || noise(gl_FragCoord.yx, blueNoiseTex32) < 0.125) {
- discard;
- }
-
- gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);
- gl_FragDepth = calcDepth(wp, matrix_viewProjection);
- }
-
- void front(vec3 ray, float t0, float t1) {
- if (t0 < 0.0) {
- behind(ray, t1);
- } else {
- vec3 wp = view_position + ray * t0;
- if (strips(wp - sphere.xyz) || noise(gl_FragCoord.xy, blueNoiseTex32) < 0.6) {
- behind(ray, t1);
- } else {
- gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);
- gl_FragDepth = calcDepth(wp, matrix_viewProjection);
- }
- }
- }
-
- void main() {
- vec3 ray = normalize(fragWorld - view_position);
-
- float t0, t1;
- if (!intersectSphere(t0, t1, view_position, ray, sphere)) {
- discard;
- }
-
- front(ray, t0, t1);
- }
-`;
-
-const v = new Vec3();
-const bound = new BoundingBox();
-
-class SphereShape extends Element {
- _radius = 1;
- pivot: Entity;
- material: Material;
-
- constructor() {
- super(ElementType.debug);
-
- this.pivot = new Entity('spherePivot');
- this.pivot.addComponent('render', {
- type: 'box'
- });
- const r = this._radius * 2;
- this.pivot.setLocalScale(r, r, r);
- }
-
- add() {
- const device = this.scene.app.graphicsDevice;
-
- const shader = createShaderFromCode(
- device,
- vsCode,
- fsCode,
- 'sphere-shape'
- );
-
- const material = new Material();
- material.shader = shader;
- material.cull = CULLFACE_NONE;
- material.update();
-
- this.pivot.render.meshInstances[0].material = material;
-
- this.material = material;
-
- this.scene.contentRoot.addChild(this.pivot);
-
- this.updateBound();
- }
-
- remove() {
- this.scene.contentRoot.removeChild(this.pivot);
- this.scene.boundDirty = true;
- }
-
- destroy() {
-
- }
-
- serialize(serializer: Serializer): void {
- serializer.packa(this.pivot.getWorldTransform().data);
- serializer.pack(this.radius);
- }
-
- onPreRender() {
- this.pivot.getWorldTransform().getTranslation(v);
- this.material.setParameter('sphere', [v.x, v.y, v.z, this.radius]);
- }
-
- moved() {
- this.updateBound();
- }
-
- updateBound() {
- bound.center.copy(this.pivot.getPosition());
- bound.halfExtents.set(this.radius, this.radius, this.radius);
- this.scene.boundDirty = true;
- }
-
- get worldBound(): BoundingBox | null {
- return bound;
- }
-
- set radius(radius: number) {
- this._radius = radius;
-
- const r = this._radius * 2;
- this.pivot.setLocalScale(r, r, r);
-
- this.updateBound();
- }
-
- get radius() {
- return this._radius;
- }
-}
-
-export { SphereShape };
diff --git a/mirror-2/splat/src/splat-convert.ts b/mirror-2/splat/src/splat-convert.ts
deleted file mode 100644
index d69ece84..00000000
--- a/mirror-2/splat/src/splat-convert.ts
+++ /dev/null
@@ -1,712 +0,0 @@
-import {
- GSplatData,
- Mat3,
- Mat4,
- Quat,
- Vec3
-} from 'playcanvas';
-import { State } from './splat-state';
-import { Splat } from './splat';
-import { SHRotation } from './sh-utils';
-import { version } from '../package.json';
-
-const generatedByString = `Generated by SuperSplat ${version}`;
-
-const countTotalSplats = (splats: Splat[]) => {
- return splats.reduce((accum, splat) => {
- return accum + splat.numSplats;
- }, 0);
-};
-
-const getVertexProperties = (splatData: GSplatData) => {
- return new Set(
- splatData.getElement('vertex')
- .properties.filter((p: any) => p.storage)
- .map((p: any) => p.name)
- );
-};
-
-const getCommonPropNames = (splats: Splat[]) => {
- let result: Set;
-
- for (let i = 0; i < splats.length; ++i) {
- const props = getVertexProperties(splats[i].splatData);
- result = i == 0 ? props : new Set([...result].filter(i => props.has(i)));
- }
-
- return [...result];
-};
-
-// calculate splat transforms on demand and cache the result for next time
-class SplatTransformCache {
- getMat: (index: number) => Mat4;
- getRot: (index: number) => Quat;
- getScale: (index: number) => Vec3;
- getSHRot: (index: number) => SHRotation;
-
- constructor(splat: Splat) {
- const transforms = new Map();
- const indices = splat.transformTexture.getSource() as unknown as Uint32Array;
- const tmpMat = new Mat4();
- const tmpMat3 = new Mat3();
- const tmpQuat = new Quat();
-
- const getTransform = (index: number) => {
- let result = transforms.get(index);
- if (!result) {
- result = { mat: null, rot: null, scale: null, shRot: null };
- transforms.set(index, result);
- }
- return result;
- };
-
- this.getMat = (index: number) => {
- const transform = getTransform(index);
-
- if (!transform.mat) {
- const mat = new Mat4();
-
- // we must undo the transform we apply at load time to output data
- mat.setFromEulerAngles(0, 0, -180);
- mat.mul2(mat, splat.entity.getWorldTransform());
-
- // combine with transform palette matrix
- const transformIndex = indices?.[index] ?? 0;
- if (transformIndex > 0) {
- splat.transformPalette.getTransform(transformIndex, tmpMat);
- mat.mul2(mat, tmpMat);
- }
-
- transform.mat = mat;
- }
-
- return transform.mat;
- };
-
- this.getRot = (index: number) => {
- const transform = getTransform(index);
-
- if (!transform.rot) {
- transform.rot = new Quat().setFromMat4(this.getMat(index));
- }
-
- return transform.rot;
- }
-
- this.getScale = (index: number) => {
- const transform = getTransform(index);
-
- if (!transform.scale) {
- const scale = new Vec3();
- this.getMat(index).getScale(scale);
- transform.scale = scale;
- }
-
- return transform.scale;
- }
-
- this.getSHRot = (index: number) => {
- const transform = getTransform(index);
-
- if (!transform.shRot) {
- tmpQuat.setFromMat4(this.getMat(index));
- tmpMat3.setFromQuat(tmpQuat);
- transform.shRot = new SHRotation(tmpMat3);
- }
-
- return transform.shRot;
- };
- }
-}
-
-const v = new Vec3();
-const q = new Quat();
-
-const convertPly = (splats: Splat[]) => {
- // count the number of non-deleted splats
- const totalSplats = countTotalSplats(splats);
-
- const internalProps = ['state'];
-
- // get the vertex properties common to all splats
- const propNames = getCommonPropNames(splats).filter((p) => !internalProps.includes(p));
- const hasPosition = ['x', 'y', 'z'].every(v => propNames.includes(v));
- const hasRotation = ['rot_0', 'rot_1', 'rot_2', 'rot_3'].every(v => propNames.includes(v));
- const hasScale = ['scale_0', 'scale_1', 'scale_2'].every(v => propNames.includes(v));
- const hasSH = (() => {
- for (let i = 0; i < 45; ++i) {
- if (!propNames.includes(`f_rest_${i}`)) return false;
- }
- return true;
- })();
-
- const headerText = [
- `ply`,
- `format binary_little_endian 1.0`,
- `comment ${generatedByString}`,
- `element vertex ${totalSplats}`,
- propNames.map(p => `property float ${p}`),
- `end_header`,
- ``
- ].flat().join('\n');
-
- const header = (new TextEncoder()).encode(headerText);
- const result = new Uint8Array(header.byteLength + totalSplats * propNames.length * 4);
- const dataView = new DataView(result.buffer);
-
- // construct an object for holding a single splat's properties
- const splat = propNames.reduce((acc: any, name) => {
- acc[name] = 0;
- return acc;
- }, {});
-
- result.set(header);
-
- let offset = header.byteLength;
-
- for (let e = 0; e < splats.length; ++e) {
- const splatData = splats[e].splatData;
- const state = splatData.getProp('state') as Uint8Array;
- const storage = propNames.map((name) => splatData.getProp(name));
- const transformCache = new SplatTransformCache(splats[e]);
-
- let shData;
- let shCoeffs: number[];
- if (hasSH) {
- // get sh coefficient array
- shData = [];
- for (let i = 0; i < 45; ++i) {
- shData.push(splatData.getProp(`f_rest_${i}`));
- }
-
- shCoeffs = [0];
- }
-
- for (let i = 0; i < splatData.numSplats; ++i) {
- if ((state[i] & State.deleted) === State.deleted) continue;
-
- const mat = transformCache.getMat(i);
-
- // read splat data
- for (let j = 0; j < propNames.length; ++j) {
- splat[propNames[j]] = storage[j][i];
- }
-
- // transform
- if (hasPosition) {
- v.set(splat.x, splat.y, splat.z);
- mat.transformPoint(v, v);
- [splat.x, splat.y, splat.z] = [v.x, v.y, v.z];
- }
-
- if (hasRotation) {
- const quat = transformCache.getRot(i);
- q.set(splat.rot_1, splat.rot_2, splat.rot_3, splat.rot_0).mul2(quat, q);
- [splat.rot_1, splat.rot_2, splat.rot_3, splat.rot_0] = [q.x, q.y, q.z, q.w];
- }
-
- if (hasScale) {
- const scale = transformCache.getScale(i);
- splat.scale_0 = Math.log(Math.exp(splat.scale_0) * scale.x);
- splat.scale_1 = Math.log(Math.exp(splat.scale_1) * scale.y);
- splat.scale_2 = Math.log(Math.exp(splat.scale_2) * scale.z);
- }
-
- if (hasSH) {
- for (let c = 0; c < 3; ++c) {
- for (let d = 0; d < 15; ++d) {
- shCoeffs[d + 1] = shData[c * 15 + d][i];
- }
-
- transformCache.getSHRot(i).apply(shCoeffs, shCoeffs);
-
- for (let d = 0; d < 15; ++d) {
- splat[`f_rest_${c * 15 + d}`] = shCoeffs[d + 1];
- }
- }
- }
-
- // write
- for (let j = 0; j < propNames.length; ++j) {
- dataView.setFloat32(offset, splat[propNames[j]], true);
- offset += 4;
- }
- }
- }
-
- return result;
-};
-
-interface CompressedIndex {
- splatIndex: number;
- i: number;
- globalIndex: number;
-}
-
-class SingleSplat {
- x = 0;
- y = 0;
- z = 0;
- scale_0 = 0;
- scale_1 = 0;
- scale_2 = 0;
- f_dc_0 = 0;
- f_dc_1 = 0;
- f_dc_2 = 0;
- opacity = 0;
- rot_0 = 0;
- rot_1 = 0;
- rot_2 = 0;
- rot_3 = 0;
-
- read(splats: Splat[], index: CompressedIndex) {
- const { splatData } = splats[index.splatIndex];
- const val = (prop: string) => splatData.getProp(prop)[index.i];
- [this.x, this.y, this.z] = [val('x'), val('y'), val('z')];
- [this.scale_0, this.scale_1, this.scale_2] = [val('scale_0'), val('scale_1'), val('scale_2')];
- [this.f_dc_0, this.f_dc_1, this.f_dc_2, this.opacity] = [val('f_dc_0'), val('f_dc_1'), val('f_dc_2'), val('opacity')];
- [this.rot_0, this.rot_1, this.rot_2, this.rot_3] = [val('rot_0'), val('rot_1'), val('rot_2'), val('rot_3')];
- }
-
- transform(mat: Mat4, quat: Quat, scale: Vec3) {
- // position
- v.set(this.x, this.y, this.z);
- mat.transformPoint(v, v);
- [this.x, this.y, this.z] = [v.x, v.y, v.z];
-
- // rotation
- q.set(this.rot_1, this.rot_2, this.rot_3, this.rot_0).mul2(quat, q);
- [this.rot_1, this.rot_2, this.rot_3, this.rot_0] = [q.x, q.y, q.z, q.w];
-
- // scale
- this.scale_0 = Math.log(Math.exp(this.scale_0) * scale.x);
- this.scale_1 = Math.log(Math.exp(this.scale_1) * scale.y);
- this.scale_2 = Math.log(Math.exp(this.scale_2) * scale.z);
- }
-}
-
-// process and compress a chunk of 256 splats
-class Chunk {
- static members = [
- 'x', 'y', 'z',
- 'scale_0', 'scale_1', 'scale_2',
- 'f_dc_0', 'f_dc_1', 'f_dc_2', 'opacity',
- 'rot_0', 'rot_1', 'rot_2', 'rot_3'
- ];
-
- size: number;
- data: any = {};
-
- // compressed data
- position: Uint32Array;
- rotation: Uint32Array;
- scale: Uint32Array;
- color: Uint32Array;
-
- constructor(size = 256) {
- this.size = size;
- Chunk.members.forEach((m) => {
- this.data[m] = new Float32Array(size);
- });
- this.position = new Uint32Array(size);
- this.rotation = new Uint32Array(size);
- this.scale = new Uint32Array(size);
- this.color = new Uint32Array(size);
- }
-
- set(index: number, splat: SingleSplat) {
- Chunk.members.forEach((name) => {
- this.data[name][index] = (splat as any)[name];
- });
- }
-
- pack() {
- const calcMinMax = (data: Float32Array) => {
- let min;
- let max;
- min = max = data[0];
- for (let i = 1; i < data.length; ++i) {
- const v = data[i];
- min = Math.min(min, v);
- max = Math.max(max, v);
- }
- return { min, max };
- };
-
- const normalize = (x: number, min: number, max: number) => {
- return (max - min < 0.00001) ? 0 : (x - min) / (max - min);
- };
-
- const data = this.data;
-
- const x = data.x;
- const y = data.y;
- const z = data.z;
- const scale_0 = data.scale_0;
- const scale_1 = data.scale_1;
- const scale_2 = data.scale_2;
- const rot_0 = data.rot_0;
- const rot_1 = data.rot_1;
- const rot_2 = data.rot_2;
- const rot_3 = data.rot_3;
- const f_dc_0 = data.f_dc_0;
- const f_dc_1 = data.f_dc_1;
- const f_dc_2 = data.f_dc_2;
- const opacity = data.opacity;
-
- const px = calcMinMax(x);
- const py = calcMinMax(y);
- const pz = calcMinMax(z);
-
- const sx = calcMinMax(scale_0);
- const sy = calcMinMax(scale_1);
- const sz = calcMinMax(scale_2);
-
- const packUnorm = (value: number, bits: number) => {
- const t = (1 << bits) - 1;
- return Math.max(0, Math.min(t, Math.floor(value * t + 0.5)));
- };
-
- const pack111011 = (x: number, y: number, z: number) => {
- return packUnorm(x, 11) << 21 |
- packUnorm(y, 10) << 11 |
- packUnorm(z, 11);
- };
-
- const pack8888 = (x: number, y: number, z: number, w: number) => {
- return packUnorm(x, 8) << 24 |
- packUnorm(y, 8) << 16 |
- packUnorm(z, 8) << 8 |
- packUnorm(w, 8);
- };
-
- // pack quaternion into 2,10,10,10
- const packRot = (x: number, y: number, z: number, w: number) => {
- q.set(x, y, z, w).normalize();
- const a = [q.x, q.y, q.z, q.w];
- const largest = a.reduce((curr, v, i) => Math.abs(v) > Math.abs(a[curr]) ? i : curr, 0);
-
- if (a[largest] < 0) {
- a[0] = -a[0];
- a[1] = -a[1];
- a[2] = -a[2];
- a[3] = -a[3];
- }
-
- const norm = Math.sqrt(2) * 0.5;
- let result = largest;
- for (let i = 0; i < 4; ++i) {
- if (i !== largest) {
- result = (result << 10) | packUnorm(a[i] * norm + 0.5, 10);
- }
- }
-
- return result;
- };
-
- const packColor = (r: number, g: number, b: number, a: number) => {
- const SH_C0 = 0.28209479177387814;
- return pack8888(
- r * SH_C0 + 0.5,
- g * SH_C0 + 0.5,
- b * SH_C0 + 0.5,
- 1 / (1 + Math.exp(-a))
- );
- };
-
- // pack
- for (let i = 0; i < this.size; ++i) {
- this.position[i] = pack111011(
- normalize(x[i], px.min, px.max),
- normalize(y[i], py.min, py.max),
- normalize(z[i], pz.min, pz.max)
- );
-
- this.rotation[i] = packRot(rot_0[i], rot_1[i], rot_2[i], rot_3[i]);
-
- this.scale[i] = pack111011(
- normalize(scale_0[i], sx.min, sx.max),
- normalize(scale_1[i], sy.min, sy.max),
- normalize(scale_2[i], sz.min, sz.max)
- );
-
- this.color[i] = packColor(f_dc_0[i], f_dc_1[i], f_dc_2[i], opacity[i]);
- }
-
- return { px, py, pz, sx, sy, sz };
- }
-}
-
-// sort the compressed indices into morton order
-const sortSplats = (splats: Splat[], indices: CompressedIndex[]) => {
- // https://fgiesen.wordpress.com/2009/12/13/decoding-morton-codes/
- const encodeMorton3 = (x: number, y: number, z: number) : number => {
- const Part1By2 = (x: number) => {
- x &= 0x000003ff;
- x = (x ^ (x << 16)) & 0xff0000ff;
- x = (x ^ (x << 8)) & 0x0300f00f;
- x = (x ^ (x << 4)) & 0x030c30c3;
- x = (x ^ (x << 2)) & 0x09249249;
- return x;
- };
-
- return (Part1By2(z) << 2) + (Part1By2(y) << 1) + Part1By2(x);
- };
-
- let minx: number;
- let miny: number;
- let minz: number;
- let maxx: number;
- let maxy: number;
- let maxz: number;
-
- // calculate scene extents across all splats (using sort centers, because they're in world space)
- for (let i = 0; i < splats.length; ++i) {
- const splat = splats[i];
- const splatData = splat.splatData;
- const state = splatData.getProp('state') as Uint8Array;
- const { centers } = splat.entity.gsplat.instance.sorter;
-
- for (let i = 0; i < splatData.numSplats; ++i) {
- if ((state[i] & State.deleted) === 0) {
- const x = centers[i * 3 + 0];
- const y = centers[i * 3 + 1];
- const z = centers[i * 3 + 2];
-
- if (minx === undefined) {
- minx = maxx = x;
- miny = maxy = y;
- minz = maxz = z;
- } else {
- if (x < minx) minx = x; else if (x > maxx) maxx = x;
- if (y < miny) miny = y; else if (y > maxy) maxy = y;
- if (z < minz) minz = z; else if (z > maxz) maxz = z;
- }
- }
- }
- }
-
- const xlen = maxx - minx;
- const ylen = maxy - miny;
- const zlen = maxz - minz;
-
- const morton = new Uint32Array(indices.length);
- let idx = 0;
- for (let i = 0; i < splats.length; ++i) {
- const splat = splats[i];
- const splatData = splat.splatData;
- const state = splatData.getProp('state') as Uint8Array;
- const { centers } = splat.entity.gsplat.instance.sorter;
-
- for (let i = 0; i < splatData.numSplats; ++i) {
- if ((state[i] & State.deleted) === 0) {
- const x = centers[i * 3 + 0];
- const y = centers[i * 3 + 1];
- const z = centers[i * 3 + 2];
-
- const ix = Math.floor(1024 * (x - minx) / xlen);
- const iy = Math.floor(1024 * (y - miny) / ylen);
- const iz = Math.floor(1024 * (z - minz) / zlen);
-
- morton[idx++] = encodeMorton3(ix, iy, iz);
- }
- }
- }
-
- // order splats by morton code
- indices.sort((a, b) => morton[a.globalIndex] - morton[b.globalIndex]);
-};
-
-const convertPlyCompressed = (splats: Splat[]) => {
- const chunkProps = [
- 'min_x', 'min_y', 'min_z',
- 'max_x', 'max_y', 'max_z',
- 'min_scale_x', 'min_scale_y',
- 'min_scale_z', 'max_scale_x',
- 'max_scale_y', 'max_scale_z'
- ];
-
- const vertexProps = [
- 'packed_position',
- 'packed_rotation',
- 'packed_scale',
- 'packed_color'
- ];
-
- // create a list of indices spanning all splats
- const indices: CompressedIndex[] = splats.reduce((indices, splat, splatIndex) => {
- const splatData = splat.splatData;
- const state = splatData.getProp('state') as Uint8Array;
- for (let i = 0; i < splatData.numSplats; ++i) {
- if ((state[i] & State.deleted) === 0) {
- indices.push({
- splatIndex,
- i,
- globalIndex: indices.length
- });
- }
- }
- return indices;
- }, []);
-
- if (indices.length === 0) {
- console.error('nothing to export');
- return;
- }
-
- const numSplats = indices.length;
- const numChunks = Math.ceil(numSplats / 256);
-
- const headerText = [
- [
- `ply`,
- `format binary_little_endian 1.0`,
- `comment ${generatedByString}`,
- `element chunk ${numChunks}`
- ],
- chunkProps.map(p => `property float ${p}`),
- [
- `element vertex ${numSplats}`
- ],
- vertexProps.map(p => `property uint ${p}`),
- [
- `end_header\n`
- ]
- ].flat().join('\n');
-
- const header = (new TextEncoder()).encode(headerText);
- const result = new Uint8Array(header.byteLength + numChunks * chunkProps.length * 4 + numSplats * vertexProps.length * 4);
- const dataView = new DataView(result.buffer);
-
- result.set(header);
-
- const chunkOffset = header.byteLength;
- const vertexOffset = chunkOffset + numChunks * 12 * 4;
-
- // sort splats into some kind of order
- sortSplats(splats, indices);
-
- const transformCaches = splats.map((splat) => new SplatTransformCache(splat));
- const chunk = new Chunk();
- const singleSplat = new SingleSplat();
-
- for (let i = 0; i < numChunks; ++i) {
- const num = Math.min(numSplats, (i + 1) * 256) - i * 256;
- for (let j = 0; j < num; ++j) {
- const index = indices[i * 256 + j];
-
- // read splat
- singleSplat.read(splats, index);
-
- // transform
- const t = transformCaches[index.splatIndex];
- singleSplat.transform(t.getMat(index.i), t.getRot(index.i), t.getScale(index.i));
-
- // set
- chunk.set(j, singleSplat);
- }
-
- const result = chunk.pack();
-
- // write chunk data
- dataView.setFloat32(chunkOffset + i * 12 * 4 + 0, result.px.min, true);
- dataView.setFloat32(chunkOffset + i * 12 * 4 + 4, result.py.min, true);
- dataView.setFloat32(chunkOffset + i * 12 * 4 + 8, result.pz.min, true);
- dataView.setFloat32(chunkOffset + i * 12 * 4 + 12, result.px.max, true);
- dataView.setFloat32(chunkOffset + i * 12 * 4 + 16, result.py.max, true);
- dataView.setFloat32(chunkOffset + i * 12 * 4 + 20, result.pz.max, true);
-
- dataView.setFloat32(chunkOffset + i * 12 * 4 + 24, result.sx.min, true);
- dataView.setFloat32(chunkOffset + i * 12 * 4 + 28, result.sy.min, true);
- dataView.setFloat32(chunkOffset + i * 12 * 4 + 32, result.sz.min, true);
- dataView.setFloat32(chunkOffset + i * 12 * 4 + 36, result.sx.max, true);
- dataView.setFloat32(chunkOffset + i * 12 * 4 + 40, result.sy.max, true);
- dataView.setFloat32(chunkOffset + i * 12 * 4 + 44, result.sz.max, true);
-
- // write splat data
- const offset = vertexOffset + i * 256 * 4 * 4;
- const chunkSplats = Math.min(numSplats, (i + 1) * 256) - i * 256;
- for (let j = 0; j < chunkSplats; ++j) {
- dataView.setUint32(offset + j * 4 * 4 + 0, chunk.position[j], true);
- dataView.setUint32(offset + j * 4 * 4 + 4, chunk.rotation[j], true);
- dataView.setUint32(offset + j * 4 * 4 + 8, chunk.scale[j], true);
- dataView.setUint32(offset + j * 4 * 4 + 12, chunk.color[j], true);
- }
- }
-
- return result;
-};
-
-const convertSplat = (splats: Splat[]) => {
- const totalSplats = countTotalSplats(splats);
-
- // position.xyz: float32, scale.xyz: float32, color.rgba: uint8, quaternion.ijkl: uint8
- const result = new Uint8Array(totalSplats * 32);
- const dataView = new DataView(result.buffer);
-
- let idx = 0;
-
- for (let e = 0; e < splats.length; ++e) {
- const splat = splats[e];
- const splatData = splat.splatData;
- const transformCache = new SplatTransformCache(splat);
-
- // count the number of non-deleted splats
- const x = splatData.getProp('x');
- const y = splatData.getProp('y');
- const z = splatData.getProp('z');
- const opacity = splatData.getProp('opacity');
- const rot_0 = splatData.getProp('rot_0');
- const rot_1 = splatData.getProp('rot_1');
- const rot_2 = splatData.getProp('rot_2');
- const rot_3 = splatData.getProp('rot_3');
- const f_dc_0 = splatData.getProp('f_dc_0');
- const f_dc_1 = splatData.getProp('f_dc_1');
- const f_dc_2 = splatData.getProp('f_dc_2');
- const scale_0 = splatData.getProp('scale_0');
- const scale_1 = splatData.getProp('scale_1');
- const scale_2 = splatData.getProp('scale_2');
-
- const state = splatData.getProp('state') as Uint8Array;
-
- const clamp = (x: number) => Math.max(0, Math.min(255, x));
-
- for (let i = 0; i < splatData.numSplats; ++i) {
- if ((state[i] & State.deleted) === State.deleted) {
- continue;
- }
-
- const off = idx++ * 32;
-
- const mat = transformCache.getMat(i);
- const scale = transformCache.getScale(i);
- const quat = transformCache.getRot(i);
-
- v.set(x[i], y[i], z[i]);
- mat.transformPoint(v, v);
- dataView.setFloat32(off + 0, v.x, true);
- dataView.setFloat32(off + 4, v.y, true);
- dataView.setFloat32(off + 8, v.z, true);
-
- dataView.setFloat32(off + 12, Math.exp(scale_0[i]) * scale.x, true);
- dataView.setFloat32(off + 16, Math.exp(scale_1[i]) * scale.x, true);
- dataView.setFloat32(off + 20, Math.exp(scale_2[i]) * scale.x, true);
-
- const SH_C0 = 0.28209479177387814;
- dataView.setUint8(off + 24, clamp((0.5 + SH_C0 * f_dc_0[i]) * 255));
- dataView.setUint8(off + 25, clamp((0.5 + SH_C0 * f_dc_1[i]) * 255));
- dataView.setUint8(off + 26, clamp((0.5 + SH_C0 * f_dc_2[i]) * 255));
- dataView.setUint8(off + 27, clamp((1 / (1 + Math.exp(-opacity[i]))) * 255));
-
- q.set(rot_1[i], rot_2[i], rot_3[i], rot_0[i]).mul2(quat, q).normalize();
- dataView.setUint8(off + 28, clamp(q.w * 128 + 128));
- dataView.setUint8(off + 29, clamp(q.x * 128 + 128));
- dataView.setUint8(off + 30, clamp(q.y * 128 + 128));
- dataView.setUint8(off + 31, clamp(q.z * 128 + 128));
- }
- }
-
- return result;
-};
-
-export { convertPly, convertPlyCompressed, convertSplat };
diff --git a/mirror-2/splat/src/splat-overlay.ts b/mirror-2/splat/src/splat-overlay.ts
deleted file mode 100644
index c82e9886..00000000
--- a/mirror-2/splat/src/splat-overlay.ts
+++ /dev/null
@@ -1,118 +0,0 @@
-import {
- createShaderFromCode,
- BLEND_NORMAL,
- BUFFER_STATIC,
- PRIMITIVE_POINTS,
- SEMANTIC_POSITION,
- Material,
- Mesh,
- MeshInstance,
- TYPE_UINT32,
- VertexBuffer,
- VertexFormat,
-} from 'playcanvas';
-import { Splat } from './splat';
-import { ElementType, Element } from './element';
-import { vertexShader, fragmentShader } from './shaders/splat-overlay-shader';
-
-class SplatOverlay extends Element {
- meshInstance: MeshInstance;
-
- constructor() {
- super(ElementType.debug);
- }
-
- add() {
- const scene = this.scene;
- const device = scene.graphicsDevice;
-
- const shader = createShaderFromCode(device, vertexShader, fragmentShader, `splatOverlayShader`, {
- vertex_id: SEMANTIC_POSITION
- });
-
- const material = new Material();
- material.name = 'splatOverlayMaterial';
- material.blendType = BLEND_NORMAL;
- material.shader = shader;
-
- const mesh = new Mesh(device);
-
- const meshInstance = new MeshInstance(mesh, material, null);
-
- const events = this.scene.events;
-
- const update = (splat: Splat) => {
- if (!splat) {
- meshInstance.node = null;
- return;
- }
-
- const splatData = splat.splatData;
-
- const vertexFormat = new VertexFormat(device, [{
- semantic: SEMANTIC_POSITION,
- components: 1,
- type: TYPE_UINT32,
- asInt: true
- }]);
-
- // TODO: make use of Splat's mapping instead of rendering all splats
- const vertexData = new Uint32Array(splatData.numSplats);
- for (let i = 0; i < splatData.numSplats; ++i) {
- vertexData[i] = i;
- }
-
- const vertexBuffer = new VertexBuffer(device, vertexFormat, splatData.numSplats, {
- usage: BUFFER_STATIC,
- data: vertexData
- });
-
- if (mesh.vertexBuffer) {
- mesh.vertexBuffer.destroy();
- mesh.vertexBuffer = null;
- }
-
- mesh.vertexBuffer = vertexBuffer;
- mesh.primitive[0] = {
- type: PRIMITIVE_POINTS,
- base: 0,
- count: splatData.numSplats,
- };
-
- material.setParameter('splatState', splat.stateTexture);
- material.setParameter('splatPosition', splat.entity.gsplat.instance.splat.transformATexture);
- material.setParameter('splatTransform', splat.transformTexture);
- material.setParameter('transformPalette', splat.transformPalette.texture);
- material.setParameter('texParams', [splat.stateTexture.width, splat.stateTexture.height]);
- material.update();
-
- meshInstance.node = splat.entity;
- };
-
- events.on('selection.changed', (selection: Splat) => {
- update(selection);
- });
-
- this.meshInstance = meshInstance;
- }
-
- destroy() {
- this.meshInstance.material.destroy();
- this.meshInstance.destroy();
- }
-
- onPreRender() {
- const events = this.scene.events;
- const splatSize = events.invoke('camera.splatSize');
-
- if (this.meshInstance.node &&
- splatSize > 0 &&
- events.invoke('camera.overlay') &&
- events.invoke('camera.mode') === 'centers') {
- this.meshInstance.material.setParameter('splatSize', splatSize * window.devicePixelRatio);
- this.scene.app.drawMeshInstance(this.meshInstance);
- }
- }
-}
-
-export { SplatOverlay };
diff --git a/mirror-2/splat/src/splat-state.ts b/mirror-2/splat/src/splat-state.ts
deleted file mode 100644
index b319f960..00000000
--- a/mirror-2/splat/src/splat-state.ts
+++ /dev/null
@@ -1,7 +0,0 @@
-enum State {
- selected = 1,
- hidden = 2,
- deleted = 4
-}
-
-export { State };
diff --git a/mirror-2/splat/src/splat.ts b/mirror-2/splat/src/splat.ts
deleted file mode 100644
index 3e54be3b..00000000
--- a/mirror-2/splat/src/splat.ts
+++ /dev/null
@@ -1,396 +0,0 @@
-import {
- ADDRESS_CLAMP_TO_EDGE,
- FILTER_NEAREST,
- PIXELFORMAT_L8,
- PIXELFORMAT_R16U,
- Asset,
- BoundingBox,
- Color,
- Entity,
- GSplatData,
- GSplatResource,
- Mat4,
- Quat,
- Texture,
- Vec3
-} from 'playcanvas';
-import { Element, ElementType } from "./element";
-import { Serializer } from "./serializer";
-import { State } from './splat-state';
-import { vertexShader, fragmentShader } from './shaders/splat-shader';
-import { TransformPalette } from './transform-palette';
-
-const vec = new Vec3();
-const veca = new Vec3();
-const vecb = new Vec3();
-
-const boundingPoints =
- [-1, 1].map((x) => {
- return [-1, 1].map((y) => {
- return [-1, 1].map((z) => {
- return [
- new Vec3(x, y, z), new Vec3(x * 0.75, y, z),
- new Vec3(x, y, z), new Vec3(x, y * 0.75, z),
- new Vec3(x, y, z), new Vec3(x, y, z * 0.75)
- ];
- });
- });
- }).flat(3);
-
-class Splat extends Element {
- asset: Asset;
- splatData: GSplatData;
- numSplats = 0;
- numDeleted = 0;
- numHidden = 0;
- numSelected = 0;
- entity: Entity;
- changedCounter = 0;
- stateTexture: Texture;
- transformTexture: Texture;
- selectionBoundStorage: BoundingBox;
- localBoundStorage: BoundingBox;
- worldBoundStorage: BoundingBox;
- selectionBoundDirty = true;
- localBoundDirty = true;
- worldBoundDirty = true;
- _visible = true;
- transformPalette: TransformPalette;
-
- selectionAlpha = 1;
-
- rebuildMaterial: (bands: number) => void;
-
- constructor(asset: Asset) {
- super(ElementType.splat);
-
- const splatResource = asset.resource as GSplatResource;
- const splatData = splatResource.splatData;
-
- // get material options object for a shader that renders with the given number of bands
- const getMaterialOptions = (bands: number) => {
- return {
- vertex: vertexShader,
- fragment: fragmentShader,
- defines: ['USE_SH1', 'USE_SH2', 'USE_SH3'].splice(0, bands)
- };
- };
-
- this.asset = asset;
- this.splatData = splatData;
- this.numSplats = splatData.numSplats;
- this.entity = splatResource.instantiate(getMaterialOptions(0));
-
- const instance = this.entity.gsplat.instance;
-
- // added per-splat state channel
- // bit 1: selected
- // bit 2: deleted
- // bit 3: hidden
- this.splatData.addProp('state', new Uint8Array(this.splatData.numSplats));
-
- // per-splat transform matrix
- this.splatData.addProp('transform', new Uint16Array(this.splatData.numSplats));
-
- const { width, height } = instance.splat.colorTexture;
-
- // pack spherical harmonic data
- const createTexture = (name: string, format: number) => {
- return new Texture(splatResource.device, {
- name: name,
- width: width,
- height: height,
- format: format,
- mipmaps: false,
- minFilter: FILTER_NEAREST,
- magFilter: FILTER_NEAREST,
- addressU: ADDRESS_CLAMP_TO_EDGE,
- addressV: ADDRESS_CLAMP_TO_EDGE
- });
- };
-
- // create the state texture
- this.stateTexture = createTexture('splatState', PIXELFORMAT_L8);
- this.transformTexture = createTexture('splatTransform', PIXELFORMAT_R16U);
-
- // create the transform palette
- this.transformPalette = new TransformPalette(splatResource.device);
-
- this.rebuildMaterial = (bands: number) => {
- // @ts-ignore
- instance.createMaterial(getMaterialOptions(instance.splat.hasSH ? bands : 0));
-
- const material = instance.material;
- material.setParameter('splatState', this.stateTexture);
- material.setParameter('splatTransform', this.transformTexture);
- material.setParameter('transformPalette', this.transformPalette.texture);
- material.update();
- };
-
- this.selectionBoundStorage = new BoundingBox();
- this.localBoundStorage = instance.splat.aabb;
- this.worldBoundStorage = instance.meshInstance._aabb;
-
- instance.meshInstance._updateAabb = false;
-
- // when sort changes, re-render the scene
- instance.sorter.on('updated', () => {
- this.changedCounter++;
- });
- }
-
- destroy() {
- super.destroy();
- this.entity.destroy();
- this.asset.registry.remove(this.asset);
- this.asset.unload();
- }
-
- updateState(changedState = State.selected) {
- const state = this.splatData.getProp('state') as Uint8Array;
-
- // write state data to gpu texture
- const data = this.stateTexture.lock();
- data.set(state);
- this.stateTexture.unlock();
-
- let numSelected = 0;
- let numHidden = 0;
- let numDeleted = 0;
-
- for (let i = 0; i < state.length; ++i) {
- const s = state[i];
- if (s & State.deleted) {
- numDeleted++;
- } else if (s & State.hidden) {
- numHidden++;
- } else if (s & State.selected) {
- numSelected++;
- }
- }
-
- this.numSplats = state.length - numDeleted;
- this.numHidden = numHidden;
- this.numSelected = numSelected;
- this.numDeleted = numDeleted;
-
- this.makeSelectionBoundDirty();
-
- // handle splats being added or removed
- if (changedState & State.deleted) {
- this.updateSorting();
- }
-
- this.scene.forceRender = true;
- this.scene.events.fire('splat.stateChanged', this);
- }
-
- updatePositions() {
- const data = this.scene.dataProcessor.calcPositions(this);
-
- // update the splat centers which are used for render-time sorting
- const state = this.splatData.getProp('state') as Uint8Array;
- const { sorter } = this.entity.gsplat.instance;
- const { centers } = sorter;
- for (let i = 0; i < this.splatData.numSplats; ++i) {
- if (state[i] === State.selected) {
- centers[i * 3 + 0] = data[i * 4];
- centers[i * 3 + 1] = data[i * 4 + 1];
- centers[i * 3 + 2] = data[i * 4 + 2];
- }
- }
-
- this.updateSorting();
-
- this.scene.forceRender = true;
- this.scene.events.fire('splat.positionsChanged', this);
- }
-
- updateSorting() {
- const state = this.splatData.getProp('state') as Uint8Array;
-
- this.makeLocalBoundDirty();
-
- let mapping;
-
- // create a sorter mapping to remove deleted splats
- if (this.numSplats !== state.length) {
- mapping = new Uint32Array(this.numSplats);
- let idx = 0;
- for (let i = 0; i < state.length; ++i) {
- if ((state[i] & State.deleted) === 0) {
- mapping[idx++] = i;
- }
- }
- }
-
- // update sorting instance
- this.entity.gsplat.instance.sorter.setMapping(mapping);
- }
-
- get worldTransform() {
- return this.entity.getWorldTransform();
- }
-
- get filename() {
- return this.asset.file.filename;
- }
-
- calcSplatWorldPosition(splatId: number, result: Vec3) {
- if (splatId >= this.splatData.numSplats) {
- return false;
- }
-
- // use centers data, which are updated when edits occur
- const { sorter } = this.entity.gsplat.instance;
- const { centers } = sorter;
-
- result.set(
- centers[splatId * 3 + 0],
- centers[splatId * 3 + 1],
- centers[splatId * 3 + 2]
- );
-
- this.worldTransform.transformPoint(result, result);
-
- return true;
- }
-
- add() {
- // add the entity to the scene
- this.scene.contentRoot.addChild(this.entity);
-
- this.makeSelectionBoundDirty();
-
- this.scene.events.on('view.bands', this.rebuildMaterial, this);
- this.rebuildMaterial(this.scene.events.invoke('view.bands'));
- }
-
- remove() {
- this.scene.events.off('view.bands', this.rebuildMaterial, this);
-
- this.scene.contentRoot.removeChild(this.entity);
- this.scene.boundDirty = true;
- }
-
- serialize(serializer: Serializer) {
- serializer.packa(this.entity.getWorldTransform().data);
- serializer.pack(this.changedCounter);
- serializer.pack(this.visible);
- }
-
- onPreRender() {
- const events = this.scene.events;
- const selected = events.invoke('selection') === this;
- const cameraMode = events.invoke('camera.mode');
- const cameraOverlay = events.invoke('camera.overlay');
-
- // configure rings rendering
- const material = this.entity.gsplat.instance.material;
- material.setParameter('ringSize', (selected && cameraOverlay && cameraMode === 'rings') ? 0.04 : 0);
- material.setParameter('selectionAlpha', this.selectionAlpha);
-
- if (this.visible && selected) {
- // render bounding box
- if (events.invoke('camera.bound')) {
- const bound = this.localBound;
- const scale = new Mat4().setTRS(bound.center, Quat.IDENTITY, bound.halfExtents);
- scale.mul2(this.entity.getWorldTransform(), scale);
-
- for (let i = 0; i < boundingPoints.length / 2; i++) {
- const a = boundingPoints[i * 2];
- const b = boundingPoints[i * 2 + 1];
- scale.transformPoint(a, veca);
- scale.transformPoint(b, vecb);
-
- this.scene.app.drawLine(veca, vecb, Color.WHITE, true, this.scene.debugLayer);
- }
- }
- }
-
- this.entity.enabled = this.visible;
- }
-
- focalPoint() {
- return this.asset.resource?.getFocalPoint?.();
- }
-
- move(position?: Vec3, rotation?: Quat, scale?: Vec3) {
- const entity = this.entity;
- if (position) {
- entity.setLocalPosition(position);
- }
- if (rotation) {
- entity.setLocalRotation(rotation);
- }
- if (scale) {
- entity.setLocalScale(scale);
- }
-
- this.makeWorldBoundDirty();
-
- this.scene.events.fire('splat.moved', this);
- }
-
- makeSelectionBoundDirty() {
- this.selectionBoundDirty = true;
- this.makeLocalBoundDirty();
- }
-
- makeLocalBoundDirty() {
- this.localBoundDirty = true;
- this.makeWorldBoundDirty();
- }
-
- makeWorldBoundDirty() {
- this.worldBoundDirty = true;
- this.scene.boundDirty = true;
- }
-
- // get the selection bound
- get selectionBound() {
- const selectionBound = this.selectionBoundStorage;
- if (this.selectionBoundDirty) {
- this.scene.dataProcessor.calcBound(this, selectionBound, true);
- this.selectionBoundDirty = false;
- }
- return selectionBound;
- }
-
- // get local space bound
- get localBound() {
- const localBound = this.localBoundStorage;
- if (this.localBoundDirty) {
- this.scene.dataProcessor.calcBound(this, localBound, false);
- this.localBoundDirty = false;
- this.entity.getWorldTransform().transformPoint(localBound.center, vec);
- }
- return localBound;
- }
-
- // get world space bound
- get worldBound() {
- const worldBound = this.worldBoundStorage;
- if (this.worldBoundDirty) {
- // calculate meshinstance aabb (transformed local bound)
- worldBound.setFromTransformedAabb(this.localBound, this.entity.getWorldTransform());
-
- // flag scene bound as dirty
- this.worldBoundDirty = false;
- }
- return worldBound;
- }
-
- get visible() {
- return this._visible;
- }
-
- set visible(value: boolean) {
- if (value !== this.visible) {
- this._visible = value;
- this.scene.events.fire('splat.visibility', this);
- }
- }
-}
-
-export { Splat };
diff --git a/mirror-2/splat/src/splats-transform-handler.ts b/mirror-2/splat/src/splats-transform-handler.ts
deleted file mode 100644
index af3f16c1..00000000
--- a/mirror-2/splat/src/splats-transform-handler.ts
+++ /dev/null
@@ -1,180 +0,0 @@
-import { Mat4, Vec3 } from 'playcanvas';
-import { Events } from './events';
-import { Splat } from './splat';
-import { Transform } from './transform';
-import { PlacePivotOp, SplatsTransformOp, MultiOp } from './edit-ops';
-import { TransformHandler } from './transform-handler';
-import { Pivot } from './pivot';
-import { State } from './splat-state';
-
-const mat = new Mat4();
-const mat2 = new Mat4();
-const vec = new Vec3();
-const transform = new Transform();
-
-class SplatsTransformHandler implements TransformHandler {
- events: Events;
- splat: Splat;
- pivotStart = new Transform();
- localToPivot = new Mat4();
- worldToLocal = new Mat4();
-
- transform = new Mat4();
- paletteMap = new Map();
-
- constructor(events: Events) {
- this.events = events;
-
- events.on('pivot.started', (pivot: Pivot) => {
- if (this.splat) {
- this.start();
- }
- });
-
- events.on('pivot.moved', (pivot: Pivot) => {
- if (this.splat) {
- this.update(pivot.transform);
- }
- });
-
- events.on('pivot.ended', (pivot: Pivot) => {
- if (this.splat) {
- this.end();
- }
- });
-
- events.on('selection.changed', (splat) => {
- if (this.splat && splat === this.splat) {
- this.placePivot();
- }
- });
-
- events.on('camera.focalPointPicked', (details: { splat: Splat, position: Vec3 }) => {
- if (this.splat) {
- const pivot = events.invoke('pivot') as Pivot;
- const oldt = pivot.transform.clone();
- const newt = new Transform(details.position, pivot.transform.rotation, pivot.transform.scale);
- const op = new PlacePivotOp({ pivot, oldt, newt });
- events.fire('edit.add', op);
- }
- });
- }
-
- placePivot() {
- const { splat } = this;
- const { entity } = splat;
-
- // place the pivot at the center of the selected splats
- entity.getLocalTransform().transformPoint(splat.selectionBound.center, vec);
- transform.set(vec, entity.getLocalRotation(), entity.getLocalScale());
- this.events.fire('pivot.place', transform);
- }
-
- activate() {
- this.splat = this.events.invoke('selection') as Splat;
- if (this.splat) {
- this.placePivot();
- }
- }
-
- deactivate() {
- this.splat = null;
- }
-
- start() {
- const pivot = this.events.invoke('pivot') as Pivot;
- const { transform } = pivot;
- const { splat } = this;
- const { transformPalette } = splat;
-
- mat.setTRS(transform.position, transform.rotation, transform.scale);
-
- // calculate local -> pivot transform
- this.localToPivot.invert(mat);
- this.localToPivot.mul2(this.localToPivot, splat.entity.getLocalTransform());
-
- // calculate the world -> local transform
- this.worldToLocal.invert(splat.entity.getLocalTransform());
-
- this.pivotStart.copy(transform);
-
- // allocate a new transform for the current selection
- const state = splat.splatData.getProp('state') as Uint8Array;
- const indices = splat.transformTexture.lock() as Uint16Array;
-
- const { paletteMap } = this;
- paletteMap.clear();
-
- for (let i = 0; i < state.length; ++i) {
- if (state[i] === State.selected) {
- const oldIdx = indices[i];
- let newIdx;
- if (!paletteMap.has(oldIdx)) {
- newIdx = transformPalette.alloc();
- paletteMap.set(oldIdx, newIdx);
- } else {
- newIdx = paletteMap.get(oldIdx);
- }
-
- indices[i] = newIdx;
- }
- }
-
- splat.transformTexture.unlock();
-
- // initialize transforms
- this.paletteMap.forEach((newIdx, oldIdx) => {
- transformPalette.getTransform(oldIdx, mat);
- transformPalette.setTransform(newIdx, mat);
- });
-
- splat.selectionAlpha = 0;
- }
-
- update(transform: Transform) {
- // calculate updated new pivot -> world transform
- mat.setTRS(transform.position, transform.rotation, transform.scale);
- mat.mul2(mat, this.localToPivot); // local -> world
- mat.mul2(this.worldToLocal, mat); // world -> local
-
- this.transform.copy(mat);
-
- // update the transform palette
- const { transformPalette } = this.splat;
- this.paletteMap.forEach((newIdx, oldIdx) => {
- transformPalette.getTransform(oldIdx, mat2);
- mat2.mul2(mat, mat2);
- transformPalette.setTransform(newIdx, mat2);
- });
-
- this.splat.makeSelectionBoundDirty();
- }
-
- end() {
- const { splat, transform, paletteMap } = this;
-
- // TODO: consider moving this to update() function above so splats are sorted correctly
- // for render during drag (which is slower).
- splat.updatePositions();
- splat.selectionAlpha = 1;
-
- // create op for splat transform
- const top = new SplatsTransformOp({
- splat,
- transform: transform.clone(),
- paletteMap: new Map(paletteMap)
- });
-
-
- // create op for pivot placement
- const pivot = this.events.invoke('pivot') as Pivot;
- const oldt = this.pivotStart.clone();
- const newt = pivot.transform.clone();
- const pop = new PlacePivotOp({ pivot, newt, oldt });
-
- // add the editop without applying it
- this.events.fire('edit.add', new MultiOp([top, pop]), true);
- }
-}
-
-export { SplatsTransformHandler };
diff --git a/mirror-2/splat/src/svg/arrow.svg b/mirror-2/splat/src/svg/arrow.svg
deleted file mode 100644
index e5d5943f..00000000
--- a/mirror-2/splat/src/svg/arrow.svg
+++ /dev/null
@@ -1,3 +0,0 @@
-
diff --git a/mirror-2/splat/src/svg/centers.svg b/mirror-2/splat/src/svg/centers.svg
deleted file mode 100644
index 24832679..00000000
--- a/mirror-2/splat/src/svg/centers.svg
+++ /dev/null
@@ -1,3 +0,0 @@
-
\ No newline at end of file
diff --git a/mirror-2/splat/src/svg/collapse.svg b/mirror-2/splat/src/svg/collapse.svg
deleted file mode 100644
index cfc6b0c1..00000000
--- a/mirror-2/splat/src/svg/collapse.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-
-
\ No newline at end of file
diff --git a/mirror-2/splat/src/svg/crop.svg b/mirror-2/splat/src/svg/crop.svg
deleted file mode 100644
index 3934ec0e..00000000
--- a/mirror-2/splat/src/svg/crop.svg
+++ /dev/null
@@ -1,3 +0,0 @@
-
diff --git a/mirror-2/splat/src/svg/delete.svg b/mirror-2/splat/src/svg/delete.svg
deleted file mode 100644
index e714a56e..00000000
--- a/mirror-2/splat/src/svg/delete.svg
+++ /dev/null
@@ -1,3 +0,0 @@
-
diff --git a/mirror-2/splat/src/svg/export.svg b/mirror-2/splat/src/svg/export.svg
deleted file mode 100644
index ab855903..00000000
--- a/mirror-2/splat/src/svg/export.svg
+++ /dev/null
@@ -1,3 +0,0 @@
-
diff --git a/mirror-2/splat/src/svg/frame-selection.svg b/mirror-2/splat/src/svg/frame-selection.svg
deleted file mode 100644
index 5fc498b1..00000000
--- a/mirror-2/splat/src/svg/frame-selection.svg
+++ /dev/null
@@ -1,4 +0,0 @@
-
diff --git a/mirror-2/splat/src/svg/hidden.svg b/mirror-2/splat/src/svg/hidden.svg
deleted file mode 100644
index 724a1ef2..00000000
--- a/mirror-2/splat/src/svg/hidden.svg
+++ /dev/null
@@ -1,3 +0,0 @@
-
diff --git a/mirror-2/splat/src/svg/import.svg b/mirror-2/splat/src/svg/import.svg
deleted file mode 100644
index 65e856c7..00000000
--- a/mirror-2/splat/src/svg/import.svg
+++ /dev/null
@@ -1,3 +0,0 @@
-
diff --git a/mirror-2/splat/src/svg/logo.svg b/mirror-2/splat/src/svg/logo.svg
deleted file mode 100644
index 5c36a9d1..00000000
--- a/mirror-2/splat/src/svg/logo.svg
+++ /dev/null
@@ -1,13 +0,0 @@
-
diff --git a/mirror-2/splat/src/svg/new.svg b/mirror-2/splat/src/svg/new.svg
deleted file mode 100644
index 70dca81e..00000000
--- a/mirror-2/splat/src/svg/new.svg
+++ /dev/null
@@ -1,3 +0,0 @@
-
diff --git a/mirror-2/splat/src/svg/open.svg b/mirror-2/splat/src/svg/open.svg
deleted file mode 100644
index c0f0348e..00000000
--- a/mirror-2/splat/src/svg/open.svg
+++ /dev/null
@@ -1,3 +0,0 @@
-
diff --git a/mirror-2/splat/src/svg/playcanvas-logo.svg b/mirror-2/splat/src/svg/playcanvas-logo.svg
deleted file mode 100644
index 75eb3134..00000000
--- a/mirror-2/splat/src/svg/playcanvas-logo.svg
+++ /dev/null
@@ -1,13 +0,0 @@
-
\ No newline at end of file
diff --git a/mirror-2/splat/src/svg/redo.svg b/mirror-2/splat/src/svg/redo.svg
deleted file mode 100644
index f279aea9..00000000
--- a/mirror-2/splat/src/svg/redo.svg
+++ /dev/null
@@ -1,3 +0,0 @@
-
diff --git a/mirror-2/splat/src/svg/rings.svg b/mirror-2/splat/src/svg/rings.svg
deleted file mode 100644
index 3a10b18e..00000000
--- a/mirror-2/splat/src/svg/rings.svg
+++ /dev/null
@@ -1,4 +0,0 @@
-
\ No newline at end of file
diff --git a/mirror-2/splat/src/svg/save.svg b/mirror-2/splat/src/svg/save.svg
deleted file mode 100644
index 0cb0b093..00000000
--- a/mirror-2/splat/src/svg/save.svg
+++ /dev/null
@@ -1,3 +0,0 @@
-
diff --git a/mirror-2/splat/src/svg/select-all.svg b/mirror-2/splat/src/svg/select-all.svg
deleted file mode 100644
index 787e67f1..00000000
--- a/mirror-2/splat/src/svg/select-all.svg
+++ /dev/null
@@ -1,3 +0,0 @@
-
diff --git a/mirror-2/splat/src/svg/select-brush.svg b/mirror-2/splat/src/svg/select-brush.svg
deleted file mode 100644
index 051a28aa..00000000
--- a/mirror-2/splat/src/svg/select-brush.svg
+++ /dev/null
@@ -1,4 +0,0 @@
-
diff --git a/mirror-2/splat/src/svg/select-inverse.svg b/mirror-2/splat/src/svg/select-inverse.svg
deleted file mode 100644
index 681f6aac..00000000
--- a/mirror-2/splat/src/svg/select-inverse.svg
+++ /dev/null
@@ -1,3 +0,0 @@
-
diff --git a/mirror-2/splat/src/svg/select-lasso.svg b/mirror-2/splat/src/svg/select-lasso.svg
deleted file mode 100644
index 1a5a9090..00000000
--- a/mirror-2/splat/src/svg/select-lasso.svg
+++ /dev/null
@@ -1,4 +0,0 @@
-
diff --git a/mirror-2/splat/src/svg/select-lock.svg b/mirror-2/splat/src/svg/select-lock.svg
deleted file mode 100644
index 946b8338..00000000
--- a/mirror-2/splat/src/svg/select-lock.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-
diff --git a/mirror-2/splat/src/svg/select-none.svg b/mirror-2/splat/src/svg/select-none.svg
deleted file mode 100644
index 768f5226..00000000
--- a/mirror-2/splat/src/svg/select-none.svg
+++ /dev/null
@@ -1,3 +0,0 @@
-
diff --git a/mirror-2/splat/src/svg/select-picker.svg b/mirror-2/splat/src/svg/select-picker.svg
deleted file mode 100644
index 3fd94424..00000000
--- a/mirror-2/splat/src/svg/select-picker.svg
+++ /dev/null
@@ -1,11 +0,0 @@
-
diff --git a/mirror-2/splat/src/svg/select-sphere.svg b/mirror-2/splat/src/svg/select-sphere.svg
deleted file mode 100644
index 0a511e90..00000000
--- a/mirror-2/splat/src/svg/select-sphere.svg
+++ /dev/null
@@ -1,3 +0,0 @@
-
diff --git a/mirror-2/splat/src/svg/select-unlock.svg b/mirror-2/splat/src/svg/select-unlock.svg
deleted file mode 100644
index d0f2ab75..00000000
--- a/mirror-2/splat/src/svg/select-unlock.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-
diff --git a/mirror-2/splat/src/svg/show-hide-splats.svg b/mirror-2/splat/src/svg/show-hide-splats.svg
deleted file mode 100644
index aaa2f035..00000000
--- a/mirror-2/splat/src/svg/show-hide-splats.svg
+++ /dev/null
@@ -1,4 +0,0 @@
-
diff --git a/mirror-2/splat/src/svg/shown.svg b/mirror-2/splat/src/svg/shown.svg
deleted file mode 100644
index 705db259..00000000
--- a/mirror-2/splat/src/svg/shown.svg
+++ /dev/null
@@ -1,4 +0,0 @@
-
diff --git a/mirror-2/splat/src/svg/undo.svg b/mirror-2/splat/src/svg/undo.svg
deleted file mode 100644
index 6ac62489..00000000
--- a/mirror-2/splat/src/svg/undo.svg
+++ /dev/null
@@ -1,3 +0,0 @@
-
diff --git a/mirror-2/splat/src/sw.ts b/mirror-2/splat/src/sw.ts
deleted file mode 100644
index 489c1385..00000000
--- a/mirror-2/splat/src/sw.ts
+++ /dev/null
@@ -1,50 +0,0 @@
-import { version as appVersion } from '../package.json';
-
-// export default null
-declare let self: ServiceWorkerGlobalScope;
-
-const cacheName = `superSplat-v${appVersion}`;
-
-const cacheUrls = [
- './',
- './index.html',
- './index.css',
- './index.js',
- './manifest.json',
- './static/icons/logo-192.png',
- './static/icons/logo-512.png',
- './static/images/screenshot-narrow.jpg',
- './static/images/screenshot-wide.jpg'
-];
-
-self.addEventListener('install', (event) => {
- console.log(`installing v${appVersion}`);
-
- // create cache for current version
- event.waitUntil(
- caches.open(cacheName)
- .then((cache) => {
- cache.addAll(cacheUrls);
- })
- );
-});
-
-self.addEventListener('activate', () => {
- console.log(`activating v${appVersion}`);
-
- // delete the old caches once this one is activated
- caches.keys().then((names) => {
- for (const name of names) {
- if (name !== cacheName) {
- caches.delete(name);
- }
- }
- });
-});
-
-self.addEventListener('fetch', (event) => {
- event.respondWith(
- caches.match(event.request)
- .then((response) => response ?? fetch(event.request))
- );
-});
diff --git a/mirror-2/splat/src/tools/brush-selection.ts b/mirror-2/splat/src/tools/brush-selection.ts
deleted file mode 100644
index 07a0c6e1..00000000
--- a/mirror-2/splat/src/tools/brush-selection.ts
+++ /dev/null
@@ -1,148 +0,0 @@
-import { Events } from "../events";
-
-class BrushSelection {
- activate: () => void;
- deactivate: () => void;
-
- constructor(events: Events, parent: HTMLElement) {
- let radius = 40;
-
- // create svg
- const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
- svg.id = 'brush-select-svg';
- svg.classList.add('select-svg');
-
- // create circle element
- const circle = document.createElementNS(svg.namespaceURI, 'circle') as SVGCircleElement;
- circle.setAttribute('r', radius.toString());
- circle.setAttribute('fill', 'rgba(255, 102, 0, 0.2)');
- circle.setAttribute('stroke', '#f60');
- circle.setAttribute('stroke-width', '1');
- circle.setAttribute('stroke-dasharray', '5, 5');
-
- // create canvas
- const selectCanvas = document.createElement('canvas');
- selectCanvas.id = 'brush-select-canvas';
-
- const context = selectCanvas.getContext('2d');
- context.globalCompositeOperation = 'copy';
-
- const prev = { x: 0, y: 0 };
- let dragId: number | undefined;
-
- const update = (e: PointerEvent) => {
- const x = e.offsetX;
- const y = e.offsetY;
-
- circle.setAttribute('cx', x.toString());
- circle.setAttribute('cy', y.toString());
-
- if (dragId !== undefined) {
- context.beginPath();
- context.strokeStyle = '#f60';
- context.lineCap = 'round';
- context.lineWidth = radius * 2;
- context.moveTo(prev.x, prev.y);
- context.lineTo(x, y);
- context.stroke();
-
- prev.x = x;
- prev.y = y;
- }
- };
-
- const pointerdown = (e: PointerEvent) => {
- if (dragId === undefined && (e.pointerType === 'mouse' ? e.button === 0 : e.isPrimary)) {
- e.preventDefault();
- e.stopPropagation();
-
- dragId = e.pointerId;
- parent.setPointerCapture(dragId);
-
- // initialize canvas
- if (selectCanvas.width !== parent.clientWidth || selectCanvas.height !== parent.clientHeight) {
- selectCanvas.width = parent.clientWidth;
- selectCanvas.height = parent.clientHeight;
- }
-
- // clear canvas
- context.clearRect(0, 0, selectCanvas.width, selectCanvas.height);
-
- // display it
- selectCanvas.style.display = 'inline';
-
- prev.x = e.offsetX;
- prev.y = e.offsetY;
-
- update(e);
- }
- };
-
- const pointermove = (e: PointerEvent) => {
- if (dragId !== undefined) {
- e.preventDefault();
- e.stopPropagation();
- }
-
- update(e);
- };
-
- const dragEnd = () => {
- parent.releasePointerCapture(dragId);
- dragId = undefined;
- selectCanvas.style.display = 'none';
- };
-
- const pointerup = (e: PointerEvent) => {
- if (e.pointerId === dragId) {
- e.preventDefault();
- e.stopPropagation();
-
- dragEnd();
-
- events.fire(
- 'select.byMask',
- e.shiftKey ? 'add' : (e.ctrlKey ? 'remove' : 'set'),
- selectCanvas,
- context
- );
- }
- };
-
- this.activate = () => {
- svg.style.display = 'inline';
- parent.style.display = 'block';
- parent.addEventListener('pointerdown', pointerdown);
- parent.addEventListener('pointermove', pointermove);
- parent.addEventListener('pointerup', pointerup);
- };
-
- this.deactivate = () => {
- // cancel active operation
- if (dragId !== undefined) {
- dragEnd();
- }
- svg.style.display = 'none';
- parent.style.display = 'none';
- parent.removeEventListener('pointerdown', pointerdown);
- parent.removeEventListener('pointermove', pointermove);
- parent.removeEventListener('pointerup', pointerup);
- };
-
- events.on('tool.brushSelection.smaller', () => {
- radius = Math.max(1, radius / 1.05);
- circle.setAttribute('r', radius.toString());
- });
-
- events.on('tool.brushSelection.bigger', () => {
- radius = Math.min(500, radius * 1.05);
- circle.setAttribute('r', radius.toString());
- });
-
- svg.appendChild(circle);
- parent.appendChild(svg);
- parent.appendChild(selectCanvas);
- }
-}
-
-export { BrushSelection };
diff --git a/mirror-2/splat/src/tools/move-tool.ts b/mirror-2/splat/src/tools/move-tool.ts
deleted file mode 100644
index 234fd8c8..00000000
--- a/mirror-2/splat/src/tools/move-tool.ts
+++ /dev/null
@@ -1,15 +0,0 @@
-import { TranslateGizmo } from 'playcanvas';
-import { TransformTool } from './transform-tool';
-import { Events } from '../events';
-import { EditHistory } from '../edit-history';
-import { Scene } from '../scene';
-
-class MoveTool extends TransformTool {
- constructor(events: Events, scene: Scene) {
- const gizmo = new TranslateGizmo(scene.app, scene.camera.entity.camera, scene.gizmoLayer);
-
- super(gizmo, events, scene);
- }
-}
-
-export { MoveTool };
diff --git a/mirror-2/splat/src/tools/rect-selection.ts b/mirror-2/splat/src/tools/rect-selection.ts
deleted file mode 100644
index e3e0f32e..00000000
--- a/mirror-2/splat/src/tools/rect-selection.ts
+++ /dev/null
@@ -1,129 +0,0 @@
-import { Events } from '../events';
-
-class RectSelection {
-
- activate: () => void;
- deactivate: () => void;
-
- constructor(events: Events, parent: HTMLElement) {
- const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
- svg.id = 'rect-select-svg';
- svg.classList.add('select-svg');
-
- // create rect element
- const rect = document.createElementNS(svg.namespaceURI, 'rect') as SVGRectElement;
- rect.setAttribute('fill', 'none');
- rect.setAttribute('stroke', '#f60');
- rect.setAttribute('stroke-width', '1');
- rect.setAttribute('stroke-dasharray', '5, 5');
-
- const start = { x: 0, y: 0 };
- const end = { x: 0, y: 0 };
- let dragId: number | undefined;
- let dragMoved = false;
-
- const updateRect = () => {
- const x = Math.min(start.x, end.x);
- const y = Math.min(start.y, end.y);
- const width = Math.abs(start.x - end.x);
- const height = Math.abs(start.y - end.y);
-
- rect.setAttribute('x', x.toString());
- rect.setAttribute('y', y.toString());
- rect.setAttribute('width', width.toString());
- rect.setAttribute('height', height.toString());
- };
-
- const pointerdown = (e: PointerEvent) => {
- if (dragId === undefined && (e.pointerType === 'mouse' ? e.button === 0 : e.isPrimary)) {
- e.preventDefault();
- e.stopPropagation();
-
- dragId = e.pointerId;
- dragMoved = false;
- parent.setPointerCapture(dragId);
-
- start.x = end.x = e.offsetX;
- start.y = end.y = e.offsetY;
-
- updateRect();
-
- svg.style.display = 'inline';
- }
- };
-
- const pointermove = (e: PointerEvent) => {
- if (e.pointerId === dragId) {
- e.preventDefault();
- e.stopPropagation();
-
- dragMoved = true;
- end.x = e.offsetX;
- end.y = e.offsetY;
-
- updateRect();
- }
- };
-
- const dragEnd = () => {
- parent.releasePointerCapture(dragId);
- dragId = undefined;
- svg.style.display = 'none';
- };
-
- const pointerup = (e: PointerEvent) => {
- if (e.pointerId === dragId) {
- e.preventDefault();
- e.stopPropagation();
-
- const w = parent.clientWidth;
- const h = parent.clientHeight;
-
- dragEnd();
-
- if (dragMoved) {
- // rect select
- events.fire(
- 'select.rect',
- e.shiftKey ? 'add' : (e.ctrlKey ? 'remove' : 'set'), {
- start: { x: Math.min(start.x, end.x) / w, y: Math.min(start.y, end.y) / h },
- end: { x: Math.max(start.x, end.x) / w, y: Math.max(start.y, end.y) / h },
- });
- } else {
- // pick
- events.fire(
- 'select.point',
- e.shiftKey ? 'add' : (e.ctrlKey ? 'remove' : 'set'),
- { x: e.offsetX / parent.clientWidth, y: e.offsetY / parent.clientHeight }
- );
- }
- }
- };
-
- this.activate = () => {
- parent.style.display = 'block';
- parent.addEventListener('pointerdown', pointerdown);
- parent.addEventListener('pointermove', pointermove);
- parent.addEventListener('pointerup', pointerup);
- };
-
- this.deactivate = () => {
- if (dragId !== undefined) {
- dragEnd();
- }
- parent.style.display = 'none';
- parent.removeEventListener('pointerdown', pointerdown);
- parent.removeEventListener('pointermove', pointermove);
- parent.removeEventListener('pointerup', pointerup);
- };
-
- parent.appendChild(svg);
- svg.appendChild(rect);
- }
-
- destroy() {
-
- }
-}
-
-export { RectSelection };
diff --git a/mirror-2/splat/src/tools/rotate-tool.ts b/mirror-2/splat/src/tools/rotate-tool.ts
deleted file mode 100644
index fc1eb040..00000000
--- a/mirror-2/splat/src/tools/rotate-tool.ts
+++ /dev/null
@@ -1,15 +0,0 @@
-import { RotateGizmo } from 'playcanvas';
-import { TransformTool } from './transform-tool';
-import { Events } from '../events';
-import { EditHistory } from '../edit-history';
-import { Scene } from '../scene';
-
-class RotateTool extends TransformTool {
- constructor(events: Events, scene: Scene) {
- const gizmo = new RotateGizmo(scene.app, scene.camera.entity.camera, scene.gizmoLayer);
-
- super(gizmo, events, scene);
- }
-}
-
-export { RotateTool };
diff --git a/mirror-2/splat/src/tools/scale-tool.ts b/mirror-2/splat/src/tools/scale-tool.ts
deleted file mode 100644
index 989f9056..00000000
--- a/mirror-2/splat/src/tools/scale-tool.ts
+++ /dev/null
@@ -1,20 +0,0 @@
-import { ScaleGizmo } from 'playcanvas';
-import { TransformTool } from './transform-tool';
-import { Events } from '../events';
-import { EditHistory } from '../edit-history';
-import { Scene } from '../scene';
-
-class ScaleTool extends TransformTool {
- constructor(events: Events, scene: Scene) {
- const gizmo = new ScaleGizmo(scene.app, scene.camera.entity.camera, scene.gizmoLayer);
-
- // disable everything except uniform scale
- ['x', 'y', 'z', 'yz', 'xz', 'xy'].forEach((axis) => {
- gizmo.enableShape(axis, false);
- });
-
- super(gizmo, events, scene);
- }
-}
-
-export { ScaleTool };
diff --git a/mirror-2/splat/src/tools/sphere-selection.ts b/mirror-2/splat/src/tools/sphere-selection.ts
deleted file mode 100644
index c91024dc..00000000
--- a/mirror-2/splat/src/tools/sphere-selection.ts
+++ /dev/null
@@ -1,131 +0,0 @@
-import { TranslateGizmo, Vec3 } from 'playcanvas'
-import { Button, Container, NumericInput } from '@playcanvas/pcui'
-import { Events } from '../events'
-import { Scene } from '../scene'
-import { SphereShape } from '../sphere-shape'
-import { Splat } from '../splat'
-
-class SphereSelection {
- activate: () => void
- deactivate: () => void
-
- active = false
-
- constructor(events: Events, scene: Scene, canvasContainer: Container) {
- const sphere = new SphereShape()
-
- const gizmo = new TranslateGizmo(
- scene.app,
- scene.camera.entity.camera,
- scene.gizmoLayer
- )
-
- gizmo.on('render:update', () => {
- scene.forceRender = true
- })
-
- gizmo.on('transform:move', () => {
- sphere.moved()
- })
-
- // ui
- const selectToolbar = new Container({
- id: 'select-toolbar',
- hidden: true
- })
-
- selectToolbar.dom.addEventListener('pointerdown', (e) => {
- e.stopPropagation()
- })
-
- const setButton = new Button({
- text: 'Set',
- class: 'select-toolbar-button'
- })
- const addButton = new Button({
- text: 'Add',
- class: 'select-toolbar-button'
- })
- const removeButton = new Button({
- text: 'Remove',
- class: 'select-toolbar-button'
- })
- const radius = new NumericInput({
- precision: 2,
- value: sphere.radius,
- placeholder: 'Radius',
- width: 80,
- min: 0.01
- })
-
- selectToolbar.append(setButton)
- selectToolbar.append(addButton)
- selectToolbar.append(removeButton)
- selectToolbar.append(radius)
-
- canvasContainer.append(selectToolbar)
-
- const apply = (op: 'set' | 'add' | 'remove') => {
- const p = sphere.pivot.getPosition()
- events.fire('select.bySphere', op, [p.x, p.y, p.z, sphere.radius])
- }
-
- setButton.dom.addEventListener('pointerdown', (e) => {
- e.stopPropagation()
- apply('set')
- })
- addButton.dom.addEventListener('pointerdown', (e) => {
- e.stopPropagation()
- apply('add')
- })
- removeButton.dom.addEventListener('pointerdown', (e) => {
- e.stopPropagation()
- apply('remove')
- })
- radius.on('change', () => {
- sphere.radius = radius.value
- })
-
- events.on(
- 'camera.focalPointPicked',
- (details: { splat: Splat; position: Vec3 }) => {
- if (this.active) {
- sphere.pivot.setPosition(details.position)
- gizmo.attach([sphere.pivot])
- }
- }
- )
-
- this.activate = () => {
- this.active = true
- scene.add(sphere)
- gizmo.attach([sphere.pivot])
- selectToolbar.hidden = false
-
- const canvas = document.getElementById('canvas')
- if (canvas) {
- const w = canvas.clientWidth
- const h = canvas.clientHeight
- gizmo.size = 1200 / Math.max(w, h)
-
- // FIXME:
- // this is a temporary workaround to undo gizmo's own auto scaling.
- // once gizmo's autoscaling code is removed, this line can go too.
- // @ts-ignore
- gizmo._deviceStartSize = Math.min(
- scene.app.graphicsDevice.width,
- scene.app.graphicsDevice.height
- )
- }
- }
-
- this.deactivate = () => {
- selectToolbar.hidden = true
- gizmo.detach()
- scene.remove(sphere)
- this.active = false
- }
- }
-}
-
-export { SphereSelection }
diff --git a/mirror-2/splat/src/tools/tool-manager.ts b/mirror-2/splat/src/tools/tool-manager.ts
deleted file mode 100644
index c9ba00dd..00000000
--- a/mirror-2/splat/src/tools/tool-manager.ts
+++ /dev/null
@@ -1,87 +0,0 @@
-import { Events } from '../events';
-
-interface Tool {
- activate: () => void;
- deactivate: () => void;
-}
-
-class ToolManager {
- tools = new Map();
- events: Events;
- active: string | null = null;
-
- constructor(events: Events) {
- this.events = events;
-
- this.events.on('tool.deactivate', () => {
- this.activate(null);
- });
-
- this.events.function('tool.active', () => {
- return this.active;
- });
-
- let coordSpace: 'local' | 'world' = 'world';
-
- const setCoordSpace = (space: 'local' | 'world') => {
- if (space !== coordSpace) {
- coordSpace = space;
- events.fire('tool.coordSpace', coordSpace);
- }
- };
-
- events.function('tool.coordSpace', () => {
- return coordSpace;
- });
-
- events.on('tool.setCoordSpace', (value: 'local' | 'world') => {
- setCoordSpace(value);
- });
-
- events.on('tool.toggleCoordSpace', () => {
- setCoordSpace(coordSpace === 'local' ? 'world' : 'local');
- });
- }
-
- register(name: string, tool: Tool) {
- this.tools.set(name, tool);
-
- this.events.on(`tool.${name}`, () => {
- this.activate(name);
- });
- }
-
- get(toolName: string) {
- return (toolName && this.tools.get(toolName)) ?? null;
- }
-
- activate(toolName: string | null) {
- if (toolName === this.active) {
- // re-activating the currently active tool deactivates it
- if (toolName) {
- this.activate(null);
- }
- } else {
- // deactive old tool
- if (this.active) {
- const tool = this.tools.get(this.active);
- tool.deactivate();
- this.events.fire(`tool.${this.active}.deactivated`);
- this.events.fire('tool.deactivated', this.active);
- }
-
- this.active = toolName;
-
- // activate the new
- if (this.active) {
- const tool = this.tools.get(this.active);
- tool.activate();
- }
-
- this.events.fire(`tool.${toolName}.activated`);
- this.events.fire('tool.activated', toolName);
- }
- }
-}
-
-export { ToolManager };
diff --git a/mirror-2/splat/src/tools/transform-tool.ts b/mirror-2/splat/src/tools/transform-tool.ts
deleted file mode 100644
index f5bb308e..00000000
--- a/mirror-2/splat/src/tools/transform-tool.ts
+++ /dev/null
@@ -1,106 +0,0 @@
-import { Entity, GraphicsDevice, TransformGizmo } from 'playcanvas';
-import { Scene } from '../scene';
-import { Events } from '../events';
-import { Pivot } from '../pivot';
-
-// patch gizmo to be more opaque
-const patchGizmoMaterials = (gizmo: TransformGizmo) => {
- // @ts-ignore
- ['x', 'y', 'z', 'xyz', 'face'].forEach(name => { gizmo._meshColors.axis[name].a = 0.8; });
- // @ts-ignore
- gizmo._meshColors.disabled.a = 0.8;
-};
-
-// set the gizmo size to remain a constant size in screen space.
-// called in response to changes in canvas size
-const updateGizmoSize = (gizmo: TransformGizmo, device: GraphicsDevice) => {
- const canvas = document.getElementById('canvas');
- if (canvas) {
- const w = canvas.clientWidth;
- const h = canvas.clientHeight;
- gizmo.size = 1200 / Math.max(w, h);
-
- // FIXME:
- // this is a temporary workaround to undo gizmo's own auto scaling.
- // once gizmo's autoscaling code is removed, this line can go too.
- // @ts-ignore
- gizmo._deviceStartSize = Math.min(device.width, device.height);
- }
-};
-
-class TransformTool {
- activate: () => void;
- deactivate: () => void;
-
- constructor(gizmo: TransformGizmo, events: Events, scene: Scene) {
- let pivot: Pivot;
- let active = false;
-
- // create the transform pivot
- const pivotEntity = new Entity('gizmoPivot');
- scene.app.root.addChild(pivotEntity);
-
- gizmo.on('render:update', () => {
- scene.forceRender = true;
- });
-
- gizmo.on('transform:start', () => {
- pivot.start();
- });
-
- gizmo.on('transform:move', () => {
- pivot.moveTRS(pivotEntity.getLocalPosition(), pivotEntity.getLocalRotation(), pivotEntity.getLocalScale());
- });
-
- gizmo.on('transform:end', () => {
- pivot.end();
- });
-
- // reattach the gizmo to the pivot
- const reattach = () => {
- if (!active || !events.invoke('selection')) {
- gizmo.detach();
- } else {
- pivot = events.invoke('pivot') as Pivot;
- pivotEntity.setLocalPosition(pivot.transform.position);
- pivotEntity.setLocalRotation(pivot.transform.rotation);
- pivotEntity.setLocalScale(pivot.transform.scale);
- gizmo.attach([pivotEntity]);
- }
- };
-
- events.on('tool.coordSpace', (coordSpace: string) => {
- gizmo.coordSpace = coordSpace;
- scene.forceRender = true;
- });
-
- events.on('pivot.placed', reattach);
- events.on('pivot.moved', reattach);
- events.on('selection.changed', reattach);
-
- events.on('camera.resize', () => {
- scene.events.on('camera.resize', () => updateGizmoSize(gizmo, scene.graphicsDevice));
- });
-
- this.activate = () => {
- active = true;
- reattach();
- };
-
- this.deactivate = () => {
- active = false;
- reattach();
- };
-
- // update gizmo size
- updateGizmoSize(gizmo, scene.graphicsDevice);
-
- // patch gizmo materials (until we have API to do this)
- patchGizmoMaterials(gizmo);
-
- // initialize coodinate space
- gizmo.coordSpace = events.invoke('tool.coordSpace');
- }
-}
-
-export { TransformTool };
diff --git a/mirror-2/splat/src/transform-handler.ts b/mirror-2/splat/src/transform-handler.ts
deleted file mode 100644
index 7b5e77d1..00000000
--- a/mirror-2/splat/src/transform-handler.ts
+++ /dev/null
@@ -1,47 +0,0 @@
-import { Events } from './events';
-import { EntityTransformHandler } from './entity-transform-handler';
-import { SplatsTransformHandler } from './splats-transform-handler';
-import { registerPivotEvents } from './pivot';
-import { Splat } from './splat';
-
-interface TransformHandler {
- activate: () => void;
- deactivate: () => void;
-}
-
-const registerTransformHandlerEvents = (events: Events) => {
- let transformHandler: TransformHandler = null;
-
- const setTransformHandler = (handler: TransformHandler) => {
- if (transformHandler) {
- transformHandler.deactivate();
- }
- transformHandler = handler;
- if (transformHandler) {
- transformHandler.activate();
- }
- };
-
- // bind transform target when selection changes
- const entityTransformHandler = new EntityTransformHandler(events);
- const splatsTransformHandler = new SplatsTransformHandler(events);
-
- const update = (splat: Splat) => {
- if (!splat) {
- setTransformHandler(null);
- } else {
- if (splat.numSelected > 0) {
- setTransformHandler(splatsTransformHandler);
- } else {
- setTransformHandler(entityTransformHandler);
- }
- }
- };
-
- events.on('selection.changed', update);
- events.on('splat.stateChanged', update);
-
- registerPivotEvents(events);
-};
-
-export { registerTransformHandlerEvents, TransformHandler };
diff --git a/mirror-2/splat/src/transform-palette.ts b/mirror-2/splat/src/transform-palette.ts
deleted file mode 100644
index 4168c746..00000000
--- a/mirror-2/splat/src/transform-palette.ts
+++ /dev/null
@@ -1,104 +0,0 @@
-import {
- ADDRESS_CLAMP_TO_EDGE,
- PIXELFORMAT_RGBA32F,
- GraphicsDevice,
- Mat4,
- Texture
-} from 'playcanvas';
-
-// mapping from Mat4 to transposed 3x4 matrix
-const idx = [
- 0, 4, 8, 12,
- 1, 5, 9, 13,
- 2, 6, 10, 14
-];
-
-// texture data stores 512 matrices per row: 512 * 3 * 4 (rgba) floats
-const width = 512 * 3;
-
-// wraps a palette of transform data. transforms are stored as 3x4 (non-perspective)
-// matrices
-class TransformPalette {
- getTransform: (index: number, transform: Mat4) => void;
- setTransform: (index: number, transform: Mat4) => void;
- alloc: (num?: number) => number;
- free: (num?: number) => void;
- texture: Texture;
-
- constructor(device: GraphicsDevice, initialSize = 4096) {
- let texture: Texture;
- let data: Float32Array;
-
- // reallocate the storage texture and copy over old data
- const realloc = (width: number, height: number) => {
- const newTexture = new Texture(device, {
- name: 'transformPalette',
- width,
- height,
- format: PIXELFORMAT_RGBA32F,
- mipmaps: false,
- addressU: ADDRESS_CLAMP_TO_EDGE,
- addressV: ADDRESS_CLAMP_TO_EDGE
- });
-
- const newData = newTexture.lock() as Float32Array;
- newTexture.unlock();
-
- // copy over data if this is a realloc
- if (texture) {
- newData.set(data);
-
- texture.destroy();
- }
-
- texture = newTexture;
- data = newData;
- };
-
- this.getTransform = (index: number, transform: Mat4) => {
- const dst = transform.data;
- for (let i = 0; i < 12; ++i) {
- dst[idx[i]] = data[index * 12 + i];
- }
- };
-
- this.setTransform = (index: number, transform: Mat4) => {
- const src = transform.data;
- for (let i = 0; i < 12; ++i) {
- data[index * 12 + i] = src[idx[i]];
- }
-
- texture.upload();
- };
-
- // index of the next available matrix. index 0 is identity.
- let nextIdx = 1;
-
- // allocate one or more matrices from the palette, returns the index of the first matrix
- this.alloc = (num = 1) => {
- const result = nextIdx;
-
- while (nextIdx + num > data.length / 12) {
- realloc(width, texture.height * 2);
- }
-
- nextIdx += num;
-
- return result;
- };
-
- this.free = (num = 1) => {
- nextIdx -= num;
- };
-
- Object.defineProperty(this, "texture", { get() { return texture; } });
-
- // allocate initial storage
- realloc(width, Math.ceil(initialSize / (width / 3)));
-
- // initialize first matrix to identity
- this.setTransform(0, Mat4.IDENTITY);
- }
-}
-
-export { TransformPalette };
diff --git a/mirror-2/splat/src/transform.ts b/mirror-2/splat/src/transform.ts
deleted file mode 100644
index 0bf7e5f0..00000000
--- a/mirror-2/splat/src/transform.ts
+++ /dev/null
@@ -1,59 +0,0 @@
-import { Quat, Vec3 } from 'playcanvas';
-
-class Transform {
- position = new Vec3();
- rotation = new Quat();
- scale = new Vec3(1, 1, 1);
-
- constructor(position?: Vec3, rotation?: Quat, scale?: Vec3) {
- this.set(position, rotation, scale);
- }
-
- set(position?: Vec3, rotation?: Quat, scale?: Vec3) {
- if (position) {
- this.position.copy(position);
- }
- if (rotation) {
- this.rotation.copy(rotation);
- }
- if (scale) {
- this.scale.copy(scale);
- }
- }
-
- copy(transform: Transform) {
- this.position.copy(transform.position);
- this.rotation.copy(transform.rotation);
- this.scale.copy(transform.scale);
- }
-
- clone() {
- return new Transform(this.position.clone(), this.rotation.clone(), this.scale.clone());
- }
-
- equals(transform: Transform) {
- return this.position.equals(transform.position) &&
- this.rotation.equals(transform.rotation) &&
- this.scale.equals(transform.scale);
- }
-
- equalsApprox(transform: Transform, epsilon = 1e-6) {
- return this.position.equalsApprox(transform.position, epsilon) &&
- this.rotation.equalsApprox(transform.rotation, epsilon) &&
- this.scale.equalsApprox(transform.scale, epsilon);
- }
-
- equalsTRS(position: Vec3, rotation: Quat, scale: Vec3) {
- return this.position.equals(position) &&
- this.rotation.equals(rotation) &&
- this.scale.equals(scale);
- }
-
- equalsApproxTRS(position: Vec3, rotation: Quat, scale: Vec3, epsilon = 1e-6) {
- return this.position.equalsApprox(position, epsilon) &&
- this.rotation.equalsApprox(rotation, epsilon) &&
- this.scale.equalsApprox(scale, epsilon);
- }
-}
-
-export { Transform };
diff --git a/mirror-2/splat/src/tween-value.ts b/mirror-2/splat/src/tween-value.ts
deleted file mode 100644
index 4ee805f7..00000000
--- a/mirror-2/splat/src/tween-value.ts
+++ /dev/null
@@ -1,75 +0,0 @@
-// possible interpolation functions
-const Interp = {
- sinosidal: (n: number) => Math.sin((n * Math.PI) / 2.0),
- quadratic: (n: number) => n * (2 - n),
- quartic: (n: number) => 1 - --n * n * n * n,
- quintic: (n: number) => Math.pow(n - 1, 5) + 1,
- vertebrae: (n: number) => -Math.pow((Math.cos(n * Math.PI) + 1) / 2, 2) + 1
-};
-
-class Ops {
- keys: string[];
-
- constructor(value: any) {
- this.keys = Object.keys(value);
- }
-
- clone(obj: any) {
- const result: any = {};
- this.keys.forEach((key: string) => {
- result[key] = obj[key];
- });
- return result;
- }
-
- copy(target: any, source: any) {
- this.keys.forEach((key: string) => {
- target[key] = source[key];
- });
- }
-
- lerp(target: any, a: any, b: any, t: number) {
- this.keys.forEach((key: string) => {
- target[key] = a[key] + t * (b[key] - a[key]);
- });
- }
-}
-
-class TweenValue {
- ops: Ops;
- value: any;
- source: any;
- target: any;
- timer: number;
- transitionTime: number;
-
- constructor(value: any) {
- this.ops = new Ops(value);
- this.value = value;
- this.source = this.ops.clone(value);
- this.target = this.ops.clone(value);
- this.timer = 0;
- this.transitionTime = 0;
- }
-
- goto(target: any, transitionTime = 0.25) {
- if (transitionTime === 0) {
- this.ops.copy(this.value, target);
- }
- this.ops.copy(this.source, this.value);
- this.ops.copy(this.target, target);
- this.timer = 0;
- this.transitionTime = transitionTime;
- }
-
- update(deltaTime: number) {
- if (this.timer < this.transitionTime) {
- this.timer = Math.min(this.timer + deltaTime, this.transitionTime);
- this.ops.lerp(this.value, this.source, this.target, Interp.quintic(this.timer / this.transitionTime));
- } else {
- this.ops.copy(this.value, this.target);
- }
- }
-}
-
-export {TweenValue};
diff --git a/mirror-2/splat/src/ui/bottom-toolbar.scss b/mirror-2/splat/src/ui/bottom-toolbar.scss
deleted file mode 100644
index 4dbb3b63..00000000
--- a/mirror-2/splat/src/ui/bottom-toolbar.scss
+++ /dev/null
@@ -1,81 +0,0 @@
-#bottom-toolbar {
- position: absolute;
- left: 50%;
- bottom: 24px;
- height: 54px;
- transform: translate(-50%, 0);
- padding: 0px 8px;
- border-radius: 8px;
-
- background-color: $bcg-dark;
-
- display: flex;
- flex-direction: row;
- align-items: center;
-}
-
-.bottom-toolbar-button, .bottom-toolbar-tool, .bottom-toolbar-toggle {
- width: 38px;
- height: 38px;
- margin: 0px 1px;
- padding: 0px;
- border: 0px;
- border-radius: 2px;
-
- &::before {
- font-size: 16px !important;
- line-height: 100%;
- }
-
- svg {
- color: $clr-default;
- }
-}
-
-.bottom-toolbar-separator {
- width: 2px;
- height: 38px;
- margin: 0px 10px;
- background-color: $bcg-primary;
-}
-
-.bottom-toolbar-button {
- svg {
- color: $clr-default;
- }
-}
-
-.bottom-toolbar-tool {
- background-color: $bcg-primary;
-
- svg {
- color: $clr-default
- }
-
- &.active {
- color: $clr-active;
- background-color: $clr-hilight !important;
-
- svg {
- color: $clr-active;
- }
- }
-
- &.disabled {
- background-color: $bcg-dark;
-
- svg {
- color: $clr-disabled;
- }
- }
-}
-
-.bottom-toolbar-toggle.active {
- &::before {
- color: $clr-hilight;
- }
-
- svg {
- color: $clr-hilight;
- }
-}
diff --git a/mirror-2/splat/src/ui/bottom-toolbar.ts b/mirror-2/splat/src/ui/bottom-toolbar.ts
deleted file mode 100644
index 86b4ab2c..00000000
--- a/mirror-2/splat/src/ui/bottom-toolbar.ts
+++ /dev/null
@@ -1,176 +0,0 @@
-import { Button, Element, Container } from '@playcanvas/pcui'
-import { Events } from '../events'
-import { Tooltips } from './tooltips'
-import { localize } from './localization'
-
-import undoSvg from '../svg/undo.svg'
-import redoSvg from '../svg/redo.svg'
-import pickerSvg from '../svg/select-picker.svg'
-import brushSvg from '../svg/select-brush.svg'
-import sphereSvg from '../svg/select-sphere.svg'
-// import lassoSvg from '../svg/select-lasso.svg';
-// import cropSvg from '../svg/crop.svg';
-
-const createSvg = () => {
- const svgString = `
-
- `
- return new Element({
- dom: new DOMParser().parseFromString(svgString, 'image/svg+xml')
- .documentElement
- })
-}
-
-class BottomToolbar extends Container {
- constructor(events: Events, tooltips: Tooltips, args = {}) {
- args = {
- ...args,
- id: 'bottom-toolbar'
- }
-
- super(args)
-
- this.dom.addEventListener('pointerdown', (event) => {
- event.stopPropagation()
- })
-
- const undo = new Button({
- id: 'bottom-toolbar-undo',
- class: 'bottom-toolbar-button',
- enabled: false
- })
-
- const redo = new Button({
- id: 'bottom-toolbar-redo',
- class: 'bottom-toolbar-button',
- enabled: false
- })
-
- const picker = new Button({
- id: 'bottom-toolbar-picker',
- class: 'bottom-toolbar-tool'
- })
-
- const brush = new Button({
- id: 'bottom-toolbar-brush',
- class: 'bottom-toolbar-tool'
- })
-
- // const lasso = new Button({
- // id: 'bottom-toolbar-lasso',
- // class: ['bottom-toolbar-tool', 'disabled']
- // });
-
- const sphere = new Button({
- id: 'bottom-toolbar-sphere',
- class: 'bottom-toolbar-tool'
- })
-
- // const crop = new Button({
- // id: 'bottom-toolbar-crop',
- // class: ['bottom-toolbar-tool', 'disabled']
- // });
-
- const translate = new Button({
- id: 'bottom-toolbar-translate',
- class: 'bottom-toolbar-tool',
- icon: 'E111'
- })
-
- const rotate = new Button({
- id: 'bottom-toolbar-rotate',
- class: 'bottom-toolbar-tool',
- icon: 'E113'
- })
-
- const scale = new Button({
- id: 'bottom-toolbar-scale',
- class: 'bottom-toolbar-tool',
- icon: 'E112'
- })
-
- const coordSpace = new Button({
- id: 'bottom-toolbar-coord-space',
- class: 'bottom-toolbar-toggle',
- icon: 'E118'
- })
-
- // undo.dom.appendChild(createSvg(undoSvg))
- // redo.dom.appendChild(createSvg(redoSvg))
- // picker.dom.appendChild(createSvg(pickerSvg))
- // brush.dom.appendChild(createSvg(brushSvg))
- // sphere.dom.appendChild(createSvg(sphereSvg))
- // lasso.dom.appendChild(createSvg(lassoSvg));
- // crop.dom.appendChild(createSvg(cropSvg));
-
- this.append(undo)
- this.append(redo)
- this.append(new Element({ class: 'bottom-toolbar-separator' }))
- this.append(picker)
- this.append(brush)
- // this.append(lasso);
- this.append(new Element({ class: 'bottom-toolbar-separator' }))
- this.append(sphere)
- // this.append(crop);
- this.append(new Element({ class: 'bottom-toolbar-separator' }))
- this.append(translate)
- this.append(rotate)
- this.append(scale)
- this.append(coordSpace)
-
- undo.dom.addEventListener('click', () => events.fire('edit.undo'))
- redo.dom.addEventListener('click', () => events.fire('edit.redo'))
- brush.dom.addEventListener('click', () =>
- events.fire('tool.brushSelection')
- )
- picker.dom.addEventListener('click', () =>
- events.fire('tool.rectSelection')
- )
- sphere.dom.addEventListener('click', () =>
- events.fire('tool.sphereSelection')
- )
- translate.dom.addEventListener('click', () => events.fire('tool.move'))
- rotate.dom.addEventListener('click', () => events.fire('tool.rotate'))
- scale.dom.addEventListener('click', () => events.fire('tool.scale'))
- coordSpace.dom.addEventListener('click', () =>
- events.fire('tool.toggleCoordSpace')
- )
-
- events.on('edit.canUndo', (value: boolean) => {
- undo.enabled = value
- })
- events.on('edit.canRedo', (value: boolean) => {
- redo.enabled = value
- })
-
- events.on('tool.activated', (toolName: string) => {
- picker.class[toolName === 'rectSelection' ? 'add' : 'remove']('active')
- brush.class[toolName === 'brushSelection' ? 'add' : 'remove']('active')
- sphere.class[toolName === 'sphereSelection' ? 'add' : 'remove']('active')
- translate.class[toolName === 'move' ? 'add' : 'remove']('active')
- rotate.class[toolName === 'rotate' ? 'add' : 'remove']('active')
- scale.class[toolName === 'scale' ? 'add' : 'remove']('active')
- })
-
- events.on('tool.coordSpace', (space: 'local' | 'world') => {
- coordSpace.dom.classList[space === 'local' ? 'add' : 'remove']('active')
- })
-
- // register tooltips
- tooltips.register(undo, localize('tooltip.undo'))
- tooltips.register(redo, localize('tooltip.redo'))
- tooltips.register(picker, localize('tooltip.picker'))
- tooltips.register(brush, localize('tooltip.brush'))
- // tooltips.register(lasso, 'Lasso Select');
- tooltips.register(sphere, localize('tooltip.sphere'))
- // tooltips.register(crop, 'Crop');
- tooltips.register(translate, localize('tooltip.translate'))
- tooltips.register(rotate, localize('tooltip.rotate'))
- tooltips.register(scale, localize('tooltip.scale'))
- tooltips.register(coordSpace, localize('tooltip.local-space'))
- }
-}
-
-export { BottomToolbar }
diff --git a/mirror-2/splat/src/ui/color.ts b/mirror-2/splat/src/ui/color.ts
deleted file mode 100644
index b252026e..00000000
--- a/mirror-2/splat/src/ui/color.ts
+++ /dev/null
@@ -1,66 +0,0 @@
-
-const rgb2hsv = (rgb: { r: number, g: number, b: number }) => {
- const r = rgb.r;
- const g = rgb.g;
- const b = rgb.b;
- const v = Math.max(r, g, b);
- const diff = v - Math.min(r, g, b);
-
- const diffc = (c: number) => {
- return (v - c) / 6 / diff + 1 / 2;
- };
-
- let h, s;
-
- if (diff === 0) {
- h = s = 0;
- } else {
- s = diff / v;
- const rr = diffc(r);
- const gg = diffc(g);
- const bb = diffc(b);
-
- if (r === v) {
- h = bb - gg;
- } else if (g === v) {
- h = (1 / 3) + rr - bb;
- } else if (b === v) {
- h = (2 / 3) + gg - rr;
- }
- if (h < 0) {
- h += 1;
- } else if (h > 1) {
- h -= 1;
- }
- }
-
- return { h, s, v };
-};
-
-const hsv2rgb = (hsv: { h: number, s: number, v: number }) => {
- const h = hsv.h;
- const s = hsv.s;
- const v = hsv.v;
-
- const i = Math.floor(h * 6);
- const f = h * 6 - i;
- const p = v * (1 - s);
- const q = v * (1 - f * s);
- const t = v * (1 - (1 - f) * s);
-
- let r, g, b;
-
- switch (i % 6) {
- case 0: r = v; g = t; b = p; break;
- case 1: r = q; g = v; b = p; break;
- case 2: r = p; g = v; b = t; break;
- case 3: r = p; g = q; b = v; break;
- case 4: r = t; g = p; b = v; break;
- case 5: r = v; g = p; b = q; break;
- }
-
- return { r, g, b };
-};
-
-export { rgb2hsv, hsv2rgb };
-
diff --git a/mirror-2/splat/src/ui/data-panel.scss b/mirror-2/splat/src/ui/data-panel.scss
deleted file mode 100644
index 9b3cd60b..00000000
--- a/mirror-2/splat/src/ui/data-panel.scss
+++ /dev/null
@@ -1,74 +0,0 @@
-#data-panel {
- width: 100%;
- height: 320px;
-}
-
-#data-panel-popup-container {
- position: absolute;
- left: 50px;
- top: 50px;
-}
-
-#data-panel-popup-label {
- background-color: $bcg-dark;
- color: $text-primary;
-}
-
-#data-controls-container {
- width: 256px;
- flex-grow: 0;
- flex-shrink: 0;
- overflow-y: auto;
-}
-
-#data-controls {
- width: 100%;
-}
-
-.control-parent {
- width: 100%;
- display: flex;
- flex-direction: row;
- flex-grow: 1;
-}
-
-.control-label {
- width: 100px;
- flex-shrink: 0;
- flex-grow: 0;
- line-height: 32px;
- margin: 0px 6px 0px 6px;
-}
-
-.control-element {
- flex-shrink: 0;
- flex-grow: 0;
-}
-
-.control-element-expand {
- flex-grow: 1;
-}
-
-.control-element.pcui-boolean-input {
- margin-top: 10px;
-}
-
-#histogram-container {
- flex-grow: 1;
- flex-shrink: 1;
-}
-
-#histogram-canvas {
- image-rendering: pixelated;
-}
-
-#histogram-svg {
- pointer-events: none;
- position: absolute;
- width: 100%;
- height: 100%;
- top: 0;
- right: 0;
- bottom: 0;
- left: 0;
-}
diff --git a/mirror-2/splat/src/ui/data-panel.ts b/mirror-2/splat/src/ui/data-panel.ts
deleted file mode 100644
index f5e55d45..00000000
--- a/mirror-2/splat/src/ui/data-panel.ts
+++ /dev/null
@@ -1,396 +0,0 @@
-import {
- BooleanInput,
- Container,
- Label,
- Panel,
- SelectInput
-} from '@playcanvas/pcui'
-import { Events } from '../events'
-import { Splat } from '../splat'
-import { Histogram } from './histogram'
-import { State } from '../splat-state'
-import { localize } from './localization'
-import { rgb2hsv } from './color'
-
-const SH_C0 = 0.28209479177387814
-
-const identity = (v: number) => v
-const scaleFunc = (v: number) => Math.exp(v)
-const colorFunc = (v: number) => 0.5 + v * SH_C0
-const sigmoid = (v: number) => {
- if (v > 0) {
- return 1 / (1 + Math.exp(-v))
- }
-
- const t = Math.exp(v)
- return t / (1 + t)
-}
-
-const dataFuncs = {
- x: identity,
- y: identity,
- z: identity,
- scale_0: scaleFunc,
- scale_1: scaleFunc,
- scale_2: scaleFunc,
- f_dc_0: colorFunc,
- f_dc_1: colorFunc,
- f_dc_2: colorFunc,
- opacity: sigmoid
-}
-
-// build a separator label
-const sepLabel = (labelText: string) => {
- const container = new Container({
- class: 'control-parent',
- id: 'sep-container'
- })
-
- container.class.add('sep-container')
-
- const label = new Label({
- class: 'control-element-expand',
- text: labelText
- })
-
- container.append(label)
-
- return container
-}
-
-// build a data label
-const dataLabel = (parent: Container, labelText: string) => {
- const container = new Container({
- class: 'control-parent'
- })
-
- const label = new Label({
- class: 'control-label',
- text: labelText
- })
-
- const value = new Label({
- class: 'control-element-expand'
- })
-
- container.append(label)
- container.append(value)
-
- parent.append(container)
-
- return value
-}
-
-class DataPanel extends Panel {
- constructor(events: Events, args = {}) {
- args = {
- ...args,
- headerText: localize('data'),
- id: 'data-panel',
- resizable: 'top',
- resizeMax: 1000,
- collapsed: true,
- collapsible: true,
- collapseHorizontally: false,
- flex: true,
- flexDirection: 'row'
- }
-
- super(args)
-
- // build the data controls
- const controlsContainer = new Container({
- id: 'data-controls-container'
- })
-
- const controls = new Container({
- id: 'data-controls'
- })
-
- const dataSelector = new SelectInput({
- class: 'control-element-expand',
- defaultValue: 'surface-area',
- options: [
- { v: 'x', t: 'X' },
- { v: 'y', t: 'Y' },
- { v: 'z', t: 'Z' },
- { v: 'distance', t: localize('data.distance') },
- { v: 'volume', t: localize('data.volume') },
- { v: 'surface-area', t: localize('data.surface-area') },
- { v: 'scale_0', t: localize('data.scale-x') },
- { v: 'scale_1', t: localize('data.scale-y') },
- { v: 'scale_2', t: localize('data.scale-z') },
- { v: 'f_dc_0', t: localize('data.red') },
- { v: 'f_dc_1', t: localize('data.green') },
- { v: 'f_dc_2', t: localize('data.blue') },
- { v: 'opacity', t: localize('data.opacity') },
- { v: 'hue', t: localize('data.hue') },
- { v: 'saturation', t: localize('data.saturation') },
- { v: 'value', t: localize('data.value') }
- ]
- })
-
- const logScale = new Container({
- class: 'control-parent'
- })
-
- const logScaleLabel = new Label({
- class: 'control-label',
- text: localize('data.log-scale')
- })
-
- const logScaleValue = new BooleanInput({
- class: 'control-element',
- value: false
- })
-
- logScale.append(logScaleLabel)
- logScale.append(logScaleValue)
-
- controls.append(dataSelector)
- controls.append(logScale)
-
- controls.append(sepLabel(localize('data.totals')))
-
- const splatsValue = dataLabel(controls, localize('data.totals.splats'))
- const selectedValue = dataLabel(controls, localize('data.totals.selected'))
- const hiddenValue = dataLabel(controls, localize('data.totals.hidden'))
- const deletedValue = dataLabel(controls, localize('data.totals.deleted'))
-
- controlsContainer.append(controls)
-
- // build histogram
- const histogram = new Histogram(256, 128)
-
- const histogramContainer = new Container({
- id: 'histogram-container'
- })
-
- histogramContainer.dom.appendChild(histogram.canvas)
-
- this.content.append(controlsContainer)
- this.content.append(histogramContainer)
-
- // current splat
- let splat: Splat
-
- // returns a function which will interpret the splat data for purposes of
- // viewing it in the histogram.
- // the returned values will depend on the currently selected data type:
- // * some value functions return the raw splat data, like 'x'.
- // * other value functions must transform the data for histogram visualization
- // (for example 'scale_0', which must be exponentiated).
- // * still other values are calculated/derived from multiple values of splat
- // data like 'volume' and 'surface area'.
- const getValueFunc = () => {
- // @ts-ignore
- const dataFunc = dataFuncs[dataSelector.value]
- const data = splat.splatData.getProp(dataSelector.value)
-
- let func: (i: number) => number
- if (dataFunc && data) {
- func = (i) => dataFunc(data[i])
- } else {
- switch (dataSelector.value) {
- case 'volume': {
- const sx = splat.splatData.getProp('scale_0')
- const sy = splat.splatData.getProp('scale_1')
- const sz = splat.splatData.getProp('scale_2')
- func = (i) => scaleFunc(sx[i]) * scaleFunc(sy[i]) * scaleFunc(sz[i])
- break
- }
- case 'distance': {
- const x = splat.splatData.getProp('x')
- const y = splat.splatData.getProp('y')
- const z = splat.splatData.getProp('z')
- func = (i) => Math.sqrt(x[i] ** 2 + y[i] ** 2 + z[i] ** 2)
- break
- }
- case 'surface-area': {
- const sx = splat.splatData.getProp('scale_0')
- const sy = splat.splatData.getProp('scale_1')
- const sz = splat.splatData.getProp('scale_2')
- func = (i) =>
- scaleFunc(sx[i]) ** 2 +
- scaleFunc(sy[i]) ** 2 +
- scaleFunc(sz[i]) ** 2
- break
- }
- case 'hue': {
- const r = splat.splatData.getProp('f_dc_0')
- const g = splat.splatData.getProp('f_dc_1')
- const b = splat.splatData.getProp('f_dc_2')
- func = (i) =>
- rgb2hsv({
- r: colorFunc(r[i]),
- g: colorFunc(g[i]),
- b: colorFunc(b[i])
- }).h * 360
- break
- }
- case 'saturation': {
- const r = splat.splatData.getProp('f_dc_0')
- const g = splat.splatData.getProp('f_dc_1')
- const b = splat.splatData.getProp('f_dc_2')
- func = (i) =>
- rgb2hsv({
- r: colorFunc(r[i]),
- g: colorFunc(g[i]),
- b: colorFunc(b[i])
- }).s
- break
- }
- case 'value': {
- const r = splat.splatData.getProp('f_dc_0')
- const g = splat.splatData.getProp('f_dc_1')
- const b = splat.splatData.getProp('f_dc_2')
- func = (i) =>
- rgb2hsv({
- r: colorFunc(r[i]),
- g: colorFunc(g[i]),
- b: colorFunc(b[i])
- }).v
- break
- }
- default:
- func = (i) => undefined
- break
- }
- }
-
- return func
- }
-
- const updateHistogram = () => {
- if (!splat || this.collapsed) return
-
- const state = splat.splatData.getProp('state') as Uint8Array
- if (state) {
- splatsValue.text = (state.length - splat.numDeleted).toString()
- selectedValue.text = splat.numSelected.toString()
- hiddenValue.text = splat.numHidden.toString()
- deletedValue.text = splat.numDeleted.toString()
-
- // update histogram
- const func = getValueFunc()
-
- // update histogram
- histogram.update({
- count: state.length,
- valueFunc: (i) =>
- state[i] === 0 || state[i] === State.selected ? func(i) : undefined,
- selectedFunc: (i) => state[i] === State.selected,
- logScale: logScaleValue.value
- })
- }
- }
-
- this.on('expand', () => {
- updateHistogram()
- })
-
- events.on('splat.stateChanged', (splat_: Splat) => {
- splat = splat_
- updateHistogram()
- })
-
- events.on('selection.changed', (selection: Element) => {
- if (selection instanceof Splat) {
- splat = selection
- updateHistogram()
- }
- })
-
- events.on('dataPanel.toggle', () => {
- this.collapsed = !this.collapsed
- updateHistogram()
- })
-
- dataSelector.on('change', updateHistogram)
- logScaleValue.on('change', updateHistogram)
-
- const popupContainer = new Container({
- id: 'data-panel-popup-container',
- hidden: true
- })
-
- const popupLabel = new Label({
- id: 'data-panel-popup-label',
- text: '',
- unsafe: true
- })
-
- popupContainer.append(popupLabel)
- this.content.append(popupContainer)
-
- histogram.events.on('showOverlay', () => {
- popupContainer.hidden = false
- })
-
- histogram.events.on('hideOverlay', () => {
- popupContainer.hidden = true
- })
-
- histogram.events.on('updateOverlay', (info: any) => {
- popupContainer.style.left = `${info.x + 14}px`
- popupContainer.style.top = `${info.y}px`
-
- const binValue = info.value.toFixed(2)
- const count = info.selected + info.unselected
- const percentage = (info.total ? (count / info.total) * 100 : 0).toFixed(
- 2
- )
-
- popupLabel.text = `value: ${binValue} cnt: ${count} (${percentage}%) sel: ${info.selected}`
- })
-
- // highlight
- const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg')
- svg.setAttribute('id', 'histogram-svg')
-
- // create rect element
- const rect = document.createElementNS(
- svg.namespaceURI,
- 'rect'
- ) as SVGRectElement
- rect.setAttribute('id', 'highlight-rect')
- rect.setAttribute('fill', 'rgba(255, 102, 0, 0.2)')
- rect.setAttribute('stroke', '#f60')
- rect.setAttribute('stroke-width', '1')
- rect.setAttribute('stroke-dasharray', '5, 5')
-
- svg.appendChild(rect)
- histogramContainer.dom.appendChild(svg)
-
- histogram.events.on('highlight', (info: any) => {
- rect.setAttribute('x', info.x.toString())
- rect.setAttribute('y', info.y.toString())
- rect.setAttribute('width', info.width.toString())
- rect.setAttribute('height', info.height.toString())
-
- svg.style.display = 'inline'
- })
-
- histogram.events.on('select', (op: string, start: number, end: number) => {
- svg.style.display = 'none'
-
- const state = splat.splatData.getProp('state') as Uint8Array
- const selection = state.some((s) => s === State.selected)
- const func = getValueFunc()
-
- // perform selection
- events.fire('select.pred', op, (i: number) => {
- if (state[i] !== 0 && state[i] !== State.selected) {
- return false
- }
-
- // select all splats that fall in the given bucket range (inclusive)
- const value = func(i)
- const bucket = histogram.histogram.valueToBucket(value)
- return bucket >= start && bucket <= end
- })
- })
- }
-}
-
-export { DataPanel }
diff --git a/mirror-2/splat/src/ui/editor.ts b/mirror-2/splat/src/ui/editor.ts
deleted file mode 100644
index 23d8d990..00000000
--- a/mirror-2/splat/src/ui/editor.ts
+++ /dev/null
@@ -1,187 +0,0 @@
-import { Container, Label } from '@playcanvas/pcui'
-import { Mat4 } from 'playcanvas'
-import { DataPanel } from './data-panel'
-import { Events } from '../events'
-import { Popup, ShowOptions } from './popup'
-import { ViewCube } from './view-cube'
-import { Menu } from './menu'
-import { ScenePanel } from './scene-panel'
-import { ViewPanel } from './view-panel'
-import { BottomToolbar } from './bottom-toolbar'
-import { RightToolbar } from './right-toolbar'
-import { ModeToggle } from './mode-toggle'
-import { Tooltips } from './tooltips'
-import { ShortcutsPopup } from './shortcuts-popup'
-import { localizeInit } from './localization'
-
-import { version } from '../../package.json'
-import logo from './playcanvas-logo.png'
-
-class EditorUI {
- appContainer: Container
- topContainer: Container
- canvasContainer: Container
- toolsContainer: Container
- canvas: HTMLCanvasElement
- popup: Popup
-
- constructor(events: Events, remoteStorageMode: boolean) {
- localizeInit()
-
- // favicon
- const link = document.createElement('link')
- link.rel = 'icon'
- link.href = logo
- document.head.appendChild(link)
-
- // app
- const appContainer = new Container({
- id: 'app-container-new'
- })
-
- // editor
- const editorContainer = new Container({
- id: 'editor-container'
- })
-
- // tooltips container
- const tooltipsContainer = new Container({
- id: 'tooltips-container'
- })
-
- // top container
- const topContainer = new Container({
- id: 'top-container'
- })
-
- // canvas
- const canvas = document.createElement('canvas')
- canvas.id = 'canvas'
-
- // filename label
- const appLabel = new Label({
- id: 'app-label',
- text: `SUPERSPLAT v${version}`
- })
-
- // canvas container
- const canvasContainer = new Container({
- id: 'canvas-container'
- })
-
- // tools container
- const toolsContainer = new Container({
- id: 'tools-container'
- })
-
- // tooltips
- const tooltips = new Tooltips()
- tooltipsContainer.append(tooltips)
-
- // bottom toolbar
- const scenePanel = new ScenePanel(events, tooltips)
- const viewPanel = new ViewPanel(events, tooltips)
- const bottomToolbar = new BottomToolbar(events, tooltips)
- const rightToolbar = new RightToolbar(events, tooltips)
- const modeToggle = new ModeToggle(events, tooltips)
- // const menu = new Menu(events)
-
- canvasContainer.dom.appendChild(canvas)
- canvasContainer.append(appLabel)
- canvasContainer.append(toolsContainer)
- canvasContainer.append(scenePanel)
- canvasContainer.append(viewPanel)
- canvasContainer.append(bottomToolbar)
- canvasContainer.append(rightToolbar)
- canvasContainer.append(modeToggle)
- // canvasContainer.append(menu)
-
- // view axes container
- const viewCube = new ViewCube(events)
- canvasContainer.append(viewCube)
- events.on('prerender', (cameraMatrix: Mat4) => {
- viewCube.update(cameraMatrix)
- })
-
- // main container
- const mainContainer = new Container({
- id: 'main-container'
- })
-
- const dataPanel = new DataPanel(events)
-
- mainContainer.append(canvasContainer)
- mainContainer.append(dataPanel)
-
- editorContainer.append(mainContainer)
-
- // message popup
- const popup = new Popup(topContainer)
- topContainer.append(popup)
-
- // shortcuts popup
- const shortcutsPopup = new ShortcutsPopup()
-
- appContainer.append(editorContainer)
- appContainer.append(tooltipsContainer)
- appContainer.append(topContainer)
- appContainer.append(shortcutsPopup)
-
- this.appContainer = appContainer
- this.topContainer = topContainer
- this.canvasContainer = canvasContainer
- this.toolsContainer = toolsContainer
- this.canvas = canvas
- this.popup = popup
-
- document.getElementById('app-container').appendChild(appContainer.dom)
- document.body.setAttribute('tabIndex', '-1')
-
- events.on('show.shortcuts', () => {
- shortcutsPopup.hidden = false
- })
-
- events.function('show.about', () => {
- return this.popup.show({
- type: 'info',
- header: 'About',
- message: `SUPERSPLAT v${version}`
- })
- })
-
- events.function('showPopup', (options: ShowOptions) => {
- return this.popup.show(options)
- })
-
- // initialize canvas to correct size before creating graphics device etc
- const pixelRatio = window.devicePixelRatio
- canvas.width = Math.ceil(canvasContainer.dom.offsetWidth * pixelRatio)
- canvas.height = Math.ceil(canvasContainer.dom.offsetHeight * pixelRatio)
-
- // disable context menu globally
- document.addEventListener(
- 'contextmenu',
- (event: MouseEvent) => {
- event.preventDefault()
- },
- true
- )
-
- // whenever the canvas container is clicked, set keyboard focus on the body
- canvasContainer.dom.addEventListener(
- 'pointerdown',
- (event: PointerEvent) => {
- // set focus on the body if user is busy pressing on the canvas or a child of the tools
- // element
- if (
- event.target === canvas ||
- toolsContainer.dom.contains(event.target as Node)
- ) {
- document.body.focus()
- }
- }
- )
- }
-}
-
-export { EditorUI }
diff --git a/mirror-2/splat/src/ui/histogram.ts b/mirror-2/splat/src/ui/histogram.ts
deleted file mode 100644
index 55748bb6..00000000
--- a/mirror-2/splat/src/ui/histogram.ts
+++ /dev/null
@@ -1,247 +0,0 @@
-import { Events } from '../events';
-
-class HistogramData {
- bins: { selected: number, unselected: number }[];
- numValues: number;
- minValue: number;
- maxValue: number;
-
- constructor(numBins: number) {
- this.bins = [];
- for (let i = 0; i < numBins; ++i) {
- this.bins.push({ selected: 0, unselected: 0 });
- }
- }
-
- calc(count: number, valueFunc: (v: number) => number | undefined, selectedFunc: (v: number) => boolean) {
- // clear bins
- const bins = this.bins;
- for (let i = 0; i < bins.length; ++i) {
- bins[i].selected = bins[i].unselected = 0;
- }
-
- // calculate min, max
- let min, max, i;
- for (i = 0; i < count; i++) {
- const v = valueFunc(i);
- if (v !== undefined) {
- min = max = v;
- break;
- }
- }
-
- // no data
- if (i === count) {
- return;
- }
-
- // continue min/max calc
- for (; i < count; i++) {
- const v = valueFunc(i);
- if (v !== undefined) {
- if (v < min) min = v; else if (v > max) max = v;
- }
- }
-
- // fill bins
- for (let i = 0; i < count; i++) {
- const v = valueFunc(i);
- if (v !== undefined) {
- const n = min === max ? 0 : (v - min) / (max - min);
- const bin = Math.min(bins.length - 1, Math.floor(n * bins.length));
- if (selectedFunc(i))
- bins[bin].selected++;
- else
- bins[bin].unselected++;
- }
- }
- this.numValues = bins.reduce((t, v) => t + v.selected + v.unselected, 0);
- this.minValue = min;
- this.maxValue = max;
- }
-
- bucketValue(bucket: number) {
- return this.minValue + bucket * this.bucketSize;
- }
-
- get bucketSize() {
- return (this.maxValue - this.minValue) / this.bins.length;
- }
-
- valueToBucket(value: number) {
- const n = this.minValue === this.maxValue ? 0 : (value - this.minValue) / (this.maxValue - this.minValue);
- return Math.min(this.bins.length - 1, Math.floor(n * this.bins.length));
- }
-}
-
-interface UpdateOptions {
- count: number;
- valueFunc: (v: number) => number | undefined;
- selectedFunc: (v: number) => boolean;
- logScale?: boolean
-}
-
-class Histogram {
- canvas: HTMLCanvasElement;
- context: CanvasRenderingContext2D;
- histogram: HistogramData;
- pixelData: ImageData;
- events = new Events();
-
- constructor(numBins: number, height: number) {
- const canvas = document.createElement('canvas');
- canvas.setAttribute('id', 'histogram-canvas');
- canvas.width = numBins;
- canvas.height = height;
- canvas.style.width = `100%`;
- canvas.style.height = `100%`;
-
- const context = canvas.getContext('2d');
- context.globalCompositeOperation = 'copy';
-
- context.fillStyle = 'black';
- context.fillRect(0, 0, canvas.width, canvas.height);
-
- this.canvas = canvas;
- this.context = context;
- this.histogram = new HistogramData(numBins);
- this.pixelData = context.createImageData(canvas.width, canvas.height);
-
- let dragging = false;
- let dragStart = 0;
- let dragEnd = 0;
-
- const offsetToBucket = (offset: number) => {
- const rect = this.canvas.getBoundingClientRect();
- const bins = this.histogram.bins.length;
- return Math.max(0, Math.min(bins - 1, Math.floor((offset - rect.left) / rect.width * bins)));
- };
-
- const bucketToOffset = (bucket: number) => {
- const rect = this.canvas.getBoundingClientRect();
- return bucket / this.histogram.bins.length * rect.width;
- };
-
- const updateHighlight = () => {
- const rect = this.canvas.getBoundingClientRect();
- const start = Math.min(dragStart, dragEnd);
- const end = Math.max(dragStart, dragEnd);
- this.events.fire('highlight', {
- x: bucketToOffset(start),
- y: 0,
- width: (end - start + 1) / this.histogram.bins.length * rect.width,
- height: rect.height
- });
- };
-
- this.canvas.addEventListener('pointerdown', (e: PointerEvent) => {
- e.preventDefault();
- e.stopPropagation();
-
- const h = this.histogram;
-
- if (h.numValues) {
- this.canvas.setPointerCapture(e.pointerId);
- dragging = true;
- dragStart = dragEnd = offsetToBucket(e.clientX);
- updateHighlight();
- }
- });
-
- this.canvas.addEventListener('pointerup', (e: PointerEvent) => {
- e.preventDefault();
- e.stopPropagation();
-
- if (dragging) {
- this.canvas.releasePointerCapture(e.pointerId);
-
- const op = e.shiftKey ? 'add' : (e.ctrlKey ? 'remove' : 'set');
- this.events.fire('select', op, Math.min(dragStart, dragEnd), Math.max(dragStart, dragEnd));
- dragging = false;
- }
- });
-
- this.canvas.addEventListener('pointermove', (e: PointerEvent) => {
- e.preventDefault();
- e.stopPropagation();
-
- const h = this.histogram;
-
- if (h.numValues) {
- if (dragging) {
- dragEnd = offsetToBucket(e.clientX);
- updateHighlight();
- }
-
- const rect = this.canvas.getBoundingClientRect();
- const x = Math.max(0, Math.min(1, (e.clientX - rect.left) / rect.width));
-
- const binIndex = Math.min(h.bins.length - 1, Math.floor(x * h.bins.length));
- const bin = h.bins[binIndex];
-
- this.events.fire('updateOverlay', {
- x: e.offsetX,
- y: e.offsetY,
- value: h.bucketValue(binIndex),
- size: h.bucketSize,
- selected: bin.selected,
- unselected: bin.unselected,
- total: h.numValues
- });
- }
- });
-
- this.canvas.addEventListener('pointerenter', (e: PointerEvent) => {
- this.events.fire('showOverlay');
- });
-
- this.canvas.addEventListener('pointerleave', (e: PointerEvent) => {
- this.events.fire('hideOverlay');
- });
- }
-
- update(options: UpdateOptions) {
- // update histogram data
- this.histogram.calc(options.count, options.valueFunc, options.selectedFunc);
-
- // draw histogram
- const canvas = this.canvas;
- const context = this.context;
- const pixelData = this.pixelData;
- const pixels = new Uint32Array(pixelData.data.buffer);
-
- const binMap = options.logScale ? (x: number) => Math.log(x + 1) : (x: number) => x;
- const bins = this.histogram.bins.map(v => {
- return {
- selected: binMap(v.unselected + v.selected),
- unselected: binMap(v.unselected)
- }
- });
- const binMax = bins.reduce((a, v) => Math.max(a, v.selected), 0);
-
- let i = 0;
- for (let y = 0; y < canvas.height; y++) {
- for (let x = 0; x < bins.length; x++) {
- const bin = bins[x];
- const targetMin = binMax / canvas.height * (canvas.height - 1 - y);
-
- if (targetMin >= bin.selected) {
- pixels[i++] = 0xff000000;
- } else {
- const targetMax = targetMin + binMax / canvas.height;
- if (bin.selected === bin.unselected || targetMax < bin.unselected) {
- pixels[i++] = 0xffff7777;
- } else {
- pixels[i++] = 0xff00ffff;
- }
- }
- }
- }
-
- context.putImageData(pixelData, 0, 0);
- }
-
-
-}
-
-export { Histogram };
diff --git a/mirror-2/splat/src/ui/localization.ts b/mirror-2/splat/src/ui/localization.ts
deleted file mode 100644
index 92922636..00000000
--- a/mirror-2/splat/src/ui/localization.ts
+++ /dev/null
@@ -1,849 +0,0 @@
-import i18next from 'i18next';
-import LanguageDetector from 'i18next-browser-languagedetector';
-
-const localizeInit = () => {
- i18next
- .use(LanguageDetector)
- .init({
- detection: {
- order: ['querystring', /*'cookie', 'localStorage', 'sessionStorage',*/ 'navigator', 'htmlTag'],
- },
- supportedLngs: ['de', 'en', 'fr', 'ja', 'ko', 'zh-CN'],
- fallbackLng: 'en',
- resources: {
- de: {
- translation: {
- // Scene menu
- "scene": "Szene",
- "scene.new": "Neu",
- "scene.open": "Öffnen",
- "scene.import": "Importieren",
- "scene.load-all-data": "PLY-Daten vollständig laden",
- "scene.save": "Speichern",
- "scene.save-as": "Speichern als...",
- "scene.export": "Exportieren",
- "scene.export.compressed-ply": "Komprimiertes PLY",
- "scene.export.splat": "Splat",
-
- // Selection menu
- "selection": "Selektion",
- "selection.all": "Alles",
- "selection.none": "Aufheben",
- "selection.invert": "Invertieren",
- "selection.lock": "Selektion sperren",
- "selection.unlock": "Sperre aufheben",
- "selection.delete": "Selektion aufheben",
- "selection.reset": "Splats zurücksetzen",
-
- // Help menu
- "help": "Hilfe",
- "help.shortcuts": "Tastaturkürzel",
- "help.user-guide": "Handbuch",
- "help.log-issue": "Problem melden",
- "help.github-repo": "GitHub Repository",
- "help.discord": "Discord Server",
- "help.forum": "Forum",
- "help.about": "Über SuperSplat",
-
- // Modes
- "mode.centers": "Punkt Modus",
- "mode.rings": "Ring Modus",
-
- // Scene panel
- "scene-manager": "SZENEN MANAGER",
- "transform": "TRANSFORMATION",
- "position": "Position",
- "rotation": "Rotation",
- "scale": "Skalierung",
-
- // Options panel
- "options": "ANSICHTS OPTIONEN",
- "options.fov": "Blickwinkel (FoV)",
- "options.sh-bands": "SH Bänder",
- "options.centers-size": "Punktgrößen",
- "options.show-grid": "Raster anzeigen",
- "options.show-bound": "Objektbox anzeigen",
-
- "options.pose-header": "POSEN",
- "options.add-pose": "Pose hinzufügen",
- "options.prev-pose": "Vorherige Pose",
- "options.next-pose": "Nächste Pose",
- "options.play-poses": "Posen abspielen",
- "options.clear-poses": "Posen leeren",
-
- // Data panel
- "data": "SPLAT DATEN",
- "data.distance": "Entfernung",
- "data.volume": "Volumen",
- "data.surface-area": "Oberfläche",
- "data.scale-x": "Größe X",
- "data.scale-y": "Größe Y",
- "data.scale-z": "Größe Z",
- "data.red": "Rot",
- "data.green": "Grün",
- "data.blue": "Blau",
- "data.opacity": "Deckkraft",
- "data.hue": "Farbe",
- "data.saturation": "Sättigung",
- "data.value": "Helligkeit",
- "data.log-scale": "Logarithmische Skala",
- "data.totals": "Summe",
- "data.totals.splats": "Splats",
- "data.totals.selected": "Selektiert",
- "data.totals.hidden": "Ausgeblendet",
- "data.totals.deleted": "Gelöscht",
-
- // Shortcuts panel
- "shortcuts.title": "TASTATURKÜRZEL",
- "shortcuts.tools": "WERKZEUGE",
- "shortcuts.move": "Bewegen",
- "shortcuts.rotate": "Drehen",
- "shortcuts.scale": "Skalieren",
- "shortcuts.rect-selection": "Rechteckselektion",
- "shortcuts.brush-selection": "Pinselselektion",
- "shortcuts.picker-selection": "Einzelselektion",
- "shortcuts.brush-size": "Pinsel Verkleinern/Vergrößern",
- "shortcuts.deactivate-tool": "Werkzeug deaktivieren",
- "shortcuts.selection": "SELEKTION",
- "shortcuts.select-all": "Alle Selektieren",
- "shortcuts.deselect-all": "Selektion aufheben",
- "shortcuts.invert-selection": "Selektion invertieren",
- "shortcuts.add-to-selection": "Zur Selektion hinzufügen",
- "shortcuts.remove-from-selection": "Von Selektion entfernen",
- "shortcuts.delete-selected-splats": "Selektierte Splats löschen",
- "shortcuts.show": "ANZEIGEN",
- "shortcuts.hide-selected-splats": "Selektierte Splats ausblenden",
- "shortcuts.unhide-all-splats": "Alle Splats einblenden",
- "shortcuts.toggle-data-panel": "Splat Daten Panel anzeigen",
- "shortcuts.other": "WEITERE",
- "shortcuts.select-next-splat": "Nächsten Splat selektieren",
- "shortcuts.undo": "Rückgängig",
- "shortcuts.redo": "Wiederholen",
- "shortcuts.toggle-splat-overlay": "Splateinblendung umschalten",
- "shortcuts.focus-camera": "Kamera auf selektion ausrichten",
- "shortcuts.toggle-camera-mode": "Kameramodus umschalten",
- "shortcuts.toggle-grid": "Rasteranzeige umschalten",
- "shortcuts.toggle-gizmo-coordinate-space": "Gizmoanzeige umschalten",
-
- // Popup
- "popup.ok": "OK",
- "popup.cancel": "Abbrechen",
- "popup.yes": "Ja",
- "popup.no": "Nein",
- "popup.error-loading": "FEHLER BEIM LADEN DER DATEI",
-
- // Right toolbar
- "tooltip.splat-mode": "Splat Modus ( M )",
- "tooltip.show-hide": "Anzeigen/Ausplenden Splats ( Leertaste )",
- "tooltip.frame-selection": "Rechteckselektion ( F )",
- "tooltip.view-options": "Anzeige Optionen",
-
- // Bottom toolbar
- "tooltip.undo": "Rückgängig ( Strg + Z )",
- "tooltip.redo": "Wiederholen ( Strg + Shift + Z )",
- "tooltip.picker": "Einzelselektion ( P )",
- "tooltip.brush": "Pinselselektion ( B )",
- "tooltip.sphere": "Kugelselektion",
- "tooltip.translate": "Verschieben ( 1 )",
- "tooltip.rotate": "Drehen ( 2 )",
- "tooltip.scale": "Skalieren ( 3 )",
- "tooltip.local-space": "Gizmo in local-space"
- }
- },
- en: {
- translation: {
- // Scene menu
- "scene": "Scene",
- "scene.new": "New",
- "scene.open": "Open",
- "scene.import": "Import",
- "scene.load-all-data": "Load all PLY data",
- "scene.save": "Save",
- "scene.save-as": "Save As...",
- "scene.export": "Export",
- "scene.export.compressed-ply": "Compressed PLY",
- "scene.export.splat": "Splat file",
-
- // Selection menu
- "selection": "Selection",
- "selection.all": "All",
- "selection.none": "None",
- "selection.invert": "Inverse",
- "selection.lock": "Lock Selection",
- "selection.unlock": "Unlock All",
- "selection.delete": "Delete Selection",
- "selection.reset": "Reset Splat",
-
- // Help menu
- "help": "Help",
- "help.shortcuts": "Keyboard Shortcuts",
- "help.user-guide": "User Guide",
- "help.log-issue": "Log an Issue",
- "help.github-repo": "GitHub Repo",
- "help.discord": "Discord Server",
- "help.forum": "Forum",
- "help.about": "About SuperSplat",
-
- // Modes
- "mode.centers": "Centers Mode",
- "mode.rings": "Rings Mode",
-
- // Scene panel
- "scene-manager": "SCENE MANAGER",
- "transform": "TRANSFORM",
- "position": "Position",
- "rotation": "Rotation",
- "scale": "Scale",
-
- // Options panel
- "options": "VIEW OPTIONS",
- "options.fov": "Field of View",
- "options.sh-bands": "SH Bands",
- "options.centers-size": "Centers Size",
- "options.show-grid": "Show Grid",
- "options.show-bound": "Show Bound",
-
- "options.pose-header": "POSES",
- "options.add-pose": "Add Pose",
- "options.prev-pose": "Previous Pose",
- "options.next-pose": "Next Pose",
- "options.play-poses": "Play Poses",
- "options.clear-poses": "Clear Poses",
-
- // Data panel
- "data": "SPLAT DATA",
- "data.distance": "Distance",
- "data.volume": "Volume",
- "data.surface-area": "Surface Area",
- "data.scale-x": "Scale X",
- "data.scale-y": "Scale Y",
- "data.scale-z": "Scale Z",
- "data.red": "Red",
- "data.green": "Green",
- "data.blue": "Blue",
- "data.opacity": "Opacity",
- "data.hue": "Hue",
- "data.saturation": "Saturation",
- "data.value": "Value",
- "data.log-scale": "Log Scale",
- "data.totals": "Totals",
- "data.totals.splats": "Splats",
- "data.totals.selected": "Selected",
- "data.totals.hidden": "Hidden",
- "data.totals.deleted": "Deleted",
-
- // Shortcuts panel
- "shortcuts.title": "KEYBOARD SHORTCUTS",
- "shortcuts.tools": "TOOLS",
- "shortcuts.move": "Move",
- "shortcuts.rotate": "Rotate",
- "shortcuts.scale": "Scale",
- "shortcuts.rect-selection": "Rect Selection",
- "shortcuts.brush-selection": "Brush Selection",
- "shortcuts.picker-selection": "Picker Selection",
- "shortcuts.brush-size": "Decrease/Increase brush size",
- "shortcuts.deactivate-tool": "Deactivate Tool",
- "shortcuts.selection": "SELECTION",
- "shortcuts.select-all": "Select All",
- "shortcuts.deselect-all": "Deselect All",
- "shortcuts.invert-selection": "Invert Selection",
- "shortcuts.add-to-selection": "Add to Selection",
- "shortcuts.remove-from-selection": "Remove from Selection",
- "shortcuts.delete-selected-splats": "Delete Selected Splats",
- "shortcuts.show": "SHOW",
- "shortcuts.hide-selected-splats": "Hide Selected Splats",
- "shortcuts.unhide-all-splats": "Unhide All Splats",
- "shortcuts.toggle-data-panel": "Toggle Data Panel",
- "shortcuts.other": "OTHER",
- "shortcuts.select-next-splat": "Select Next Splat",
- "shortcuts.undo": "Undo",
- "shortcuts.redo": "Redo",
- "shortcuts.toggle-splat-overlay": "Toggle Splat Overlay",
- "shortcuts.focus-camera": "Focus Camera on current selection",
- "shortcuts.toggle-camera-mode": "Toggle Camera Mode",
- "shortcuts.toggle-grid": "Toggle Grid",
- "shortcuts.toggle-gizmo-coordinate-space": "Toggle Gizmo Coordinate Space",
-
- // Popup
- "popup.ok": "OK",
- "popup.cancel": "Cancel",
- "popup.yes": "Yes",
- "popup.no": "No",
- "popup.error-loading": "ERROR LOADING FILE",
-
- // Right toolbar
- "tooltip.splat-mode": "Splat Mode ( M )",
- "tooltip.show-hide": "Show/Hide Splats ( Space )",
- "tooltip.frame-selection": "Frame Selection ( F )",
- "tooltip.view-options": "View Options",
-
- // Bottom toolbar
- "tooltip.undo": "Undo ( Ctrl + Z )",
- "tooltip.redo": "Redo ( Ctrl + Shift + Z )",
- "tooltip.picker": "Picker Select ( P )",
- "tooltip.brush": "Brush Select ( B )",
- "tooltip.sphere": "Sphere Select",
- "tooltip.translate": "Translate ( 1 )",
- "tooltip.rotate": "Rotate ( 2 )",
- "tooltip.scale": "Scale ( 3 )",
- "tooltip.local-space": "Local Space Gizmo"
- }
- },
- fr: {
- translation: {
- // scene menu
- "scene": "Scène",
- "scene.new": "Créer",
- "scene.open": "Ouvrir",
- "scene.import": "Importer",
- "scene.load-all-data": "Charger toutes les données ply",
- "scene.save": "Enregistrer",
- "scene.save-as": "Enregistrer sous...",
- "scene.export": "Exporter",
- "scene.export.compressed-ply": "Ply compressé",
- "scene.export.splat": "Fichier splat",
-
- // selection menu
- "selection": "Sélection",
- "selection.all": "Tout",
- "selection.none": "Aucune",
- "selection.invert": "Inverser",
- "selection.lock": "Verrouiller la sélection",
- "selection.unlock": "Tout débloquer",
- "selection.delete": "Supprimer la sélection",
- "selection.reset": "Réinitialiser splat",
-
- // help menu
- "help": "Aide",
- "help.shortcuts": "Raccourcis claviers",
- "help.user-guide": "Guide utilisateur",
- "help.log-issue": "Signaler un problème",
- "help.github-repo": "Dépôt GitHub",
- "help.discord": "Serveur Discord",
- "help.forum": "Forum",
- "help.about": "À propos de SuperSplat",
-
- // modes
- "mode.centers": "Mode centres",
- "mode.rings": "Mode anneaux",
-
- // scene panel
- "scene-manager": "GESTIONNAIRE DE SCENE",
- "transform": "TRANSFORMATION",
- "position": "Position",
- "rotation": "Rotation",
- "scale": "Échelle",
-
- // options panel
- "options": "OPTIONS D'AFFICHAGE",
- "options.fov": "Champ de vision",
- "options.sh-bands": "Ordres d'HS",
- "options.centers-size": "Échelle des centres",
- "options.show-grid": "Afficher la grille",
- "options.show-bound": "Afficher limites",
-
- // data panel
- "data": "DONNEES SPLAT",
- "data.distance": "Distance",
- "data.volume": "Volume",
- "data.surface-area": "Zone de surface",
- "data.scale-x": "Échelle X",
- "data.scale-y": "Échelle Y",
- "data.scale-z": "Échelle Z",
- "data.red": "Rouge",
- "data.green": "Vert",
- "data.blue": "Bleu",
- "data.opacity": "Opacité",
- "data.hue": "Teinte",
- "data.saturation": "Saturation",
- "data.value": "Luminosité",
- "data.log-scale": "Échelle logarithmique",
- "data.totals": "Totaux",
- "data.totals.splats": "Splats",
- "data.totals.selected": "Selectionné",
- "data.totals.hidden": "Caché",
- "data.totals.deleted": "Supprimé",
-
- // Shortcuts panel
- "shortcuts.title": "RACCOURCIS CLAVIERS",
- "shortcuts.tools": "OUTILS",
- "shortcuts.move": "Déplacer",
- "shortcuts.rotate": "Tourner",
- "shortcuts.scale": "Changer l'échelle",
- "shortcuts.rect-selection": "Sélection avec rectangle",
- "shortcuts.brush-selection": "Sélection avec pinceau",
- "shortcuts.picker-selection": "Sélection avec pipette",
- "shortcuts.brush-size": "Augmenter/Diminuer la taille du pinceau",
- "shortcuts.deactivate-tool": "Désactiver l'outil",
- "shortcuts.selection": "SELECTION",
- "shortcuts.select-all": "Tout sélectionner",
- "shortcuts.deselect-all": "Tout desélectionner",
- "shortcuts.invert-selection": "Inverser la sélection",
- "shortcuts.add-to-selection": "Ajouter à la sélection",
- "shortcuts.remove-from-selection": "Retirer de la sélection",
- "shortcuts.delete-selected-splats": "Supprimer splats sélectionnés",
- "shortcuts.show": "AFFICHER",
- "shortcuts.hide-selected-splats": "Masquer splats sélectionnés",
- "shortcuts.unhide-all-splats": "Réafficher tous les splats",
- "shortcuts.toggle-data-panel": "Afficher/Cacher l'onglet données",
- "shortcuts.other": "AUTRES",
- "shortcuts.select-next-splat": "Sélectionner le splat suivant",
- "shortcuts.undo": "Annuler",
- "shortcuts.redo": "Rétablir",
- "shortcuts.toggle-splat-overlay": "Basculer affichage splat",
- "shortcuts.focus-camera": "Focaliser la caméra sur la sélection actuelle",
- "shortcuts.toggle-camera-mode": "Basculer le mode de camera",
- "shortcuts.toggle-grid": "Afficher/Cacher la grille",
- "shortcuts.toggle-gizmo-coordinate-space": "Basculer en espace de coordonnées Gizmo",
-
- // popup
- "popup.ok": "OK",
- "popup.cancel": "Annuler",
- "popup.yes": "Oui",
- "popup.no": "Non",
- "popup.error-loading": "Erreur de chargement du fichier",
-
- // right toolbar
- "tooltip.splat-mode": "Mode splat ( M )",
- "tooltip.show-hide": "Afficher/cacher les splats ( Barre espace )",
- "tooltip.frame-selection": "Cadrer la sélection ( F )",
- "tooltip.view-options": "Options d'affichage",
-
- // bottom toolbar
- "tooltip.undo": "Annuler ( Ctrl + Z )",
- "tooltip.redo": "Rétablir ( Ctrl + Shift + Z )",
- "tooltip.picker": "Sélection avec pipette ( P )",
- "tooltip.brush": "Sélection avec pinceau ( B )",
- "tooltip.sphere": "Sélection avec sphère",
- "tooltip.translate": "Translation ( 1 )",
- "tooltip.rotate": "Rotation ( 2 )",
- "tooltip.scale": "Échelle ( 3 )",
- "tooltip.local-space": "Espace local gizmo"
- }
- },
- ja: {
- translation: {
- // Scene menu
- "scene": "シーン",
- "scene.new": "新規作成",
- "scene.open": "開く",
- "scene.import": "インポート",
- "scene.load-all-data": "全てのPLYデータを読み込む",
- "scene.save": "保存",
- "scene.save-as": "名前を付けて保存",
- "scene.export": "エクスポート",
- "scene.export.compressed-ply": "Compressed PLY ( .ply )",
- "scene.export.splat": "Splat ( .splat )",
-
- // Selection menu
- "selection": "選択",
- "selection.all": "全て",
- "selection.none": "選択を解除",
- "selection.invert": "反転",
- "selection.lock": "選択をロック",
- "selection.unlock": "ロックを解除",
- "selection.delete": "選択を削除",
- "selection.reset": "変更を全てリセット",
-
- // Help menu
- "help": "ヘルプ",
- "help.shortcuts": "キーボードショートカット",
- "help.user-guide": "ユーザーガイド",
- "help.log-issue": "問題を報告",
- "help.github-repo": "GitHubリポジトリ",
- "help.discord": "Discordサーバー",
- "help.forum": "フォーラム",
- "help.about": "SuperSplatについて",
-
- // Modes
- "mode.centers": "センターモード",
- "mode.rings": "リングモード",
-
- // Scene panel
- "scene-manager": "シーンマネージャー",
- "transform": "トランスフォーム",
- "position": "位置",
- "rotation": "回転",
- "scale": "スケール",
-
- // Options panel
- "options": "表示オプション",
- "options.fov": "視野 ( FOV )",
- "options.sh-bands": "球面調和関数のバンド",
- "options.centers-size": "センターサイズ",
- "options.show-grid": "グリッド",
- "options.show-bound": "バウンディングボックス",
-
- "options.add-pose": "ポーズを追加",
- "options.prev-pose": "前のポーズ",
- "options.next-pose": "次のポーズ",
- "options.play-poses": "ポーズを再生",
- "options.clear-poses": "ポーズをクリア",
-
- // Data panel
- "data": "スプラットの統計",
- "data.distance": "距離",
- "data.volume": "体積",
- "data.surface-area": "表面積",
- "data.scale-x": "スケール X",
- "data.scale-y": "スケール Y",
- "data.scale-z": "スケール Z",
- "data.red": "赤",
- "data.green": "緑",
- "data.blue": "青",
- "data.opacity": "不透明度",
- "data.hue": "色相",
- "data.saturation": "彩度",
- "data.value": "明度",
- "data.log-scale": "対数スケール",
- "data.totals": "合計",
- "data.totals.splats": "スプラット数",
- "data.totals.selected": "選択中",
- "data.totals.hidden": "非表示",
- "data.totals.deleted": "削除",
-
- // Shortcuts panel
- "shortcuts.title": "キーボードショートカット",
- "shortcuts.tools": "ツール",
- "shortcuts.move": "移動",
- "shortcuts.rotate": "回転",
- "shortcuts.scale": "スケール",
- "shortcuts.rect-selection": "四角形選択",
- "shortcuts.brush-selection": "ブラシ選択",
- "shortcuts.picker-selection": "ピッカー選択",
- "shortcuts.brush-size": "ブラシサイズの増減",
- "shortcuts.deactivate-tool": "ツールの非アクティブ化",
- "shortcuts.selection": "選択",
- "shortcuts.select-all": "全て選択",
- "shortcuts.deselect-all": "全て選択解除",
- "shortcuts.invert-selection": "選択反転",
- "shortcuts.add-to-selection": "選択追加",
- "shortcuts.remove-from-selection": "選択解除",
- "shortcuts.delete-selected-splats": "選択削除",
- "shortcuts.show": "表示",
- "shortcuts.hide-selected-splats": "選択非表示",
- "shortcuts.unhide-all-splats": "全て表示",
- "shortcuts.toggle-data-panel": "データパネルの切り替え",
- "shortcuts.other": "その他",
- "shortcuts.select-next-splat": "次のスプラットを選択",
- "shortcuts.undo": "元に戻す",
- "shortcuts.redo": "やり直し",
- "shortcuts.toggle-splat-overlay": "スプラットオーバーレイの切り替え",
- "shortcuts.focus-camera": "カメラの焦点を合わせる",
- "shortcuts.toggle-camera-mode": "カメラモードの切り替え",
- "shortcuts.toggle-grid": "グリッドの切り替え",
- "shortcuts.toggle-gizmo-coordinate-space": "ギズモ座標空間の切り替え",
-
- // Popup
- "popup.ok": "OK",
- "popup.cancel": "キャンセル",
- "popup.yes": "はい",
- "popup.no": "いいえ",
- "popup.error-loading": "ファイルの読み込みエラー",
-
- // Right toolbar
- "tooltip.splat-mode": "スプラットモード ( M )",
- "tooltip.show-hide": "スプラットの表示/非表示 ( Space )",
- "tooltip.frame-selection": "選択をフレームイン ( F )",
- "tooltip.view-options": "表示オプション",
-
- // Bottom toolbar
- "tooltip.undo": "元に戻す ( Ctrl + Z )",
- "tooltip.redo": "やり直し ( Ctrl + Shift + Z )",
- "tooltip.picker": "ピッカー選択 ( P )",
- "tooltip.brush": "ブラシ選択 ( B )",
- "tooltip.sphere": "球で選択",
- "tooltip.translate": "移動 ( 1 )",
- "tooltip.rotate": "回転 ( 2 )",
- "tooltip.scale": "スケール ( 3 )",
- "tooltip.local-space": "ローカル座標へ切り替え"
- }
- },
- ko: {
- translation: {
- // Scene menu
- "scene": "장면",
- "scene.new": "새로 만들기",
- "scene.open": "열기",
- "scene.import": "가져오기",
- "scene.load-all-data": "모든 PLY 데이터 불러오기",
- "scene.save": "저장",
- "scene.save-as": "다른 이름으로 저장...",
- "scene.export": "내보내기",
- "scene.export.compressed-ply": "압축된 PLY",
- "scene.export.splat": "Splat 파일",
-
- // Selection menu
- "selection": "선택",
- "selection.all": "모두",
- "selection.none": "없음",
- "selection.invert": "반전",
- "selection.lock": "선택 잠금",
- "selection.unlock": "모두 잠금 해제",
- "selection.delete": "선택 삭제",
- "selection.reset": "Splat 재설정",
-
- // Help menu
- "help": "도움말",
- "help.shortcuts": "키보드 단축키",
- "help.user-guide": "사용자 가이드",
- "help.log-issue": "문제 보고",
- "help.github-repo": "GitHub 저장소",
- "help.discord": "Discord 서버",
- "help.forum": "포럼",
- "help.about": "SuperSplat 정보",
-
- // Modes
- "mode.centers": "센터 모드",
- "mode.rings": "링 모드",
-
- // Scene panel
- "scene-manager": "장면 관리자",
- "transform": "변환",
- "position": "위치",
- "rotation": "회전",
- "scale": "크기",
-
- // Options panel
- "options": "보기 옵션",
- "options.fov": "시야각",
- "options.sh-bands": "SH 밴드",
- "options.centers-size": "센터 크기",
- "options.show-grid": "그리드 표시",
- "options.show-bound": "경계 표시",
-
- "options.add-pose": "포즈 추가",
- "options.prev-pose": "이전 포즈",
- "options.next-pose": "다음 포즈",
- "options.play-poses": "포즈 재생",
- "options.clear-poses": "포즈 지우기",
-
- // Data panel
- "data": "SPLAT 데이터",
- "data.distance": "거리",
- "data.volume": "부피",
- "data.surface-area": "표면적",
- "data.scale-x": "크기 X",
- "data.scale-y": "크기 Y",
- "data.scale-z": "크기 Z",
- "data.red": "빨강",
- "data.green": "녹색",
- "data.blue": "파랑",
- "data.opacity": "불투명도",
- "data.hue": "색조",
- "data.saturation": "채도",
- "data.value": "명도",
- "data.log-scale": "로그 크기",
- "data.totals": "합계",
- "data.totals.splats": "Splat",
- "data.totals.selected": "선택",
- "data.totals.hidden": "숨겨진",
- "data.totals.deleted": "삭제된",
-
- // Shortcuts panel
- "shortcuts.title": "키보드 단축키",
- "shortcuts.tools": "도구",
- "shortcuts.move": "이동",
- "shortcuts.rotate": "회전",
- "shortcuts.scale": "크기 조정",
- "shortcuts.rect-selection": "사각형 선택",
- "shortcuts.brush-selection": "브러시 선택",
- "shortcuts.picker-selection": "피커 선택",
- "shortcuts.brush-size": "브러시 크기 조정",
- "shortcuts.deactivate-tool": "도구 비활성화",
- "shortcuts.selection": "선택",
- "shortcuts.select-all": "모두 선택",
- "shortcuts.deselect-all": "모두 선택 해제",
- "shortcuts.invert-selection": "선택 반전",
- "shortcuts.add-to-selection": "선택 추가",
- "shortcuts.remove-from-selection": "선택 제거",
- "shortcuts.delete-selected-splats": "선택된 Splat 삭제",
- "shortcuts.show": "표시",
- "shortcuts.hide-selected-splats": "선택된 Splat 숨기기",
- "shortcuts.unhide-all-splats": "모든 Splat 표시",
- "shortcuts.toggle-data-panel": "데이터 패널 전환",
- "shortcuts.other": "기타",
- "shortcuts.select-next-splat": "다음 Splat 선택",
- "shortcuts.undo": "실행 취소",
- "shortcuts.redo": "다시 실행",
- "shortcuts.toggle-splat-overlay": "Splat 오버레이 전환",
- "shortcuts.focus-camera": "현재 선택에 초점 맞추기",
- "shortcuts.toggle-camera-mode": "카메라 모드 전환",
- "shortcuts.toggle-grid": "그리드 전환",
- "shortcuts.toggle-gizmo-coordinate-space": "기즈모 좌표 공간 전환",
-
- // Popup
- "popup.ok": "확인",
- "popup.cancel": "취소",
- "popup.yes": "예",
- "popup.no": "아니요",
- "popup.error-loading": "파일 로드 오류",
-
- // Right toolbar
- "tooltip.splat-mode": "Splat 모드 ( M )",
- "tooltip.show-hide": "스플래츠 표시/숨기기 ( Space )",
- "tooltip.frame-selection": "프레임 선택 ( F )",
- "tooltip.view-options": "보기 옵션",
-
- // Bottom toolbar
- "tooltip.undo": "실행 취소 ( Ctrl + Z )",
- "tooltip.redo": "다시 실행 ( Ctrl + Shift + Z )",
- "tooltip.picker": "피커 선택 ( P )",
- "tooltip.brush": "브러시 선택 ( B )",
- "tooltip.sphere": "구 선택",
- "tooltip.translate": "이동 ( 1 )",
- "tooltip.rotate": "회전 ( 2 )",
- "tooltip.scale": "크기 조정 ( 3 )",
- "tooltip.local-space": "로컬 공간"
- }
- },
- "zh-CN": {
- translation: {
- // Scene menu
- "scene": "场景",
- "scene.new": "新建",
- "scene.open": "打开",
- "scene.import": "导入",
- "scene.load-all-data": "加载所有 PLY 数据",
- "scene.save": "保存",
- "scene.save-as": "另存为...",
- "scene.export": "导出",
- "scene.export.compressed-ply": "压缩 PLY",
- "scene.export.splat": "Splat 文件",
-
- // Selection menu
- "selection": "选择",
- "selection.all": "全部",
- "selection.none": "无",
- "selection.invert": "反选",
- "selection.lock": "锁定选择",
- "selection.unlock": "解锁全部",
- "selection.delete": "删除选择",
- "selection.reset": "重置 Splat",
-
- // Help menu
- "help": "帮助",
- "help.shortcuts": "键盘快捷键",
- "help.user-guide": "用户指南",
- "help.log-issue": "报告问题",
- "help.github-repo": "GitHub 仓库",
- "help.discord": "Discord 服务器",
- "help.forum": "论坛",
- "help.about": "关于 SuperSplat",
-
- // Modes
- "mode.centers": "中心模式",
- "mode.rings": "环模式",
-
- // Scene panel
- "scene-manager": "场景管理器",
- "transform": "变换",
- "position": "位置",
- "rotation": "旋转",
- "scale": "缩放",
-
- // Options panel
- "options": "视图选项",
- "options.fov": "视野角",
- "options.sh-bands": "SH 带",
- "options.centers-size": "中心大小",
- "options.show-grid": "显示网格",
- "options.show-bound": "显示边界",
-
- "options.add-pose": "添加姿势",
- "options.prev-pose": "上一个姿势",
- "options.next-pose": "下一个姿势",
- "options.play-poses": "播放姿势",
- "options.clear-poses": "清除姿势",
-
- // Data panel
- "data": "SPLAT 数据",
- "data.distance": "距离",
- "data.volume": "体积",
- "data.surface-area": "表面积",
- "data.scale-x": "缩放 X",
- "data.scale-y": "缩放 Y",
- "data.scale-z": "缩放 Z",
- "data.red": "红",
- "data.green": "绿",
- "data.blue": "蓝",
- "data.opacity": "不透明度",
- "data.hue": "色相",
- "data.saturation": "饱和度",
- "data.value": "明度",
- "data.log-scale": "对数缩放",
- "data.totals": "总计",
- "data.totals.splats": "Splat",
- "data.totals.selected": "选择",
- "data.totals.hidden": "隐藏",
- "data.totals.deleted": "删除",
-
- // Shortcuts panel
- "shortcuts.title": "键盘快捷键",
- "shortcuts.tools": "工具",
- "shortcuts.move": "移动",
- "shortcuts.rotate": "旋转",
- "shortcuts.scale": "缩放",
- "shortcuts.rect-selection": "矩形选择",
- "shortcuts.brush-selection": "画笔选择",
- "shortcuts.picker-selection": "拾取选择",
- "shortcuts.brush-size": "减小/增大画笔大小",
- "shortcuts.deactivate-tool": "停用工具",
- "shortcuts.selection": "选择",
- "shortcuts.select-all": "全选",
- "shortcuts.deselect-all": "取消全选",
- "shortcuts.invert-selection": "反选",
- "shortcuts.add-to-selection": "添加到选择",
- "shortcuts.remove-from-selection": "从选择中移除",
- "shortcuts.delete-selected-splats": "删除选择的 Splat",
- "shortcuts.show": "显示",
- "shortcuts.hide-selected-splats": "隐藏选择的 Splat",
- "shortcuts.unhide-all-splats": "显示全部 Splat",
- "shortcuts.toggle-data-panel": "切换数据面板",
- "shortcuts.other": "其他",
- "shortcuts.select-next-splat": "选择下一个 Splat",
- "shortcuts.undo": "撤销",
- "shortcuts.redo": "重做",
- "shortcuts.toggle-splat-overlay": "切换 Splat 叠加",
- "shortcuts.focus-camera": "聚焦当前选择",
- "shortcuts.toggle-camera-mode": "切换相机模式",
- "shortcuts.toggle-grid": "切换网格",
- "shortcuts.toggle-gizmo-coordinate-space": "切换 Gizmo 坐标空间",
-
- // Popup
- "popup.ok": "确定",
- "popup.cancel": "取消",
- "popup.yes": "是",
- "popup.no": "否",
- "popup.error-loading": "加载文件错误",
-
- // Right toolbar
- "tooltip.splat-mode": "Splat 模式 ( M )",
- "tooltip.show-hide": "显示/隐藏 Splats ( Space )",
- "tooltip.frame-selection": "框选 ( F )",
- "tooltip.view-options": "视图选项",
-
- // Bottom toolbar
- "tooltip.undo": "撤销 ( Ctrl + Z )",
- "tooltip.redo": "重做 ( Ctrl + Shift + Z )",
- "tooltip.picker": "选择器 ( P )",
- "tooltip.brush": "画笔 ( B )",
- "tooltip.sphere": "球选择",
- "tooltip.translate": "移动 ( 1 )",
- "tooltip.rotate": "旋转 ( 2 )",
- "tooltip.scale": "缩放 ( 3 )",
- "tooltip.local-space": "局部坐标系"
- }
- }
- },
- interpolation: {
- escapeValue: false
- }
- });
-};
-
-const localize = (key: string) => {
- return i18next.t(key);
-};
-
-export { localizeInit, localize };
diff --git a/mirror-2/splat/src/ui/menu-panel.scss b/mirror-2/splat/src/ui/menu-panel.scss
deleted file mode 100644
index c0c61384..00000000
--- a/mirror-2/splat/src/ui/menu-panel.scss
+++ /dev/null
@@ -1,82 +0,0 @@
-.menu-panel {
- position: absolute;
-
- &::not(.pcui-hidden) {
- display: flex;
- }
- flex-direction: column;
-
- border-radius: 8px;
- overflow: hidden;
-
- background-color: $bcg-dark;
- filter: drop-shadow(5px 5px 10px rgba(0, 0, 0, 0.8));
-
- // the following is needed to get drop-shadow working on safari
- will-change: transform;
-}
-
-.menu-row {
- display: flex;
- flex-direction: row;
- min-width: 180px;
- align-items: center;
- height: 32px;
- padding: 0px 8px;
-
- svg {
- color: $text-secondary;
- }
-
- &:hover:not(.pcui-disabled) {
- background-color: $bcg-darkest;
- cursor: pointer;
-
- & > .menu-row-text, .menu-row-postscript, .menu-row-icon {
- color: $text-primary;
- }
-
- svg {
- color: $text-primary;
- }
- }
-
- &.pcui-disabled {
- & > .menu-row-text, .menu-row-postscript, .menu-row-icon {
- color: $text-darkest;
- }
-
- svg {
- color: $text-darkest;
- }
- }
-
- // tweaks for attached boolean toggles
- > .pcui-boolean-input {
- background-color: $bcg-darkest;
- border-radius: 2px;
- &.pcui-boolean-input-ticked {
- background-color: $clr-hilight;
- &::after {
- color: $text-primary;
- }
- }
- }
-}
-
-.menu-row-icon {
- font-family: 'pc-icon' !important;
-}
-
-.menu-row-text {
- flex-grow: 1;
-}
-
-.menu-row-postscript {
- color: $text-dark;
-}
-
-.menu-row-separator {
- height: 1px;
- background-color: $bcg-light;
-}
diff --git a/mirror-2/splat/src/ui/menu-panel.ts b/mirror-2/splat/src/ui/menu-panel.ts
deleted file mode 100644
index 2a4e0092..00000000
--- a/mirror-2/splat/src/ui/menu-panel.ts
+++ /dev/null
@@ -1,219 +0,0 @@
-import { Container, Element, Label, Menu } from '@playcanvas/pcui'
-
-type Direction = 'left' | 'right' | 'top' | 'bottom'
-
-type MenuItem = {
- text?: string
- icon?: string | Element
- extra?: string | Element
- subMenu?: MenuPanel
-
- onSelect?: () => any
- isEnabled?: () => boolean
-}
-
-const offsetParent = (elem: HTMLElement): HTMLElement => {
- const parent = elem.parentNode as HTMLElement
-
- return parent.tagName === 'BODY' ||
- window.getComputedStyle(parent).position !== 'static'
- ? parent
- : offsetParent(parent)
-}
-
-const arrange = (
- element: HTMLElement,
- target: HTMLElement,
- direction: Direction,
- padding: number
-) => {
- const rect = target.getBoundingClientRect()
- const parentRect = offsetParent(element).getBoundingClientRect()
-
- const style = element.style
- switch (direction) {
- case 'left':
- break
- case 'right':
- style.left = `${rect.right - parentRect.left + padding}px`
- style.top = `${rect.top - parentRect.top}px`
- break
- case 'top':
- break
- case 'bottom':
- style.left = `${rect.left - parentRect.left}px`
- style.top = `${rect.bottom - parentRect.top + padding}px`
- break
- }
-}
-
-const isString = (value: any) => {
- return !value || typeof value === 'string' || value instanceof String
-}
-
-class MenuPanel extends Container {
- parentPanel: MenuPanel | null = null
-
- constructor(menuItems: MenuItem[], args = {}) {
- args = {
- ...args,
- class: 'menu-panel',
- hidden: true
- }
-
- super(args)
-
- this.on('hide', () => {
- for (const menuItem of menuItems) {
- if (menuItem.subMenu) {
- menuItem.subMenu.hidden = true
- }
- }
- })
-
- this.on('show', () => {
- for (let i = 0; i < menuItems.length; i++) {
- const menuItem = menuItems[i]
- if (menuItem.isEnabled) {
- this.dom.children.item(i).ui.enabled = menuItem.isEnabled()
- }
- }
- })
-
- let deactivate: () => void | null = null
-
- for (const menuItem of menuItems) {
- const type = menuItem.subMenu
- ? 'menu'
- : menuItem.text
- ? 'button'
- : 'separator'
-
- const createIcon = (icon: string | Element) => {
- return isString(menuItem.icon)
- ? new Label({
- class: 'menu-row-icon',
- text:
- menuItem.icon &&
- String.fromCodePoint(parseInt(menuItem.icon as string, 16))
- })
- : menuItem.icon
- }
-
- let row: Container | null = null
- let activate: () => void | null = null
- switch (type) {
- case 'button': {
- row = new Container({ class: 'menu-row' })
- const icon = createIcon(menuItem.icon)
- const text = new Label({
- class: 'menu-row-text',
- text: menuItem.text
- })
- const postscript = isString(menuItem.extra)
- ? new Label({
- class: 'menu-row-postscript',
- text: menuItem.extra as string
- })
- : menuItem.extra
- row.append(icon)
- row.append(text)
- row.append(postscript)
-
- break
- }
-
- case 'menu': {
- row = new Container({ class: 'menu-row' })
- const icon = createIcon(menuItem.icon)
- const text = new Label({
- class: 'menu-row-text',
- text: menuItem.text
- })
- const postscript = new Label({
- class: 'menu-row-postscript',
- text: '\u232A'
- })
- row.append(icon)
- row.append(text)
- row.append(postscript)
-
- // set parent panel
- menuItem.subMenu.parentPanel = this
-
- const childPanel = menuItem.subMenu
- if (childPanel) {
- activate = () => {
- if (childPanel.hidden) {
- childPanel.position(row.dom, 'right', 2)
- childPanel.hidden = !childPanel.hidden
- }
-
- deactivate = () => {
- childPanel.hidden = true
- }
- }
- }
-
- break
- }
-
- case 'separator':
- this.append(new Container({ class: 'menu-row-separator' }))
- break
- }
-
- if (row) {
- let timer = -1
-
- row.dom.addEventListener('pointerenter', () => {
- timer = setTimeout(() => {
- if (deactivate) {
- deactivate()
- }
- if (activate) {
- activate()
- }
- }, 250)
- })
-
- row.dom.addEventListener('pointerleave', () => {
- if (timer !== -1) {
- clearTimeout(timer)
- timer = -1
- }
- })
-
- row.dom.addEventListener('pointerdown', (event: PointerEvent) => {
- event.stopPropagation()
- })
-
- row.dom.addEventListener('pointerup', (event: PointerEvent) => {
- event.stopPropagation()
-
- if (!row.disabled && menuItem.onSelect) {
- this.rootPanel.hidden = true
- menuItem.onSelect()
- }
- })
-
- this.append(row)
- }
- }
- }
-
- get rootPanel() {
- // eslint-disable-next-line @typescript-eslint/no-this-alias
- let panel: MenuPanel = this
- while (panel.parentPanel) {
- panel = panel.parentPanel
- }
- return panel
- }
-
- position(parent: HTMLElement, direction: Direction, padding = 2) {
- arrange(this.dom, parent, direction, padding)
- }
-}
-
-export { MenuPanel }
diff --git a/mirror-2/splat/src/ui/menu.scss b/mirror-2/splat/src/ui/menu.scss
deleted file mode 100644
index 74bc6624..00000000
--- a/mirror-2/splat/src/ui/menu.scss
+++ /dev/null
@@ -1,94 +0,0 @@
-#menu {
- position: absolute;
-}
-
-#menu-bar {
- transition: width 0.1s ease;
-
- position: absolute;
- top: 24px;
- left: 24px;
- width: 320px;
- height: 50px;
- border-radius: 8px;
-
- overflow: hidden;
-
- background-color: $bcg-primary;
-
- display: flex;
- flex-direction: row;
- align-items: center;
-}
-
-#app-icon {
- width: 54px;
- font-family: 'pc-icon';
-
- cursor: pointer;
-}
-
-#menu-arrow {
- display: none;
-}
-
-#menu-container {
- display: flex;
- flex-direction: column;
-}
-
-#menu-options-container {
- display: flex;
- flex-direction: row;
- flex-grow: 1;
-}
-
-.menu-icon {
- width: 16px;
- height: 16px;
- padding: 16px 10px;
- margin: 0px;
- flex-grow: 1;
- color: $text-secondary;
-
- cursor: pointer;
- &:hover {
- color: $text-primary;
- background-color: $bcg-dark;
- }
-}
-
-.menu-option {
- padding: 16px 20px;
- margin: 0px;
- flex-grow: 1;
- text-align: center;
- text-overflow: clip;
-
- background-color: $bcg-primary;
-
- cursor: pointer;
-
- &:hover {
- color: $text-primary;
- background-color: $bcg-dark;
- }
-}
-
-.collapsed {
- #menu-bar {
- width: 90px;
- }
-
- #menu-collapse {
- display: none;
- }
-
- #menu-arrow {
- display: block;
- }
-
- .menu-option {
- display: none;
- }
-}
\ No newline at end of file
diff --git a/mirror-2/splat/src/ui/menu.tsx b/mirror-2/splat/src/ui/menu.tsx
deleted file mode 100644
index 4dbeb268..00000000
--- a/mirror-2/splat/src/ui/menu.tsx
+++ /dev/null
@@ -1,333 +0,0 @@
-'use client'
-import React, { useState, useEffect, useRef } from 'react'
-import {
- Container,
- Element as PCUIElement,
- Label as PCUILabel,
- BooleanInput
-} from '@playcanvas/pcui'
-import { Events } from '../events'
-import { MenuPanel } from './menu-panel'
-import { localize } from './localization'
-
-import logoSvg from '../svg/playcanvas-logo.svg'
-import collapseSvg from '../svg/collapse.svg'
-import arrowSvg from '../svg/arrow.svg'
-import sceneNew from '../svg/new.svg'
-import sceneOpen from '../svg/open.svg'
-import sceneSave from '../svg/save.svg'
-import sceneExport from '../svg/export.svg'
-import sceneImport from '../svg/import.svg'
-import selectAll from '../svg/select-all.svg'
-import selectNone from '../svg/select-none.svg'
-import selectInverse from '../svg/select-inverse.svg'
-import selectLock from '../svg/select-lock.svg'
-import selectUnlock from '../svg/select-unlock.svg'
-import selectDelete from '../svg/delete.svg'
-
-const createSvg = (svgString: any) => {
- return new PCUIElement({
- dom: new DOMParser().parseFromString(svgString, 'image/svg+xml')
- .documentElement
- })
-}
-
-const Menu = ({ events }: { events: any }) => {
- const [allDataToggle, setAllDataToggle] = useState(true)
- const [menuPanels, setMenuPanels] = useState({
- sceneMenuPanel: null,
- exportMenuPanel: null,
- selectionMenuPanel: null,
- helpMenuPanel: null
- })
- const menubarRef = useRef(null)
-
- useEffect(() => {
- const menubar = new Container({
- id: 'menu-bar'
- })
-
- menubar.dom.addEventListener('pointerdown', (event) => {
- event.stopPropagation()
- })
-
- const iconDom = document.createElement('img')
- iconDom.src = logoSvg
- iconDom.setAttribute('id', 'app-icon')
- iconDom.addEventListener('pointerdown', (event) => {
- window.open('https://playcanvas.com', '_blank').focus()
- })
-
- const icon = new PCUIElement({
- dom: iconDom
- })
-
- const scene = new PCUILabel({
- text: localize('scene'),
- class: 'menu-option'
- })
-
- const selection = new PCUILabel({
- text: localize('selection'),
- class: 'menu-option'
- })
-
- const help = new PCUILabel({
- text: localize('help'),
- class: 'menu-option'
- })
-
- const toggleCollapsed = () => {
- document.body.classList.toggle('collapsed')
- }
-
- if (document.body.clientWidth < 600) {
- toggleCollapsed()
- }
-
- const collapse = createSvg(collapseSvg)
- collapse.dom.classList.add('menu-icon')
- collapse.dom.setAttribute('id', 'menu-collapse')
- collapse.dom.addEventListener('click', toggleCollapsed)
-
- const arrow = createSvg(arrowSvg)
- arrow.dom.classList.add('menu-icon')
- arrow.dom.setAttribute('id', 'menu-arrow')
- arrow.dom.addEventListener('click', toggleCollapsed)
-
- const buttonsContainer = new Container({
- id: 'menu-options-container'
- })
- buttonsContainer.append(scene)
- buttonsContainer.append(selection)
- buttonsContainer.append(help)
- buttonsContainer.append(collapse)
- buttonsContainer.append(arrow)
-
- menubar.append(icon)
- menubar.append(buttonsContainer)
-
- const exportMenuPanel = new MenuPanel([
- {
- text: localize('scene.export.compressed-ply'),
- icon: createSvg(sceneExport),
- onSelect: () => events.invoke('scene.export', 'compressed-ply'),
- isEnabled: () => !events.invoke('scene.empty')
- },
- {
- text: localize('scene.export.splat'),
- icon: createSvg(sceneExport),
- onSelect: () => events.invoke('scene.export', 'splat'),
- isEnabled: () => !events.invoke('scene.empty')
- }
- ])
-
- const sceneMenuPanel = new MenuPanel([
- {
- text: localize('scene.new'),
- icon: createSvg(sceneNew),
- onSelect: () => events.invoke('scene.new')
- },
- {
- text: localize('scene.open'),
- icon: createSvg(sceneOpen),
- onSelect: async () => {
- if (await events.invoke('scene.new')) {
- events.fire('scene.open')
- }
- }
- },
- {
- text: localize('scene.import'),
- icon: createSvg(sceneImport),
- onSelect: () => events.fire('scene.open')
- },
- {
- text: localize('scene.load-all-data'),
- extra: new BooleanInput({ value: allDataToggle }),
- onSelect: () => {
- events.fire('toggleAllData')
- setAllDataToggle(!allDataToggle)
- sceneMenuPanel.hidden = false
- }
- },
- {
- text: localize('scene.save'),
- icon: createSvg(sceneSave),
- onSelect: () => events.fire('scene.save'),
- isEnabled: () => !events.invoke('scene.empty')
- },
- {
- text: localize('scene.save-as'),
- icon: createSvg(sceneSave),
- onSelect: () => events.fire('scene.saveAs'),
- isEnabled: () => !events.invoke('scene.empty')
- },
- {
- text: localize('scene.export'),
- icon: createSvg(sceneExport),
- subMenu: exportMenuPanel
- }
- ])
-
- const selectionMenuPanel = new MenuPanel([
- {
- text: localize('selection.all'),
- icon: createSvg(selectAll),
- extra: 'A',
- onSelect: () => events.fire('select.all')
- },
- {
- text: localize('selection.none'),
- icon: createSvg(selectNone),
- extra: 'Shift + A',
- onSelect: () => events.fire('select.none')
- },
- {
- text: localize('selection.invert'),
- icon: createSvg(selectInverse),
- extra: 'I',
- onSelect: () => events.fire('select.invert')
- },
- {
- text: localize('selection.lock'),
- icon: createSvg(selectLock),
- extra: 'H',
- onSelect: () => events.fire('select.hide')
- },
- {
- text: localize('selection.unlock'),
- icon: createSvg(selectUnlock),
- extra: 'U',
- onSelect: () => events.fire('select.unhide')
- },
- {
- text: localize('selection.delete'),
- icon: createSvg(selectDelete),
- extra: 'Delete',
- onSelect: () => events.fire('select.delete')
- },
- {
- text: localize('selection.reset'),
- onSelect: () => events.fire('scene.reset')
- }
- ])
-
- const helpMenuPanel = new MenuPanel([
- {
- text: localize('help.shortcuts'),
- icon: 'E136',
- onSelect: () => events.fire('show.shortcuts')
- },
- {
- text: localize('help.user-guide'),
- icon: 'E232',
- onSelect: () =>
- window
- .open(
- 'https://github.com/playcanvas/supersplat/blob/main/docs/index.md#supersplat-user-guide',
- '_blank'
- )
- .focus()
- },
- {
- text: localize('help.log-issue'),
- icon: 'E336',
- onSelect: () =>
- window
- .open('https://github.com/playcanvas/supersplat/issues', '_blank')
- .focus()
- },
- {
- text: localize('help.github-repo'),
- icon: 'E259',
- onSelect: () =>
- window
- .open('https://github.com/playcanvas/supersplat', '_blank')
- .focus()
- },
- {
- text: localize('help.discord'),
- icon: 'E233',
- onSelect: () =>
- window.open('https://discord.gg/T3pnhRTTAY', '_blank').focus()
- },
- {
- text: localize('help.forum'),
- icon: 'E432',
- onSelect: () =>
- window.open('https://forum.playcanvas.com', '_blank').focus()
- },
- {
- text: localize('help.about'),
- icon: 'E138',
- onSelect: () => events.invoke('show.about')
- }
- ])
-
- setMenuPanels({
- sceneMenuPanel,
- exportMenuPanel,
- selectionMenuPanel,
- helpMenuPanel
- })
-
- menubarRef.current.appendChild(menubar.dom)
- }, [events, allDataToggle])
-
- useEffect(() => {
- const options = [
- {
- dom: menuPanels.sceneMenuPanel?.dom,
- menuPanel: menuPanels.sceneMenuPanel
- },
- {
- dom: menuPanels.selectionMenuPanel?.dom,
- menuPanel: menuPanels.selectionMenuPanel
- },
- {
- dom: menuPanels.helpMenuPanel?.dom,
- menuPanel: menuPanels.helpMenuPanel
- }
- ]
-
- const activate = (option) => {
- option.menuPanel.position(option.dom, 'bottom', 2)
- options.forEach((opt) => (opt.menuPanel.hidden = opt !== option))
- }
-
- options.forEach((option) => {
- option.dom?.addEventListener('pointerdown', (event) => {
- if (!option.menuPanel.hidden) {
- option.menuPanel.hidden = true
- } else {
- activate(option)
- }
- })
-
- option.dom?.addEventListener('pointerenter', (event) => {
- if (!options.every((opt) => opt.menuPanel.hidden)) {
- activate(option)
- }
- })
- })
-
- const checkEvent = (event) => {
- if (!menubarRef.current.contains(event.target)) {
- options.forEach((opt) => (opt.menuPanel.hidden = true))
- }
- }
-
- window.addEventListener('pointerdown', checkEvent, true)
- window.addEventListener('pointerup', checkEvent, true)
-
- return () => {
- window.removeEventListener('pointerdown', checkEvent, true)
- window.removeEventListener('pointerup', checkEvent, true)
- }
- }, [menuPanels])
-
- return
-}
-
-export { Menu }
diff --git a/mirror-2/splat/src/ui/mode-toggle.scss b/mirror-2/splat/src/ui/mode-toggle.scss
deleted file mode 100644
index 242eb22d..00000000
--- a/mirror-2/splat/src/ui/mode-toggle.scss
+++ /dev/null
@@ -1,43 +0,0 @@
-
-#mode-toggle {
- position: absolute;
- left: calc(50% - 60px);
- top: 0px;
- width: 120px;
-
- padding: 0px 8px;
- border-radius: 0px 0px 8px 8px;
-
- background-color: $bcg-dark;
-
- display: flex;
- flex-direction: row;
- align-items: center;
- justify-content: center;
-
- cursor: pointer;
-
- &.centers-mode {
- #rings-icon, #rings-text {
- display: none;
- }
- }
-
- &.rings-mode {
- #centers-icon, #centers-text {
- display: none;
- }
- }
-
- #centers-icon {
- color: $clr-hilight;
- }
-
- #rings-icon {
- color: $clr-hilight;
- }
-
- &:hover {
- color: $text-primary;
- }
-}
\ No newline at end of file
diff --git a/mirror-2/splat/src/ui/mode-toggle.ts b/mirror-2/splat/src/ui/mode-toggle.ts
deleted file mode 100644
index d96de233..00000000
--- a/mirror-2/splat/src/ui/mode-toggle.ts
+++ /dev/null
@@ -1,71 +0,0 @@
-import { Container, Element, Label } from '@playcanvas/pcui'
-import { Events } from '../events'
-import { Tooltips } from './tooltips'
-import { localize } from './localization'
-
-import centersSvg from '../svg/centers.svg'
-import ringsSvg from '../svg/rings.svg'
-
-const createSvg = () => {
- const svgString = `
-
- `
- return new Element({
- dom: new DOMParser().parseFromString(svgString, 'image/svg+xml')
- .documentElement
- })
-}
-
-class ModeToggle extends Container {
- constructor(events: Events, tooltips: Tooltips, args = {}) {
- args = {
- id: 'mode-toggle',
- class: 'centers-mode',
- ...args
- }
-
- super(args)
-
- const centersIcon = new Element({
- id: 'centers-icon',
- dom: createSvg(centersSvg)
- })
-
- const ringsIcon = new Element({
- id: 'rings-icon',
- dom: createSvg(ringsSvg)
- })
-
- const centersText = new Label({
- id: 'centers-text',
- text: localize('mode.centers')
- })
-
- const ringsText = new Label({
- id: 'rings-text',
- text: localize('mode.rings')
- })
-
- this.append(centersIcon)
- this.append(ringsIcon)
- this.append(centersText)
- this.append(ringsText)
-
- this.dom.addEventListener('pointerdown', (event) => {
- event.stopPropagation()
- events.fire('camera.toggleMode')
- events.fire('camera.setOverlay', true)
- })
-
- events.on('camera.mode', (mode: string) => {
- this.class[mode === 'centers' ? 'add' : 'remove']('centers-mode')
- this.class[mode === 'rings' ? 'add' : 'remove']('rings-mode')
- })
-
- tooltips.register(this, localize('tooltip.splat-mode'))
- }
-}
-
-export { ModeToggle }
diff --git a/mirror-2/splat/src/ui/panel.scss b/mirror-2/splat/src/ui/panel.scss
deleted file mode 100644
index 8d185d29..00000000
--- a/mirror-2/splat/src/ui/panel.scss
+++ /dev/null
@@ -1,55 +0,0 @@
-.panel {
- position: absolute;
- border-radius: 8px;
- overflow: hidden;
-
- background-color: $bcg-primary;
-
- & > .panel-header {
- display: flex;
- flex-direction: row;
- align-items: center;
- padding: 2px;
-
- background-color: $bcg-dark;
-
- & > .panel-header-icon {
- font-family: pc-icon;
- font-weight: bold;
- font-size: 13px;
- color: $clr-hilight;
- }
-
- & > .panel-header-label {
- color: $text-primary;
- font-weight: bold;
- flex-grow: 1;
- }
-
- & > .panel-header-button {
- font-family: pc-icon;
- font-weight: bold;
- font-size: 13px;
- color: $clr-hilight;
-
- padding: 4px;
-
- svg {
- color: $clr-hilight;
- }
-
- &:hover {
- color: #ff9900;
- cursor: pointer;
- }
- }
-
- & > .panel-header-spacer {
- width: 2px;
- height: 28px;
- padding: 0px;
- margin: 0px;
- background-color: $bcg-primary;
- }
- }
-}
diff --git a/mirror-2/splat/src/ui/pcui-theme-grey.scss b/mirror-2/splat/src/ui/pcui-theme-grey.scss
deleted file mode 100644
index e804c7ae..00000000
--- a/mirror-2/splat/src/ui/pcui-theme-grey.scss
+++ /dev/null
@@ -1,2902 +0,0 @@
-$bcg-darkest: #202020;
-$bcg-darker: #202020;
-$bcg-dark: #282828;
-$bcg-primary: #333;
-$text-darkest: rgb(170 170 170 / 50%);
-$text-dark: rgb(170 170 170 / 50%);
-$text-secondary: #aaa;
-$text-primary: #fff;
-$text-active: #f60;
-$error: #fb222f;
-$error-secondary: #d34141;
-$border-primary: #aaa;
-$element-shadow-hover: 0 0 2px 1px rgb(255 102 0 / 30%);
-$element-shadow-active: 0 0 0 1px rgb(255 102 0 / 30%);
-$element-shadow-error: 0 0 0 1px $error-secondary;
-$element-color-placeholder: #829193;
-
-$field-padding: 3px;
-$disabled-opacity: 0.4;
-$element-margin: 6px;
-$element-opacity-disabled: 0.4;
-$element-opacity-readonly: 0.7;
-
-$playicons-regular: url('data:application/font-woff;charset=utf-7;base64,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')
- format('woff');
-
-@font-face {
- font-family: pc-icon;
- src: $playicons-regular;
- font-weight: normal;
- font-style: normal;
-}
-
-.font-icon {
- font-family: pc-icon;
-}
-
-.font-thin {
- font-weight: 100;
- font-style: normal;
-}
-
-.font-light {
- font-weight: 200;
- font-style: normal;
-}
-
-.font-regular {
- font-weight: normal;
- font-style: normal;
-}
-
-.font-bold {
- font-weight: bold;
- font-style: normal;
-}
-
-.fixed-font {
- font-family: inconsolatamedium, Monaco, Menlo, 'Ubuntu Mono', Consolas,
- source-code-pro, monospace;
- font-weight: normal;
- font-size: 12px;
-}
-
-/* Apply scrollbar styles globally */
-* {
- /* Webkit-based browsers */
- &::-webkit-scrollbar {
- width: 8px;
- height: 8px;
- }
-
- &::-webkit-scrollbar-track {
- background: $bcg-darkest;
- }
-
- &::-webkit-scrollbar-thumb {
- background: $text-darkest;
- }
-
- &::-webkit-scrollbar-thumb:hover {
- background: $text-active;
- }
-
- &::-webkit-scrollbar-corner {
- background: $bcg-dark;
- }
-
- /* Standardized Properties */
- @supports not selector(::-webkit-scrollbar) {
- /* Firefox */
- scrollbar-width: thin;
- scrollbar-color: $text-darkest $bcg-darkest;
- }
-}
-
-.pcui-no-select {
- -webkit-touch-callout: none;
- user-select: none;
-}
-
-// flex container
-.pcui-flex {
- &:not(.pcui-hidden) {
- display: flex;
- }
-
- flex-direction: column;
-}
-
-// grid container
-.pcui-grid {
- display: grid;
-}
-
-// scrollable element
-.pcui-scrollable {
- // show scrollbars automatically
- overflow: auto;
-}
-
-// Components
-// Element styling
-@keyframes pcui-flash-animation {
- from {
- outline-color: $text-active;
- }
- to {
- outline-color: rgba($text-active, 0);
- }
-}
-
-.pcui-element {
- @extend .font-regular;
-
- border: 0 solid $border-primary;
-
- &.flash {
- outline: 1px solid $text-active;
- animation: pcui-flash-animation 200ms ease-in-out forwards;
- }
-
- &:focus {
- outline: none;
- }
-
- // remove dotted border on focused elements in firefox
- &::-moz-focus-inner {
- border: 0;
- }
-}
-
-.pcui-element.pcui-hidden {
- display: none;
-}
-
-.pcui-input-element {
- display: inline-block;
- border: 1px solid $bcg-darker;
- border-radius: 2px;
- box-sizing: border-box;
- margin: $element-margin;
- min-height: 24px;
- height: 24px;
- background-color: $bcg-dark;
- vertical-align: top;
- transition:
- color 100ms,
- background-color 100ms,
- box-shadow 100ms;
- position: relative;
- color: $text-secondary;
-
- > input {
- height: 100%;
- width: calc(100% - 16px);
- padding: 0 $element-margin;
- line-height: 1;
- color: inherit;
- background: transparent;
- border: none;
- outline: none;
- box-shadow: none;
-
- @extend .fixed-font;
- }
-
- &::before {
- color: inherit;
- }
-}
-
-.pcui-input-element.pcui-multiple-values {
- &::before {
- position: absolute;
- padding: 0 8px;
- content: '...';
- white-space: nowrap;
-
- @extend .fixed-font;
-
- top: 5px;
- font-size: 12px;
- }
-}
-
-// focus / hover states
-.pcui-input-element:not(.pcui-disabled, .pcui-readonly) {
- &:hover {
- background-color: $bcg-darker;
- color: $text-primary;
- }
-
- &:not(.pcui-error):hover {
- box-shadow: $element-shadow-hover;
- }
-
- &.pcui-focus {
- background-color: $bcg-darkest;
- box-shadow: $element-shadow-active;
- }
-}
-
-.pcui-input-element {
- &.pcui-focus,
- &:hover {
- &::after,
- &::before {
- display: none;
- }
- }
-}
-
-// readonly state
-.pcui-input-element.pcui-readonly {
- background-color: transparentize(
- $color: $bcg-dark,
- $amount: 1 - $element-opacity-readonly
- );
- border-color: transparent;
-}
-
-// disabled state
-.pcui-input-element.pcui-disabled {
- color: $text-darkest;
-}
-
-// error state
-.pcui-input-element.pcui-error {
- color: $text-secondary;
- box-shadow: $element-shadow-error;
-}
-
-// placeholder
-.pcui-input-element[placeholder] {
- position: relative;
-
- &::after {
- content: attr(placeholder);
- background-color: $bcg-dark;
- position: absolute;
- top: 0;
- right: 0;
- padding: 0 8px;
- line-height: 22px;
- font-size: 10px;
- font-weight: 600;
- white-space: nowrap;
- color: $element-color-placeholder;
- pointer-events: none;
- }
-}
-
-.pcui-text-area-input {
- min-height: 48px;
- height: auto;
-
- > textarea {
- resize: none;
- height: 100%;
- width: calc(100% - 16px);
- padding: 0 8px;
- line-height: 22px;
- color: inherit;
- background: transparent;
- border: none;
- outline: none;
- box-shadow: none;
-
- @extend .fixed-font;
-
- min-height: 44px;
- min-width: 172px;
- }
-}
-
-.pcui-text-area-input.pcui-text-area-input-resizable-none {
- > textarea {
- resize: none;
- }
-}
-
-.pcui-text-area-input.pcui-text-area-input-resizable-both {
- > textarea {
- resize: both;
- }
-}
-
-.pcui-text-area-input.pcui-text-area-input-resizable-horizontal {
- > textarea {
- resize: horizontal;
- }
-}
-
-.pcui-text-area-input.pcui-text-area-input-resizable-vertical {
- > textarea {
- resize: vertical;
- }
-}
-
-.pcui-numeric-input-slider-control {
- display: none;
- position: absolute;
- width: 10px;
- height: 10px;
- right: 3px;
- border: 2px solid $bcg-darkest;
- background-color: $bcg-darker;
- border-radius: 100px;
- z-index: 9999;
- transform: translateY(-50%);
- top: 50%;
- cursor: ew-resize;
-}
-
-.pcui-numeric-input-slider-control::after {
- content: '\E408';
- font-size: 15px;
- font-family: pc-icon;
- position: absolute;
- left: -5px;
- top: -5px;
- transform: rotateZ(90deg);
-}
-
-.pcui-numeric-input-slider-control:hover {
- opacity: 0.5;
- color: $text-secondary;
-}
-
-.pcui-numeric-input-slider-control-active {
- opacity: 1 !important;
- color: #7f7 !important;
-}
-
-.pcui-numeric-input-slider-control-hidden {
- display: none !important;
-}
-
-.pcui-numeric-input:hover {
- .pcui-numeric-input-slider-control {
- display: block;
- }
-}
-
-.pcui-numeric-input.pcui-disabled:hover {
- .pcui-numeric-input-slider-control {
- display: none;
- }
-}
-
-.pcui-numeric-input.pcui-disabled,
-.pcui-numeric-input.pcui-readonly {
- .pcui-numeric-input-slider-control {
- display: none;
- }
-}
-
-.pcui-slider {
- @extend .pcui-no-select;
-
- display: inline-flex;
- height: 24px;
- margin: $element-margin;
- align-items: center;
- touch-action: none; // Prevents gestures and touch event interference.
-
- > .pcui-numeric-input {
- flex: 1;
- margin-left: 0;
- }
-}
-
-.pcui-slider-container {
- flex: 3;
-}
-
-.pcui-slider-bar {
- position: relative;
- width: calc(100% - 18px);
- height: 4px;
- margin: 9px 8px;
- background-color: $bcg-dark;
- border: 1px solid $bcg-darker;
-}
-
-.pcui-slider-handle {
- position: absolute;
- top: -7px;
- left: 0;
- margin-left: -9px;
- width: 8px;
- height: 16px;
- background-color: $text-darkest;
- border: 1px solid $bcg-darker;
- transition: left 100ms ease;
-
- &:hover,
- &:focus {
- outline: none;
- }
-}
-
-// active state
-.pcui-slider-active {
- .pcui-slider-bar {
- border-color: $bcg-darkest;
- background-color: $bcg-darkest;
- }
-
- .pcui-slider-handle {
- border-color: $bcg-darkest;
- background-color: $text-primary;
- transition: none;
- }
-}
-
-// hover state
-.pcui-slider:not(.pcui-disabled, .pcui-readonly) {
- .pcui-slider-handle {
- &:focus,
- &:hover {
- cursor: ew-resize;
- outline: none;
- border-color: $bcg-darkest;
- background-color: $text-primary;
- }
- }
-}
-
-.pcui-slider {
- cursor: pointer;
- &.pcui-slider-active {
- cursor: ew-resize;
- }
-}
-// readonly state (hide slider)
-.pcui-slider.pcui-readonly {
- .pcui-numeric-input {
- flex: 1;
- }
-
- .pcui-slider-bar {
- display: none;
- }
-}
-
-// multiple values
-.pcui-slider.pcui-multiple-values {
- .pcui-slider-handle {
- display: none;
- }
-}
-
-.pcui-vector-input {
- @extend .pcui-flex;
-
- flex-direction: row;
- align-items: center;
-
- > .pcui-numeric-input {
- flex: 1;
- margin: $element-margin calc($element-margin / 2);
-
- &:first-child {
- margin-left: 0;
- }
-
- &:last-child {
- margin-right: 0;
- }
- }
-}
-
-// boolean input
-.pcui-boolean-input {
- display: inline-block;
- position: relative;
- box-sizing: border-box;
- background-color: $bcg-dark;
- color: #fff;
- width: 14px;
- height: 14px;
- line-height: 1;
- overflow: hidden;
- margin: $element-margin;
- transition:
- opacity 100ms,
- background-color 100ms,
- box-shadow 100ms;
-
- &:focus {
- outline: none;
- }
-}
-
-// ticked
-.pcui-boolean-input.pcui-boolean-input-ticked {
- background-color: $text-secondary;
-
- &::after {
- @extend .font-icon;
-
- content: '\E372';
- color: $bcg-darkest;
- background-color: inherit;
- font-size: 19px;
- display: block;
- margin-top: -2px;
- margin-left: -2px;
- }
-}
-
-// hover / focus
-.pcui-boolean-input:not(.pcui-disabled, .pcui-readonly) {
- &:hover,
- &:focus {
- cursor: pointer;
- background-color: $bcg-darker;
- box-shadow: $element-shadow-hover;
- }
-
- &.pcui-boolean-input-ticked {
- &:hover,
- &:focus {
- background-color: $text-secondary;
- }
- }
-}
-
-// disabled state
-.pcui-boolean-input.pcui-disabled {
- opacity: $element-opacity-disabled;
-}
-
-// showing multiple values
-.pcui-boolean-input.pcui-multiple-values {
- &::after {
- position: absolute;
- font-size: 17px;
- font-weight: bold;
- color: $text-secondary;
- left: 4px;
- top: -3px;
- content: '-';
- }
-}
-
-// toggle type
-.pcui-boolean-input-toggle {
- display: inline-block;
- position: relative;
- width: 30px;
- height: 16px;
- border-radius: 8px;
- flex-shrink: 0;
- border: 1px solid $bcg-darker;
- box-sizing: border-box;
- background-color: $bcg-primary;
- color: #fff;
- line-height: 1;
- overflow: hidden;
- margin: $element-margin;
- transition:
- opacity 100ms,
- background-color 100ms,
- box-shadow 100ms;
-
- &:focus {
- outline: none;
- }
-
- &::after {
- content: '\00a0';
- position: absolute;
- top: 1px;
- left: 1px;
- width: 12px;
- height: 12px;
- border-radius: 6px;
- background-color: $text-darkest;
- transition:
- left 100ms ease,
- background-color 100ms ease;
- }
-}
-
-// ticked
-.pcui-boolean-input-toggle.pcui-boolean-input-ticked {
- border-color: $bcg-darker;
-
- &::after {
- left: 15px;
- background-color: mix($text-darkest, #7f7, 50%);
- }
-}
-
-// hover focus
-.pcui-boolean-input-toggle:not(.pcui-disabled, .pcui-readonly) {
- &:hover,
- &:focus {
- cursor: pointer;
- border-color: $bcg-darkest;
- background-color: $bcg-darkest;
- box-shadow: $element-shadow-hover;
-
- &::after {
- background-color: $error-secondary;
- }
- }
-
- &.pcui-boolean-input-ticked {
- &:hover,
- &:focus {
- border-color: $bcg-darkest;
- background-color: $bcg-darkest;
- }
-
- &::after {
- background-color: #7f7;
- }
- }
-}
-
-// readonly
-.pcui-boolean-input-toggle.pcui-readonly {
- opacity: $element-opacity-readonly;
-}
-
-// disabled
-.pcui-boolean-input-toggle.pcui-disabled {
- opacity: $element-opacity-disabled;
-}
-
-// multiple values
-.pcui-boolean-input-toggle.pcui-multiple-values {
- &::after {
- left: 8px;
- background-color: rgba($text-dark, 0.25);
- }
-}
-
-.pcui-label {
- display: inline-block;
- box-sizing: border-box;
- margin: $element-margin;
- vertical-align: middle;
- transition: opacity 100ms;
- color: $text-secondary;
- white-space: nowrap;
- overflow: hidden;
- text-overflow: ellipsis;
- user-select: none;
-}
-
-.pcui-label.pcui-default-mousedown {
- user-select: initial;
-}
-
-.pcui-label.pcui-multiple-values {
- position: relative;
- color: transparent;
-
- &::before {
- content: '...';
- color: $text-secondary;
- white-space: nowrap;
-
- @extend .fixed-font;
-
- font-size: 12px;
- }
-}
-
-.pcui-label.pcui-error {
- color: $error-secondary;
-}
-
-.pcui-label.pcui-selectable {
- &:hover {
- color: $text-active;
- text-decoration: underline;
-
- @extend .pcui-no-select;
- }
-}
-
-// placeholder
-.pcui-label[placeholder] {
- position: relative;
-
- &::after {
- content: attr(placeholder);
- position: absolute;
- top: 0;
- right: 0;
- padding: 0 8px;
- color: #999;
- pointer-events: none;
- }
-}
-
-// buttons
-.pcui-button {
- @extend .pcui-no-select;
-
- display: inline-block;
- border: 1px solid $bcg-darkest;
- border-radius: 2px;
- box-sizing: border-box;
- background-color: $bcg-dark;
- color: $text-secondary;
- padding: 0 8px;
- margin: $element-margin;
- height: 28px;
- line-height: 28px;
- max-height: 100%;
- vertical-align: middle;
- font-size: 12px;
- font-weight: 600;
- text-align: center;
- white-space: nowrap;
- cursor: pointer;
- transition:
- color 100ms,
- opacity 100ms,
- box-shadow 100ms;
- overflow: hidden;
- text-overflow: ellipsis;
-}
-
-// icon
-.pcui-button[data-icon] {
- // show icon using data-icon attribute
- // as the content
- &::before {
- content: attr(data-icon);
-
- @extend .font-icon;
-
- font-weight: 100;
- font-size: inherit;
- margin-right: $element-margin;
- vertical-align: middle;
- }
-
- // remove right margin from icons
- // if the button has no text
- &:empty {
- &::before {
- margin-right: 0;
- }
- }
-}
-
-// focus / hover states
-.pcui-button:not(.pcui-disabled, .pcui-readonly) {
- &:hover,
- &:focus {
- color: $text-primary;
- background-color: $bcg-dark;
- box-shadow: $element-shadow-hover;
- }
-
- &:active {
- background-color: $bcg-darkest;
- box-shadow: none;
- }
-}
-
-// readonly states
-.pcui-button.pcui-readonly {
- opacity: $element-opacity-readonly;
- cursor: default;
-}
-
-// disabled states
-.pcui-button.pcui-disabled {
- opacity: $element-opacity-disabled;
- cursor: default;
-}
-
-// small button
-.pcui-button.pcui-small {
- height: 24px;
- line-height: 24px;
- font-size: 10px;
-}
-
-.pcui-code {
- background: #20292b;
- overflow: auto;
-
- .pcui-code-inner {
- color: #f60;
- font-family: inconsolatamedium, Monaco, Menlo, 'Ubuntu Mono', Consolas,
- source-code-pro, monospace;
- font-weight: normal;
- font-size: 10px;
- white-space: pre;
- }
-}
-
-// container element
-.pcui-container {
- // containers should be relative to each other
- position: relative;
- min-width: 0; // this fixes a lot of flex / grid issues
- min-height: 0; // this fixes a lot of flex / grid issues
-}
-
-// resizable content
-.pcui-container.pcui-resizable {
- // resizable handle
- > .pcui-resizable-handle {
- position: absolute;
- z-index: 1;
- opacity: 0;
- background-color: transparent;
- touch-action: none;
-
- &:hover {
- opacity: 1;
- }
- }
-
- // resizable handle state while resizing
- &.pcui-resizable-resizing > .pcui-resizable-handle {
- opacity: 1;
- }
-
- // horizontal handle
- &.pcui-resizable-left,
- &.pcui-resizable-right {
- > .pcui-resizable-handle {
- top: 0;
- bottom: 0;
- width: 1px;
- height: auto;
- cursor: ew-resize;
- }
- }
-
- &.pcui-resizable-left {
- > .pcui-resizable-handle {
- left: 0;
- border-left: 3px solid $bcg-darkest;
- }
- }
-
- &.pcui-resizable-right {
- > .pcui-resizable-handle {
- right: 0;
- border-right: 3px solid $bcg-darkest;
- }
- }
-
- // vertical handle
- &.pcui-resizable-top,
- &.pcui-resizable-bottom {
- > .pcui-resizable-handle {
- left: 0;
- right: 0;
- width: auto;
- height: 1px;
- cursor: ns-resize;
- }
- }
-
- &.pcui-resizable-top {
- > .pcui-resizable-handle {
- top: 0;
- border-top: 3px solid $bcg-darkest;
- }
- }
-
- &.pcui-resizable-bottom {
- > .pcui-resizable-handle {
- bottom: 0;
- border-bottom: 3px solid $bcg-darkest;
- }
- }
-}
-
-.pcui-container-dragged {
- outline: 2px solid $text-primary;
- box-sizing: border-box;
- opacity: 0.7;
- z-index: 1;
-
- // background: $bcg-darkest !important;
- // > * {
- // transition: none !important;
- // visibility: hidden;
- // }
-}
-
-.pcui-container-dragged-child {
- outline: 1px dotted $text-active;
- box-sizing: border-box;
-}
-
-.pcui-canvas {
- @extend .pcui-no-select;
-}
-
-// color input
-.pcui-color-input {
- @extend .pcui-no-select;
-
- position: relative;
- display: inline-block;
- box-sizing: border-box;
- width: 44px;
- height: 24px;
- margin: $element-margin;
- vertical-align: top;
- cursor: pointer;
- transition: opacity 100ms;
-
- > .pcui-overlay-clickable {
- position: fixed;
- }
-
- > div {
- position: absolute;
- inset: 0;
- }
-
- // checkerboard pattern
- // @include checkerboard(#fff, black, calc(44px/5));
-
- &::after {
- content: '\00a0';
- position: absolute;
- bottom: 0;
- right: 0;
- width: 0;
- height: 0;
- background-color: transparent;
- border-bottom: 16px solid $bcg-darker;
- border-left: 16px solid transparent;
- }
-}
-
-.picker-color {
- &.c-1 > .pcui-overlay-content {
- > .pick-opacity {
- display: block;
- }
-
- > .fields > .field-r {
- display: block;
- }
- }
-
- &.c-2 > .pcui-overlay-content {
- > .fields > .field-hex {
- display: block;
- }
- }
-
- &.c-3 > .pcui-overlay-content {
- width: 298px;
-
- > .pick-rect {
- display: block;
- }
-
- > .pick-hue {
- display: block;
- }
-
- > .pick-opacity {
- display: none;
- }
-
- > .fields {
- > .field-g,
- > .field-b {
- display: block;
- }
- }
- }
-
- &.c-4 > .pcui-overlay-content {
- width: 320px;
-
- > .pick-opacity {
- display: block;
- }
-
- > .fields > .field-a {
- display: block;
- }
- }
-
- > .pcui-overlay-content {
- border: 1px solid #000;
- width: 320px;
- height: 162px;
-
- // background-color: #333;
- white-space: nowrap;
- transition: none;
-
- > .pick-rect {
- @extend .pcui-no-select;
-
- position: relative;
- display: none;
- float: left;
- width: 146px;
- height: 146px;
- border: 1px solid #000;
- box-sizing: border-box;
- margin: 8px 0 8px 8px;
- background-color: #f00;
- touch-action: none;
- cursor: crosshair;
-
- > .white {
- position: absolute;
- width: 144px;
- height: 144px;
- top: 0;
- left: 0;
- background: linear-gradient(
- to right,
- rgb(255 255 255 / 100%) 0%,
- rgb(255 255 255 / 1%) 100%
- );
- }
-
- > .black {
- position: absolute;
- width: 144px;
- height: 144px;
- top: 0;
- left: 0;
- background: linear-gradient(
- to bottom,
- rgb(0 0 0 / 1%) 0%,
- rgb(0 0 0 / 100%) 100%
- );
- }
-
- > .handle {
- position: absolute;
- top: 0;
- left: 0;
- width: 12px;
- height: 12px;
- margin: -7px 0 0 -7px;
- border: 1px solid #000;
- outline: 1px solid #fff;
- }
- }
-
- > .pick-hue {
- @extend .pcui-no-select;
-
- position: relative;
- display: none;
- float: left;
- width: 14px;
- height: 146px;
- margin: 8px 0 8px 8px;
- border: 1px solid #000;
- box-sizing: border-box;
- touch-action: none;
- cursor: crosshair;
- background: #000;
- background: linear-gradient(
- to bottom,
- rgb(255 0 0 / 100%) 0%,
- rgb(255 255 0 / 100%) 16.67%,
- rgb(0 255 0 / 100%) 33.33%,
- rgb(0 255 255 / 100%) 50%,
- rgb(0 0 255 / 100%) 66.67%,
- rgb(255 0 255 / 100%) 83.33%,
- rgb(255 0 0 / 100%) 100%
- );
-
- > .handle {
- position: absolute;
- top: 0;
- left: -3px;
- width: 16px;
- height: 4px;
- margin: -3px 0 0;
- border: 1px solid #000;
- outline: 1px solid #fff;
- }
- }
-
- > .pick-opacity {
- @extend .pcui-no-select;
-
- position: relative;
- display: none;
- float: left;
- width: 12px;
- height: 144px;
- margin: 8px 0 8px 8px;
- border: 1px solid #000;
- touch-action: none;
- cursor: crosshair;
- background: #000;
- background: linear-gradient(to bottom, #fff 0%, #000 100%);
-
- > .handle {
- position: absolute;
- top: 0;
- left: -3px;
- width: 16px;
- height: 4px;
- margin: -3px 0 0;
- border: 1px solid #000;
- outline: 1px solid #fff;
- }
- }
-
- > .fields {
- float: left;
- width: 106px;
- height: 154px;
- margin: 0 0 0 8px;
- padding: 4px;
-
- > .field {
- display: none;
- width: calc(106px - 6px);
- }
- }
- }
-}
-
-.pcui-color-input.pcui-multiple-values {
- > div {
- display: none;
- }
-
- // @include checkerboard(#465659, #5b696c, calc(44px/5));
-}
-
-// readonly color input
-.pcui-color-input.pcui-readonly {
- cursor: default;
-
- &::after {
- display: none;
- }
-}
-
-// disabled color input
-.pcui-color-input.pcui-disabled {
- opacity: $element-opacity-disabled;
- cursor: default;
-}
-
-// hover / focus states
-.pcui-color-input:not(.pcui-disabled, .pcui-readonly) {
- &:hover,
- &:focus {
- box-shadow: $element-shadow-hover;
-
- &::after {
- border-bottom-color: $bcg-darkest;
- }
- }
-
- &:active {
- box-shadow: $element-shadow-active;
- }
-}
-
-.pcui-gradient {
- display: inline-block;
- flex: 1;
- height: 24px;
- box-sizing: border-box;
- margin: $element-margin;
- transition:
- opacity 100ms,
- box-shadow 100ms;
- border: 1px solid $bcg-darker;
- background-color: $bcg-dark;
-
- > .pcui-canvas {
- width: 100%;
- height: 100%;
- background-color: transparent;
- }
-}
-
-// disabled gradient input
-.pcui-gradient.pcui-disabled,
-.pcui-gradient.pcui-multiple-values {
- opacity: $element-opacity-disabled;
-}
-
-// hover / focus states
-.pcui-gradient:not(.pcui-disabled, .pcui-readonly, .pcui-multiple-values) {
- &:hover,
- &:focus {
- cursor: pointer;
- box-shadow: $element-shadow-hover;
- }
-
- &:active {
- box-shadow: $element-shadow-active;
- }
-}
-
-.picker-gradient {
- > .pcui-overlay-content {
- width: 343px;
- height: 262px;
-
- > .picker-gradient-panel {
- height: 100%;
- font-size: 11px;
-
- > .show-selected-position {
- position: absolute;
- width: 18px;
- min-height: 17px !important;
- height: 17px !important;
- top: 14px;
- margin-top: 0;
- margin-bottom: 0;
- display: flex;
- align-items: center;
- text-align: center;
- color: #9ba1a3;
- background-color: #2c393c;
- border-radius: 2px;
- justify-content: center;
-
- > .show-selected-position-input {
- width: inherit;
- text-align: center;
- justify-content: center;
- font-style: normal;
- font-weight: 400;
- font-size: 12px;
- line-height: 22px;
- }
- }
-
- > .anchor-crosshair {
- position: absolute;
- top: 41.5px;
- pointer-events: none;
- background: none;
-
- > .crosshair-bar {
- background: #293538;
- width: 1px;
- height: 29px;
- position: absolute;
- top: -34px;
- left: 8px;
- }
-
- > .show-crosshair-position {
- font-style: normal;
- font-weight: 400;
- font-size: 12px;
- font-family: inconsolatamedium, Monaco, Menlo, 'Ubuntu Mono', Consolas,
- source-code-pro, monospace;
- line-height: 22px;
- position: absolute;
- width: 18px;
- min-height: 17px !important;
- height: 17px !important;
- top: 14px;
- margin-top: 0;
- margin-bottom: 0;
- display: flex;
- align-items: center;
- text-align: center;
- color: #9ba1a3;
- background-color: #2c393c;
- border-radius: 2px;
- justify-content: center;
- }
- }
-
- > .picker-gradient-gradient {
- width: 321px;
- height: 28px;
- display: block;
- padding: 8px 10px 0 11px;
- background-color: #2c393c;
-
- .crosshair-active {
- cursor: none;
- }
- }
-
- > .picker-gradient-anchors {
- width: 320px;
- height: 28px;
- display: block;
- padding: 0 10px 0 11px;
- background-color: #2c393c;
- }
-
- > .picker-gradient-footer {
- padding: 5px;
-
- > .pcui-panel-header {
- display: none;
- }
-
- > .pcui-panel-content {
- display: flex;
-
- > .pcui-label {
- align-self: center;
- font-family: inherit;
- font-style: normal;
- font-weight: 600;
- font-size: 12px;
- line-height: 19px;
- align-content: center;
- height: 20px;
- }
-
- > .pcui-select-input {
- align-self: center;
- width: 162px;
- height: 22px;
- }
-
- > .pcui-numeric-input {
- align-self: center;
- }
-
- > .pcui-button {
- width: 22px;
- height: 22px;
-
- @extend .font-icon;
-
- vertical-align: bottom;
- margin: 0;
- margin-right: 8px;
- margin-top: 6px;
- }
-
- > .copy-curve-button {
- border-color: #2c393c;
-
- &::after {
- content: '\e351';
- position: absolute;
- top: 4px;
- left: 218px;
- font-size: 15px;
- text-align: center;
-
- @extend .font-icon;
- }
- }
-
- > .paste-curve-button {
- border-color: #2c393c;
-
- &::after {
- content: '\e348';
- position: absolute;
- top: 4px;
- left: 248px;
- font-size: 15px;
- text-align: center;
-
- @extend .font-icon;
- }
- }
-
- > .delete-curve-button {
- border-color: #2c393c;
-
- &::after {
- content: '\e125';
- position: absolute;
- top: 4px;
- left: 278px;
- font-size: 15px;
- text-align: center;
-
- @extend .font-icon;
- }
- }
- }
- }
-
- > .color-panel {
- height: 156px;
-
- > .pcui-panel-header {
- display: none;
- }
-
- > .pcui-panel-content {
- > .color-rect {
- margin: 5px 10px 10px;
- width: 140px;
- height: 140px;
- cursor: crosshair;
- position: relative;
- float: left;
- border-width: 1px;
- }
-
- > .color-handle {
- position: absolute;
- width: 14px;
- height: 14px;
- border: 1px solid #000;
- outline: 1px solid #fff;
- pointer-events: none;
- }
-
- > .hue-rect,
- > .alpha-rect {
- margin: 5px 10px 10px 0;
- width: 20px;
- height: 140px;
- cursor: crosshair;
- border-width: 1px;
- }
-
- > .hue-handle,
- > .alpha-handle {
- position: absolute;
- width: 20px;
- height: 4px;
- border: 1px solid rgb(92 82 79);
- outline: 1px solid #fff;
- pointer-events: none;
- }
-
- > .fields {
- display: inline-block;
- margin: 3px 0 0;
- width: 112px;
- height: 145px;
- vertical-align: top;
-
- > .pcui-numeric-input {
- margin: 2px 0;
- width: 108px;
- }
-
- > .pcui-text-input {
- margin: 2px 0;
- min-height: 22px;
- min-width: 111px;
- }
- }
- }
- }
- }
- }
-}
-
-// panel element
-.pcui-panel {
- background-color: $bcg-primary;
-}
-
-// header of panel
-.pcui-panel-header {
- background-color: $bcg-darker;
- color: $text-primary;
- font-size: 12px;
- white-space: nowrap;
- padding-left: 10px;
- flex-shrink: 0;
- align-items: center;
-}
-
-.pcui-panel-header-title {
- overflow: hidden;
- text-overflow: ellipsis;
- flex: 1;
- color: inherit;
- font-size: inherit;
- white-space: inherit;
- margin: 0 auto 0 0;
-}
-
-// contents of panel
-.pcui-panel-content {
- flex: 1;
-}
-
-// collapsible panel
-.pcui-panel.pcui-collapsible {
- // animate height and width
- transition:
- height 100ms,
- width 100ms;
-
- // cursor pointer on header
- > .pcui-panel-header {
- cursor: pointer;
-
- // expanded icon
- &::before {
- @extend .font-icon;
-
- content: '\E179';
- font-size: 14px;
- margin-right: 10px;
- text-align: center;
- color: $text-active;
- }
-
- // header collapsible hover state
- &:hover {
- color: $text-primary;
-
- &::before {
- color: $text-primary;
- }
- }
- }
-
- &.pcui-panel-normal {
- > .pcui-panel-header::before {
- content: '\E183';
- font-weight: 200;
- }
- }
-
- // delay visibility hidden
- > .pcui-panel-content {
- transition: visibility 100ms;
- }
-
- // collapsed panel
- &.pcui-collapsed {
- // hide stuff
- overflow: hidden;
-
- // hide contents
- > .pcui-panel-content {
- visibility: hidden;
- }
-
- > .pcui-panel-header {
- // collapsed icon
- &::before {
- content: '\E180';
- }
- }
-
- &.pcui-panel-normal {
- > .pcui-panel-header::before {
- content: '\E184';
- }
- }
-
- // collapsed horizontally
- &.pcui-panel-horizontal {
- > .pcui-panel-header {
- width: 2048px; // this is to make the now vertical header really big
-
- // rotate the header 90 degrees
- transform: rotate(90deg);
- transform-origin: 0% 100%;
-
- // collapsed icon
- &::before {
- content: '\E177';
- }
- }
-
- &.pcui-panel-normal {
- > .pcui-panel-header::before {
- content: '\E181';
- }
- }
-
- // do not animate visibility
- > .pcui-panel-content {
- transition: none;
- }
- }
- }
-}
-
-// resizable panel
-.pcui-panel.pcui-resizable {
- // hide resize handle if panel is collapsed
- &.pcui-collapsible.pcui-collapsed {
- > .pcui-resizable-handle {
- display: none;
- }
- }
-
- // disable width / height transitions while resizing
- &.pcui-resizable-resizing {
- transition: none;
-
- > .pcui-panel-content {
- transition: none;
- }
- }
-}
-
-// sortable panel
-.pcui-panel-header {
- > .pcui-panel-sortable-icon {
- color: $text-darkest;
- transition: color 100ms;
-
- @extend .pcui-flex;
-
- flex-direction: row;
- align-items: center;
- margin: 0 10px 0 0;
- height: 100%;
-
- // left border
- &::before {
- content: ' ';
- border-left: 1px solid $bcg-primary;
- margin-right: 10px;
- height: calc(100% - 14px);
- flex-shrink: 0;
- }
-
- // dots
- &::after {
- content: '.. .. ..';
- white-space: normal;
- width: 12px;
- line-height: 5px;
- overflow: hidden;
- height: 24px;
- font-size: 22px;
- letter-spacing: 1px;
- flex-shrink: 0;
- }
- }
-}
-
-// hover on sortable
-.pcui-panel:not(.pcui-disabled, .pcui-readonly) {
- > .pcui-panel-header {
- > .pcui-panel-sortable-icon:hover {
- color: $text-primary;
- cursor: move;
- }
- }
-}
-
-// hide left border of sortable icon if panel is not collapsible
-.pcui-panel:not(.pcui-collapsible) {
- > .pcui-panel-header {
- > .pcui-panel-sortable-icon::before {
- display: none;
- }
- }
-}
-
-// remove button
-.pcui-panel-remove {
- align-self: flex-end;
- order: 100; // always put remove button last
- &::before {
- line-height: 30px;
- }
-}
-
-// hide remove button if readonly
-.pcui-panel.pcui-readonly {
- .pcui-panel-remove {
- display: none;
- }
-}
-
-.pcui-panel-header > .pcui-button {
- flex-shrink: 0;
- margin: 1px;
- background-color: transparent;
- border: 0;
-}
-
-// disabled panel
-.pcui-panel.pcui-disabled {
- > .pcui-panel-header {
- background-color: mix($bcg-dark, $bcg-primary, 60 * 1%);
- color: #999;
- }
-}
-
-.pcui-subpanel {
- box-sizing: border-box;
- margin: $element-margin;
- border: 1px solid $bcg-darker;
- border-radius: 2px;
- background-color: $bcg-dark;
- color: $text-secondary;
- font-size: 12px;
-
- .pcui-button {
- background-color: $bcg-primary;
- border-color: $bcg-darker;
-
- &:not(.pcui-disabled, .pcui-readonly) {
- &:hover,
- &:focus {
- background-color: $bcg-primary;
- }
-
- &:active {
- background-color: $bcg-dark;
- }
- }
- }
-}
-
-.pcui-overlay {
- width: auto;
- height: auto;
- inset: 0;
- z-index: 101;
- transition:
- opacity 100ms,
- visibility 100ms;
-
- @extend .pcui-flex;
-
- justify-content: center;
- align-items: center;
- position: absolute;
-}
-
-.pcui-overlay-inner {
- @extend .pcui-no-select;
-
- position: absolute;
- width: auto;
- height: auto;
- inset: 0;
- background-color: rgba($bcg-darkest, 0.7);
-}
-
-.pcui-overlay-clickable {
- > .pcui-overlay-inner {
- cursor: pointer;
- }
-}
-
-.pcui-overlay-transparent {
- > .pcui-overlay-inner {
- background-color: transparent;
- }
-}
-
-.pcui-overlay-content {
- background-color: $bcg-primary;
- transition:
- width 100ms,
- height 100ms,
- margin-left 100ms,
- margin-top 100ms;
- box-shadow: 7px 7px 7px rgb(0 0 0 / 15%);
-}
-
-.pcui-divider {
- height: 1px;
- background-color: $bcg-dark;
- margin: $element-margin 0;
-}
-
-.pcui-infobox {
- box-sizing: border-box;
- margin: $element-margin;
- padding: 2 * $element-margin;
- border: 1px solid $bcg-darker;
- border-radius: 2px;
- background-color: $bcg-dark;
- color: $text-secondary;
- font-size: 12px;
-
- :first-child {
- color: $text-primary;
- margin-bottom: 2px;
- }
-
- // show icon using data-icon attribute
- // as the content
- &[data-icon]:not(.pcui-hidden) {
- display: grid;
- grid: auto-flow / min-content 1fr;
-
- &::before {
- content: attr(data-icon);
-
- @extend .font-icon;
-
- font-weight: 100;
- font-size: 16px;
- margin-right: 2 * $element-margin;
- vertical-align: middle;
- grid-column: 1;
- grid-row: 1 / 3;
- }
- }
-}
-
-.pcui-select-input {
- @extend .pcui-flex;
-
- box-sizing: border-box;
- margin: $element-margin;
- border-radius: 2px;
- min-width: 0; // this prevents the element from overflowing
-}
-
-.pcui-select-input-container-value {
- @extend .pcui-flex;
-
- background-color: $bcg-dark;
- transition:
- box-shadow 100ms,
- opacity 100ms;
-}
-
-.pcui-select-input-shadow {
- position: absolute;
- width: 100%;
- height: 100%;
- transition: box-shadow 100ms;
- border-radius: 2px;
- pointer-events: none;
- z-index: 1;
-
- // &:after {
- // content: ' ';
- // width: 100%;
- // height: 2px;
- // position: absolute;
- // bottom: -1px;
- // left: 0;
- // display: block;
- // box-shadow: 0px 3px 0px $bcg-darkest;
- // }
-}
-
-.pcui-select-input-value {
- &:not(.pcui-hidden) {
- display: block;
- }
-
- margin: 0;
- padding: 0 24px 0 ($element-margin + 2px);
- height: 24px;
- line-height: 24px;
- font-size: 12px;
-
- @extend .fixed-font;
-
- transition:
- background-color 100ms,
- color 100ms;
-}
-
-.pcui-label.pcui-select-input-value {
- margin: 0;
-}
-
-.pcui-select-input-textinput {
- margin: 0;
-}
-
-.pcui-select-input-textinput:not(.pcui-disabled, .pcui-readonly, .pcui-error) {
- &.pcui-focus,
- &:hover {
- box-shadow: none;
- }
-}
-
-.pcui-label.pcui-select-input-icon {
- position: absolute;
- right: $element-margin;
- color: $text-darkest;
- pointer-events: none;
- transition: color 100ms;
- margin: 0;
- height: 24px;
- line-height: 24px;
-
- &::after {
- @extend .font-icon;
-
- content: '\E159';
- vertical-align: middle;
- }
-}
-
-.pcui-select-input-has-disabled-value
- .pcui-container.pcui-select-input-list
- .pcui-label.pcui-selected {
- &::after {
- font-family: inherit;
- content: 'fallback';
- color: $text-primary;
- font-size: 10px;
- position: absolute;
- right: 6px;
- }
-}
-
-.pcui-label.pcui-select-input-disabled-value {
- &::after {
- @extend .font-icon;
-
- content: '\e133' !important;
- position: absolute;
- right: 6px;
- }
-}
-
-.pcui-select-input.pcui-open {
- .pcui-select-input-shadow {
- box-shadow: $element-shadow-hover;
- }
-
- .pcui-select-input-value {
- color: $text-primary;
- background-color: $bcg-darkest;
- }
-
- .pcui-select-input-icon::after {
- color: $text-primary;
- content: '\E157';
- }
-}
-
-.pcui-container.pcui-select-input-list {
- position: absolute;
- z-index: 1;
- top: 100%;
- width: 100%;
- max-height: 200px;
- overflow-y: auto;
- background-color: $bcg-darker;
-
- .pcui-label {
- &:not(.pcui-hidden) {
- display: block;
- }
-
- font-size: 12px;
-
- @extend .fixed-font;
-
- height: 22px;
- line-height: 22px;
- padding: 0 24px 0 $element-margin;
- margin: 0;
- transition:
- background-color 100ms,
- color 100ms;
-
- &.pcui-selected {
- color: $text-primary;
-
- &::after {
- @extend .font-icon;
-
- content: '\E133';
- color: $text-darkest;
- position: absolute;
- right: $element-margin;
- }
- }
- }
-}
-
-.pcui-select-input-fit-height {
- .pcui-select-input-list {
- top: initial;
- bottom: 100%;
- }
-
- .pcui-select-input-shadow {
- top: initial;
- bottom: 0;
- }
-}
-
-.pcui-select-input-tags:not(.pcui-select-input-tags-empty) {
- margin-top: 1px;
- flex-wrap: wrap;
-}
-
-.pcui-select-input-tag {
- background-color: $bcg-darker;
- align-items: center;
- border-radius: 2px;
- border: 1px solid $border-primary;
- margin-right: 2px;
- margin-top: 2px;
- min-width: 0; // prevents flex overflow
- height: 18px;
-
- > * {
- margin: 0;
- background-color: transparent;
- border: 0;
- }
-
- > .pcui-label {
- padding: 0 5px 0 8px;
-
- @extend .fixed-font;
- }
-
- > .pcui-button {
- padding: 0 5px;
- height: 18px;
- line-height: 18px;
- flex-shrink: 0;
-
- &:not(.pcui-disabled, .pcui-readonly):hover {
- box-shadow: none;
- color: $error-secondary;
- }
- }
-}
-
-.pcui-select-input-tag-not-everywhere {
- > .pcui-label {
- opacity: 0.5;
-
- &::before {
- content: '*';
- margin-right: 5px;
- }
- }
-}
-
-.pcui-select-input:not(.pcui-disabled, .pcui-readonly) {
- .pcui-select-input-container-value {
- &:hover {
- .pcui-select-input-shadow {
- box-shadow: $element-shadow-hover;
- }
-
- .pcui-select-input-icon {
- color: $text-dark;
- }
- }
- }
-
- &.pcui-focus {
- .pcui-select-input-shadow {
- box-shadow: $element-shadow-hover;
- }
-
- .pcui-select-input-icon {
- color: $text-dark;
- }
- }
-
- .pcui-select-input-value:hover {
- color: $text-primary;
- background-color: $bcg-darkest;
- cursor: pointer;
- }
-
- .pcui-select-input-list {
- > *:hover,
- > .pcui-select-input-label-highlighted {
- background-color: $bcg-darkest;
- color: $text-primary;
- cursor: pointer;
- }
- }
-}
-
-.pcui-select-input-create-new {
- > .pcui-label {
- padding-right: $element-margin;
- }
-
- > .pcui-label:last-child {
- flex-shrink: 0;
- margin-left: auto;
-
- &::before {
- content: '\E120';
-
- @extend .font-icon;
-
- margin-right: $element-margin;
- }
- }
-}
-
-.pcui-select-input.pcui-disabled {
- opacity: $element-opacity-disabled;
-}
-
-.pcui-select-input {
- .pcui-label.pcui-disabled {
- opacity: $element-opacity-disabled;
- }
-}
-
-.pcui-select-input.pcui-readonly {
- .pcui-select-input-icon {
- display: none;
- }
-
- &.pcui-select-input-multi {
- .pcui-select-input-container-value {
- display: none;
- }
-
- .pcui-select-input-tag > .pcui-button {
- display: none;
- }
- }
-
- &.pcui-select-input-allow-input:not(.pcui-select-input-multi) {
- opacity: $element-opacity-readonly;
-
- .pcui-select-input-textinput::after {
- display: none;
- }
- }
-}
-
-@keyframes animation-spin {
- from {
- transform: rotate(0deg);
- }
-
- to {
- transform: rotate(360deg);
- }
-}
-
-.pcui-spinner {
- display: inline-block;
- margin: $element-margin;
- vertical-align: middle;
-
- > path {
- animation-name: animation-spin;
- animation-duration: 750ms;
- animation-iteration-count: infinite;
- animation-timing-function: linear;
- transform-origin: center;
- }
-
- &.pcui-error {
- > path {
- animation: none;
- fill: rgba(darken(#f77, 17%), 1);
-
- &.pcui-spinner-highlight {
- fill: rgba(#f77, 1);
- }
- }
- }
-}
-
-.pcui-progress {
- height: 4px;
- background-color: $bcg-darkest;
- transition: opacity 100ms;
- width: 100%;
-
- .pcui-progress-inner {
- width: 0%;
- height: inherit;
-
- $first: rgba($text-active, 1);
- $second: rgba(darken($text-active, 17%), 1);
-
- background: $text-active;
- background: linear-gradient(
- 135deg,
- $first 0%,
- $first 25%,
- $second 26%,
- $second 50%,
- $first 51%,
- $first 75%,
- $second 76%,
- $second 100%
- );
- background-position: 0 0;
- background-size: 24px 24px;
- background-repeat: repeat;
-
- // animate
- animation: pcui-progress-background 1000ms linear infinite;
- }
-}
-
-.pcui-progress.pcui-error {
- .pcui-progress-inner {
- $first: rgba(#f77, 1);
- $second: rgba(darken(#f77, 17%), 1);
-
- background: $text-active;
- background: linear-gradient(
- 135deg,
- $first 0%,
- $first 25%,
- $second 26%,
- $second 50%,
- $first 51%,
- $first 75%,
- $second 76%,
- $second 100%
- );
- background-position: 0 0;
- background-size: 24px 24px;
- background-repeat: repeat;
- animation: none;
- }
-}
-
-// ui-progress animation
-@keyframes pcui-progress-background {
- from {
- background-position: 0 0;
- }
- to {
- background-position: 24px 0;
- }
-}
-
-.pcui-treeview {
- @extend .pcui-no-select;
-
- // make sure our width covers the largest visible tree item child
- // this does not work on Edge
- min-width: max-content;
-}
-
-.pcui-treeview-item {
- position: relative;
- padding-left: 24px;
-
- // top line
- &::before {
- content: '\00a0';
- position: absolute;
- background-color: mix($bcg-dark, $bcg-primary, 50%);
- width: 2px;
- left: 14px;
- top: -12px;
- bottom: 12px;
- }
-
- // top line, last item
- &:last-child::before {
- height: 25px;
- bottom: auto;
- }
-}
-
-.pcui-treeview-item.pcui-disabled {
- > .pcui-treeview-item-contents {
- > .pcui-treeview-item-text {
- opacity: $disabled-opacity;
- }
- }
-}
-
-.pcui-treeview-item-contents {
- position: relative;
- color: $text-secondary;
- margin-left: 3px;
- border: 1px solid transparent;
- align-items: center;
- height: 24px;
- box-sizing: border-box;
-
- &:hover {
- cursor: pointer;
- color: $text-primary;
- background-color: $bcg-dark;
-
- > .pcui-treeview-item-icon {
- color: $text-primary;
- }
- }
-}
-
-.pcui-treeview-item-icon {
- color: $text-darkest;
- margin: 0 2px 0 0;
- flex-shrink: 0;
-
- &::before {
- content: '\00a0';
- position: absolute;
- background-color: mix($bcg-dark, $bcg-primary, 50%);
- left: -12px;
- top: 10px;
- width: 24px;
- height: 2px;
- }
-
- &::after {
- content: attr(data-icon);
-
- @extend .font-icon;
-
- display: inline-block;
- vertical-align: sub;
- width: 22px;
- height: 22px;
- position: relative;
- z-index: 1;
- text-align: center;
- }
-}
-
-.pcui-treeview-item-text {
- margin: 0;
- flex-shrink: 0;
- position: relative;
- z-index: 1;
- transition: opacity 100ms;
- padding-right: 8px;
- color: inherit;
-}
-
-.pcui-treeview-item-contents.pcui-treeview-item-selected {
- background-color: $bcg-darkest;
- color: $text-primary;
-
- > .pcui-treeview-item-icon {
- color: $text-primary;
- }
-}
-
-.pcui-treeview-item:not(.pcui-treeview-item-empty) {
- > .pcui-treeview-item-contents::before {
- content: '\E120';
-
- @extend .font-icon;
-
- position: absolute;
- font-size: 10px;
- font-weight: bold;
- text-align: center;
- color: $text-secondary;
- background-color: $bcg-dark;
- top: 0;
- left: -24px;
- width: 16px;
- height: 16px;
- line-height: 16px;
- margin: 3px;
- cursor: pointer;
- z-index: 1;
- }
-
- &.pcui-treeview-item-open {
- > .pcui-treeview-item-contents::before {
- content: '\E121';
- }
- }
-}
-
-.pcui-treeview {
- // direct children of tree
- > .pcui-treeview-item {
- padding-left: 0;
-
- &::before {
- content: none;
- }
-
- > .pcui-treeview-item-contents {
- margin-left: 0;
-
- > .pcui-treeview-item-icon {
- &::before {
- content: none;
- }
-
- &::after {
- margin-left: 0;
- }
- }
- }
-
- > .pcui-treeview-item {
- padding-left: 21px;
-
- // top line
- &::before {
- left: 11px;
- }
- }
- }
-}
-
-.pcui-treeview:not(.pcui-treeview-filtering) {
- // direct children of tree
- > .pcui-treeview-item {
- .pcui-treeview-item {
- &:not(.pcui-treeview-item-open, .pcui-treeview-item-empty) {
- > .pcui-treeview-item {
- display: none;
- }
- }
- }
- }
-}
-
-.pcui-treeview-item-dragged > .pcui-treeview-item-contents {
- background-color: rgba($bcg-dark, 0.5);
- color: $text-primary;
-}
-
-.pcui-treeview-drag-handle {
- position: fixed;
- width: 32px;
- height: 20px;
- top: 0;
- bottom: 0;
- z-index: 4;
- margin-top: -1px;
- margin-left: -1px;
-
- &.before {
- border-top: 4px solid $text-active;
- padding-right: 8px;
- height: 24px;
- }
-
- &.inside {
- border: 4px solid $text-active;
- }
-
- &.after {
- border-bottom: 4px solid $text-active;
- padding-right: 8px;
- height: 24px;
- }
-}
-
-.pcui-treeview-item-contents::after {
- content: ' ';
- display: block;
- clear: both;
-}
-
-.pcui-treeview-item.pcui-treeview-item-rename {
- > .pcui-treeview-item-contents {
- > .pcui-treeview-item-text {
- display: none;
- }
-
- > .pcui-text-input {
- margin: 0;
- flex-grow: 1;
- box-shadow: none !important;
- border: 0;
- background-color: transparent;
-
- > input {
- font-family: inherit;
- font-size: 14px;
- padding: 0;
- }
- }
- }
-}
-
-.pcui-treeview.pcui-treeview-filtering {
- // > .pcui-treeview-item {
- // display: none;
- // }
- .pcui-treeview-item {
- padding-left: 0;
-
- &::before {
- display: none;
- }
-
- &:not(.pcui-treeview-filtering-result) {
- > .pcui-treeview-item-contents {
- display: none;
- }
- }
- }
-
- .pcui-treeview-item-contents {
- margin-left: 0;
- }
-}
-
-.pcui-treeview-filtering-result {
- .pcui-treeview-item-contents::before,
- .pcui-treeview-item-icon::before {
- display: none;
- }
-}
-
-.pcui-label-group {
- @extend .pcui-flex;
-
- align-items: center;
- flex-flow: row nowrap;
- margin: $element-margin;
-
- // set width for label and don't let it shrink
- > .pcui-label:first-child {
- width: 100px;
- flex-shrink: 0;
- margin: 0;
- }
-
- // remove top margin from sub elements
- > .pcui-element:not(:first-child) {
- margin: 0 0 0 $element-margin;
- }
-
- // field should be stretched
- // except for ones marked
- // as specifically not flexible
- > .pcui-element:nth-child(2) {
- &:not(.pcui-not-flexible) {
- flex: 1;
- }
- }
-
- // remove top/bottom margin from vector fields
- > .pcui-vector-input {
- > .pcui-numeric-input {
- margin-top: 0;
- margin-bottom: 0;
- }
- }
-}
-
-.pcui-label-group-align-top {
- > .pcui-label:first-child {
- align-self: flex-start;
- margin-top: 4px;
- }
-}
-
-.pcui-label-group.pcui-disabled {
- > .pcui-label:first-child {
- opacity: $element-opacity-disabled;
- }
-}
-
-.pcui-gridview {
- @extend .pcui-flex;
-
- flex-flow: row wrap;
- align-content: flex-start;
-}
-
-.pcui-gridview-vertical {
- @extend .pcui-flex;
-
- flex-direction: column;
- align-content: flex-start;
-}
-
-// Gridview Regular Item
-.pcui-gridview-item {
- @extend .pcui-flex;
-
- box-sizing: border-box;
- justify-content: center;
- align-items: center;
- flex-shrink: 0;
- width: 104px;
-
- &:not(.pcui-disabled) {
- cursor: pointer;
-
- &:not(
- .pcui-gridview-item-selected,
- .pcui-gridview-radiobtn,
- .pcui-gridview-radiobtn-selected
- ):hover {
- background-color: $bcg-darker;
- }
- }
-}
-
-.pcui-gridview-item-selected {
- background-color: $bcg-darkest;
-}
-
-.pcui-gridview-item-text {
- max-width: 100px;
- font-size: 12px;
- overflow: hidden;
- text-overflow: ellipsis;
- margin: 0;
- padding: 0 2px;
-}
-
-// GridView Radio Buttons
-.pcui-gridview-radio-container {
- @extend .pcui-flex;
-
- box-sizing: border-box;
- flex-direction: row;
- justify-content: center;
- align-items: center;
- flex-shrink: 0;
- width: 104px;
-
- :not(.pcui-disabled) {
- cursor: pointer;
- }
-}
-
-.pcui-menu {
- position: absolute;
- z-index: 401;
- inset: 0;
- width: auto;
- height: auto;
-}
-
-.pcui-menu-items {
- position: fixed;
- top: 0;
- left: 0;
-}
-
-.pcui-menu-item {
- position: relative;
- background-color: $bcg-darkest;
- width: auto;
-}
-
-.pcui-menu-item-children {
- box-shadow: 0 0 8px rgb(0 0 0 / 60%);
- position: absolute;
- z-index: 1;
- left: 100%;
- top: 0;
- opacity: 0;
- transition:
- opacity 100ms,
- visibility 100ms;
- visibility: hidden;
-}
-
-.pcui-menu-item:hover {
- > .pcui-menu-item-children {
- opacity: 1;
- visibility: visible;
- }
-}
-
-.pcui-menu-item-has-children {
- & > .pcui-menu-item-content > .pcui-label {
- padding-right: 32px;
-
- &::after {
- content: '\E160';
-
- @extend .font-icon;
-
- position: absolute;
- right: $element-margin;
- }
- }
-}
-
-.pcui-menu-item-content {
- min-width: 158px;
- color: $text-dark;
- border-bottom: 1px solid mix($bcg-darkest, $bcg-dark, 50%);
- cursor: pointer;
-
- &:hover {
- color: $text-primary;
- background-color: $text-darkest;
- }
-
- > .pcui-label {
- transition: none;
- }
-}
-
-.pcui-menu-item:last-child {
- > .pcui-menu-item-content {
- border-bottom: none;
- }
-}
-
-.pcui-menu-item-content > .pcui-label {
- color: inherit;
-
- &[data-icon] {
- // show icon using data-icon attribute
- // as the content
- &::before {
- content: attr(data-icon);
-
- @extend .font-icon;
-
- font-weight: 100;
- font-size: inherit;
- margin-right: $element-margin;
- vertical-align: middle;
- }
- }
-}
-
-.pcui-menu-item.pcui-disabled {
- .pcui-menu-item-content {
- cursor: default;
-
- &:hover {
- color: $text-dark;
- background-color: transparent;
- }
-
- & > .pcui-label {
- cursor: default;
- opacity: $disabled-opacity;
- }
- }
-}
-
-// radio button
-.pcui-radio-button {
- display: inline-block;
- position: relative;
- background-color: $bcg-darker;
- color: #fff;
- width: 17px;
- height: 17px;
- border-radius: 50%;
- overflow: hidden;
- margin: $element-margin;
- transition:
- opacity 100ms,
- background-color 100ms,
- box-shadow 100ms;
-
- // outer ring
- &::before {
- content: '';
- position: absolute;
- display: block;
- left: 50%;
- top: 50%;
- width: 16px;
- min-width: 16px;
- height: 16px;
- transform: translate(-50%, -50%);
- border-radius: 50%;
- background-color: $bcg-darker;
- }
-
- // inner circle (hidden in initial state)
- &::after {
- position: absolute;
- left: 50%;
- top: 50%;
- width: 11px;
- min-width: 11px;
- height: 11px;
- transform: translate(-50%, -50%);
- border-radius: 50%;
- background-color: white;
- }
-}
-
-// selected
-.pcui-radio-button-selected {
- // outer ring
- &::before {
- width: 16px;
- min-width: 16px;
- height: 16px;
- box-sizing: border-box;
- border: 1px solid white;
- }
-
- // inner circle
- &::after {
- content: '';
- display: block;
- }
-}
-
-// readonly
-.pcui-radio-button.pcui-readonly {
- opacity: $element-opacity-readonly;
-}
-
-// disabled state
-.pcui-radio-button.pcui-disabled {
- opacity: $element-opacity-disabled;
-}
-
-// hover
-.pcui-radio-button:not(.pcui-disabled, .pcui-readonly) {
- &:hover {
- cursor: pointer;
-
- &::before {
- background-color: $bcg-darkest;
- }
- }
-}
-
-.pcui-array-input {
- margin: $element-margin;
- min-width: 0; // this prevents the element from overflowing
-
- > .pcui-numeric-input {
- margin: 0 0 $element-margin 0;
- }
-}
-
-.pcui-array-input.pcui-array-empty {
- > .pcui-numeric-input {
- margin: 0;
- }
-}
-
-.pcui-array-input-item {
- > * {
- margin-top: 1px;
- margin-bottom: 1px;
- }
-
- // field should be stretched
- // except for ones marked
- // as specifically not flexible
- // and panel headers
- > *:first-child {
- &:not(.pcui-not-flexible, .pcui-panel-header) {
- flex: 1;
- }
- }
-
- > .pcui-button {
- margin-left: - calc($element-margin / 2);
- margin-right: 0;
- background-color: transparent;
- border: 0;
- }
-}
-
-.pcui-array-input-item-asset {
- > .pcui-button {
- margin-top: 36px;
- }
-}
-
-.pcui-array-input.pcui-readonly {
- .pcui-array-input-item-delete {
- display: none;
- }
-}
diff --git a/mirror-2/splat/src/ui/playcanvas-logo.png b/mirror-2/splat/src/ui/playcanvas-logo.png
deleted file mode 100644
index a1ff05f1..00000000
Binary files a/mirror-2/splat/src/ui/playcanvas-logo.png and /dev/null differ
diff --git a/mirror-2/splat/src/ui/popup.scss b/mirror-2/splat/src/ui/popup.scss
deleted file mode 100644
index 3bf40e04..00000000
--- a/mirror-2/splat/src/ui/popup.scss
+++ /dev/null
@@ -1,95 +0,0 @@
-#popup {
- width: 100%;
- height: 100%;
-
- // background-color: rgba(0, 0, 0, 0.5);
- pointer-events: all;
-
- #popup-dialog {
- position: absolute;
- left: 50%;
- top: 50%;
- min-width: 320px;
- max-width: 480px;
- transform: translate(-50%, -50%);
-
- display: flex;
- flex-direction: column;
- overflow: hidden;
-
- border-radius: 8px;
- background-color: $bcg-primary;
-
- filter: drop-shadow(5px 5px 10px rgba(0, 0, 0, 0.8));
-
- // the following is needed to get drop-shadow working on safari
- will-change: transform;
-
- #popup-header {
- height: 32px;
- line-height: 32px;
- margin: 0px;
- padding: 0px 8px;
-
- font-weight: bold;
- color: $text-primary;
- background-color: $bcg-darker;
- }
-
- #popup-text {
- text-wrap: wrap;
- text-align: center;
- padding: 20px 10px;
-
- color: $text-primary;
-
- &::before {
- font-family: 'pc-icon';
- font-size: 16px;
- margin: 0px 10px;
- color: $text-primary;
- }
-
- &.error::before {
- content: '\E218';
- color: $error;
- }
-
- &.info::before {
- content: '\E400';
- }
-
- &.yesno::before {
- content: '\E138';
- }
-
- &.okcancel::before {
- content: '\E138';
- }
- }
-
- #popup-text-input {
- width: 360px;
- margin: 20px;
- }
-
- #popup-buttons {
- display: flex;
- flex-direction: row;
- justify-content: center;
- margin: 6px;
-
- .popup-button {
- height: 40px;
- width: 120px;
- border-radius: 4px;
- background-color: $bcg-darker;
-
- &:hover {
- color: $text-primary;
- background-color: $clr-hilight;
- }
- }
- }
- }
-}
diff --git a/mirror-2/splat/src/ui/popup.ts b/mirror-2/splat/src/ui/popup.ts
deleted file mode 100644
index 11e65185..00000000
--- a/mirror-2/splat/src/ui/popup.ts
+++ /dev/null
@@ -1,173 +0,0 @@
-import { Button, Container, Label, TextInput } from '@playcanvas/pcui'
-import { localize } from './localization'
-
-interface ShowOptions {
- type: 'error' | 'info' | 'yesno' | 'okcancel'
- message: string
- header?: string
- value?: string
-}
-
-class Popup extends Container {
- show: (options: ShowOptions) => void
- hide: () => void
- destroy: () => void
-
- constructor(args = {}) {
- args = {
- id: 'popup',
- hidden: true,
- tabIndex: -1,
- ...args
- }
-
- super(args)
-
- const dialog = new Container({
- id: 'popup-dialog'
- })
-
- const header = new Label({
- id: 'popup-header'
- })
-
- const text = new Label({
- id: 'popup-text'
- })
-
- const inputValue = new TextInput({
- id: 'popup-text-input'
- })
-
- const okButton = new Button({
- class: 'popup-button',
- text: localize('popup.ok')
- })
-
- const cancelButton = new Button({
- class: 'popup-button',
- text: localize('popup.cancel')
- })
-
- const yesButton = new Button({
- class: 'popup-button',
- text: localize('popup.yes')
- })
-
- const noButton = new Button({
- class: 'popup-button',
- text: localize('popup.no')
- })
-
- const buttons = new Container({
- id: 'popup-buttons'
- })
-
- buttons.append(okButton)
- buttons.append(cancelButton)
- buttons.append(yesButton)
- buttons.append(noButton)
-
- dialog.append(header)
- dialog.append(text)
- dialog.append(inputValue)
- dialog.append(buttons)
-
- this.append(dialog)
-
- let okFn: () => void
- let cancelFn: () => void
- let yesFn: () => void
- let noFn: () => void
- let containerFn: () => void
-
- okButton.on('click', () => {
- okFn()
- })
-
- cancelButton.on('click', () => {
- cancelFn()
- })
-
- yesButton.on('click', () => {
- yesFn()
- })
-
- noButton.on('click', () => {
- noFn()
- })
-
- this.on('click', () => {
- containerFn()
- })
-
- dialog.on('click', (event) => {
- event.stopPropagation()
- })
-
- this.show = async (options: ShowOptions) => {
- header.text = options.header
- text.text = options.message
-
- const { type, value } = options
-
- ;['error', 'info', 'yesno', 'okcancel'].forEach((t) => {
- text.class[t === type ? 'add' : 'remove'](t)
- })
-
- // configure based on message type
- okButton.hidden = type === 'yesno'
- cancelButton.hidden = type !== 'okcancel'
- yesButton.hidden = type !== 'yesno'
- noButton.hidden = type !== 'yesno'
- this.hidden = false
-
- inputValue.hidden = value === undefined
- if (value !== undefined) {
- inputValue.value = value
- inputValue.focus()
- }
-
- // take keyboard focus so shortcuts stop working
- this.dom.focus()
-
- return new Promise<{ action: string; value?: string }>((resolve) => {
- okFn = () => {
- this.hide()
- resolve({
- action: 'ok',
- value: value !== undefined && inputValue.value
- })
- }
- cancelFn = () => {
- this.hide()
- resolve({ action: 'cancel' })
- }
- yesFn = () => {
- this.hide()
- resolve({ action: 'yes' })
- }
- noFn = () => {
- this.hide()
- resolve({ action: 'no' })
- }
- containerFn = () => {
- if (type === 'info') {
- cancelFn()
- }
- }
- })
- }
-
- this.hide = () => {
- this.hidden = true
- }
-
- this.destroy = () => {
- this.hide()
- this.destroy()
- }
- }
-}
-
-export { Popup, ShowOptions }
diff --git a/mirror-2/splat/src/ui/right-toolbar.scss b/mirror-2/splat/src/ui/right-toolbar.scss
deleted file mode 100644
index 39a24919..00000000
--- a/mirror-2/splat/src/ui/right-toolbar.scss
+++ /dev/null
@@ -1,94 +0,0 @@
-#right-toolbar {
- position: absolute;
- right: 24px;
- top: 50%;
- width: 54px;
- transform: translate(0, -50%);
- padding: 8px 0px;
- border-radius: 8px;
-
- background-color: $bcg-dark;
-
- display: flex;
- flex-direction: column;
- align-items: center;
-
- #right-toolbar-mode-toggle {
- display: flex;
- flex-direction: column;
- align-items: center;
- justify-content: center;
-
- svg {
- width: 20px;
- height: 20px;
- }
- }
-
- &>.right-toolbar-button, .right-toolbar-tool, .right-toolbar-toggle {
- width: 38px;
- height: 38px;
- margin: 0px 1px;
- padding: 0px;
- border: 0px;
- border-radius: 2px;
-
- &::before {
- font-size: 16px !important;
- line-height: 100%;
- }
-
- svg {
- color: $clr-default;
- }
- }
-
- &>.right-toolbar-separator {
- width: 38px;
- height: 2px;
- margin: 10px 0px;
- background-color: $bcg-primary;
- }
-
- &>.right-toolbar-button {
- svg {
- color: $clr-default;
- }
- }
-
- &>.right-toolbar-tool {
- background-color: $bcg-primary;
-
- svg {
- color: $clr-default;
- }
-
- &.active {
- color: $clr-active;
- background-color: $clr-hilight !important;
-
- svg {
- color: $clr-active;
- }
- }
-
- &.disabled {
- background-color: $bcg-dark;
-
- svg {
- color: $clr-disabled;
- }
- }
- }
-
- &>.right-toolbar-toggle.active {
- // highlight icon
- &::before {
- color: $clr-hilight;
- }
-
- svg {
- color: $clr-hilight;
- }
- }
-}
\ No newline at end of file
diff --git a/mirror-2/splat/src/ui/right-toolbar.ts b/mirror-2/splat/src/ui/right-toolbar.ts
deleted file mode 100644
index 59f4169d..00000000
--- a/mirror-2/splat/src/ui/right-toolbar.ts
+++ /dev/null
@@ -1,106 +0,0 @@
-import { Button, Container, Element, Label } from '@playcanvas/pcui'
-import { Events } from '../events'
-import { Tooltips } from './tooltips'
-import { localize } from './localization'
-
-import showHideSplatsSvg from '../svg/show-hide-splats.svg'
-import frameSelectionSvg from '../svg/frame-selection.svg'
-import centersSvg from '../svg/centers.svg'
-import ringsSvg from '../svg/rings.svg'
-
-const createSvg = (): HTMLElement => {
- const svgString = `
-
- `
- return new DOMParser().parseFromString(svgString, 'image/svg+xml')
- .documentElement as HTMLElement
-}
-
-class RightToolbar extends Container {
- constructor(events: Events, tooltips: Tooltips, args = {}) {
- args = {
- ...args,
- id: 'right-toolbar'
- }
-
- super(args)
-
- this.dom.addEventListener('pointerdown', (event) => {
- event.stopPropagation()
- })
-
- const ringsModeToggle = new Button({
- id: 'right-toolbar-mode-toggle',
- class: 'right-toolbar-toggle'
- })
-
- const showHideSplats = new Button({
- id: 'right-toolbar-show-hide',
- class: ['right-toolbar-toggle', 'active']
- })
-
- const frameSelection = new Button({
- id: 'right-toolbar-frame-selection',
- class: 'right-toolbar-button'
- })
-
- const options = new Button({
- id: 'right-toolbar-options',
- class: 'right-toolbar-toggle',
- icon: 'E283'
- })
-
- const centersDom = createSvg(centersSvg)
- const ringsDom = createSvg(ringsSvg)
- ringsDom.style.display = 'none'
-
- ringsModeToggle.dom.appendChild(centersDom)
- ringsModeToggle.dom.appendChild(ringsDom)
- showHideSplats.dom.appendChild(createSvg(showHideSplatsSvg))
- frameSelection.dom.appendChild(createSvg(frameSelectionSvg))
-
- this.append(ringsModeToggle)
- this.append(showHideSplats)
- this.append(new Element({ class: 'right-toolbar-separator' }))
- this.append(frameSelection)
- this.append(new Element({ class: 'right-toolbar-separator' }))
- this.append(options)
-
- tooltips.register(ringsModeToggle, localize('tooltip.splat-mode'), 'left')
- tooltips.register(showHideSplats, localize('tooltip.show-hide'), 'left')
- tooltips.register(
- frameSelection,
- localize('tooltip.frame-selection'),
- 'left'
- )
- tooltips.register(options, localize('tooltip.view-options'), 'left')
-
- // add event handlers
-
- ringsModeToggle.on('click', () => {
- events.fire('camera.toggleMode')
- events.fire('camera.setOverlay', true)
- })
- showHideSplats.on('click', () => events.fire('camera.toggleOverlay'))
- frameSelection.on('click', () => events.fire('camera.focus'))
- options.on('click', () => events.fire('viewPanel.toggleVisible'))
-
- events.on('camera.mode', (mode: string) => {
- ringsModeToggle.class[mode === 'rings' ? 'add' : 'remove']('active')
- centersDom.style.display = mode === 'rings' ? 'none' : 'block'
- ringsDom.style.display = mode === 'rings' ? 'block' : 'none'
- })
-
- events.on('camera.overlay', (value: boolean) => {
- showHideSplats.class[value ? 'add' : 'remove']('active')
- })
-
- events.on('viewPanel.visible', (visible: boolean) => {
- options.class[visible ? 'add' : 'remove']('active')
- })
- }
-}
-
-export { RightToolbar }
diff --git a/mirror-2/splat/src/ui/scene-panel.scss b/mirror-2/splat/src/ui/scene-panel.scss
deleted file mode 100644
index ee4346f6..00000000
--- a/mirror-2/splat/src/ui/scene-panel.scss
+++ /dev/null
@@ -1,14 +0,0 @@
-#scene-panel {
- top: 102px;
- left: 24px;
- width: 320px;
-}
-
-.collapsed #scene-panel {
- display: none;
-}
-
-.splat-list-container {
- max-height: 300px;
- overflow: auto;
-}
\ No newline at end of file
diff --git a/mirror-2/splat/src/ui/scene-panel.ts b/mirror-2/splat/src/ui/scene-panel.ts
deleted file mode 100644
index 5260e19c..00000000
--- a/mirror-2/splat/src/ui/scene-panel.ts
+++ /dev/null
@@ -1,119 +0,0 @@
-import { Container, Element, Label } from '@playcanvas/pcui'
-import { Events } from '../events'
-import { Tooltips } from './tooltips'
-import { SplatList } from './splat-list'
-import { Transform } from './transform'
-import { localize } from './localization'
-
-import sceneImportSvg from '../svg/import.svg'
-import sceneNewSvg from '../svg/new.svg'
-
-const createSvg = () => {
- const svgString = `
-
- `
- return new Element({
- dom: new DOMParser().parseFromString(svgString, 'image/svg+xml')
- .documentElement
- })
-}
-
-class ScenePanel extends Container {
- constructor(events: Events, tooltips: Tooltips, args = {}) {
- args = {
- ...args,
- id: 'scene-panel',
- class: 'panel'
- }
-
- super(args)
-
- // stop pointer events bubbling
- ;['pointerdown', 'pointerup', 'pointermove', 'wheel', 'dblclick'].forEach(
- (eventName) => {
- this.dom.addEventListener(eventName, (event: Event) =>
- event.stopPropagation()
- )
- }
- )
-
- const sceneHeader = new Container({
- class: `panel-header`
- })
-
- const sceneIcon = new Label({
- text: '\uE344',
- class: `panel-header-icon`
- })
-
- const sceneLabel = new Label({
- text: localize('scene-manager'),
- class: `panel-header-label`
- })
-
- // const sceneImport = new Container({
- // class: `panel-header-button`
- // })
- // sceneImport.dom.appendChild(createSvg(sceneImportSvg))
-
- // const sceneNew = new Container({
- // class: `panel-header-button`
- // })
- // sceneNew.dom.appendChild(createSvg(sceneNewSvg))
-
- sceneHeader.append(sceneIcon)
- sceneHeader.append(sceneLabel)
- // sceneHeader.append(sceneImport)
- // sceneHeader.append(sceneNew)
-
- // sceneImport.on('click', () => {
- // events.fire('scene.open')
- // })
-
- // sceneNew.on('click', () => {
- // events.invoke('scene.new')
- // })
-
- // tooltips.register(sceneImport, 'Import Scene', 'top')
- // tooltips.register(sceneNew, 'New Scene', 'top')
-
- const splatList = new SplatList(events)
-
- const splatListContainer = new Container({
- class: 'splat-list-container'
- })
- splatListContainer.append(splatList)
-
- const transformHeader = new Container({
- class: `panel-header`
- })
-
- const transformIcon = new Label({
- text: '\uE111',
- class: `panel-header-icon`
- })
-
- const transformLabel = new Label({
- text: localize('transform'),
- class: `panel-header-label`
- })
-
- transformHeader.append(transformIcon)
- transformHeader.append(transformLabel)
-
- this.append(sceneHeader)
- this.append(splatListContainer)
- this.append(transformHeader)
- this.append(new Transform(events))
- this.append(
- new Element({
- class: `panel-header`,
- height: 20
- })
- )
- }
-}
-
-export { ScenePanel }
diff --git a/mirror-2/splat/src/ui/select-toolbar.scss b/mirror-2/splat/src/ui/select-toolbar.scss
deleted file mode 100644
index ad12d949..00000000
--- a/mirror-2/splat/src/ui/select-toolbar.scss
+++ /dev/null
@@ -1,23 +0,0 @@
-#select-toolbar {
- position: absolute;
- left: 50%;
- bottom: 100px;
- height: 54px;
- transform: translate(-50%, 0);
- padding: 0px 8px;
- border-radius: 8px;
-
- background-color: $bcg-primary;
-
- &:not(.pcui-hidden) {
- display: flex;
- }
- flex-direction: row;
- align-items: center;
-
- .select-toolbar-button {
- height: 38px;
- padding: 0px 16px;
- border-radius: 2px;
- }
-}
\ No newline at end of file
diff --git a/mirror-2/splat/src/ui/shortcuts-popup.ts b/mirror-2/splat/src/ui/shortcuts-popup.ts
deleted file mode 100644
index bdc1cadb..00000000
--- a/mirror-2/splat/src/ui/shortcuts-popup.ts
+++ /dev/null
@@ -1,98 +0,0 @@
-import { Container, Label, Overlay, Panel } from '@playcanvas/pcui'
-import { localize } from './localization'
-
-const shortcutList = [
- { header: 'tools' },
- { key: '1', action: 'move' },
- { key: '2', action: 'rotate' },
- { key: '3', action: 'scale' },
- { key: 'R', action: 'rect-selection' },
- { key: 'B', action: 'brush-selection' },
- { key: 'P', action: 'picker-selection' },
- { key: '[ ]', action: 'brush-size' },
- { key: 'Esc', action: 'deactivate-tool' },
- { header: 'selection' },
- { key: 'A', action: 'select-all' },
- { key: 'Shift + A', action: 'deselect-all' },
- { key: 'I', action: 'invert-selection' },
- { key: 'Shift', action: 'add-to-selection' },
- { key: 'Ctrl', action: 'remove-from-selection' },
- { key: 'Delete', action: 'delete-selected-splats' },
- { header: 'show' },
- { key: 'H', action: 'hide-selected-splats' },
- { key: 'U', action: 'unhide-all-splats' },
- { key: 'D', action: 'toggle-data-panel' },
- { header: 'other' },
- { key: 'Tab', action: 'select-next-splat' },
- { key: 'Ctrl + Z', action: 'undo' },
- { key: 'Ctrl + Shift + Z', action: 'redo' },
- { key: 'Space', action: 'toggle-splat-overlay' },
- { key: 'F', action: 'focus-camera' },
- { key: 'M', action: 'toggle-camera-mode' },
- { key: 'G', action: 'toggle-grid' },
- { key: 'C', action: 'toggle-gizmo-coordinate-space' }
-]
-
-class ShortcutsPopup extends Overlay {
- constructor(args = {}) {
- args = {
- ...args,
- id: 'shortcuts-popup',
- clickable: true,
- hidden: true
- }
-
- super(args)
-
- const shortcutsContainer = new Container({
- id: 'shortcuts-container'
- })
-
- shortcutList.forEach((shortcut) => {
- if (shortcut.header) {
- const label = new Label({
- class: 'shortcut-header-label',
- text: localize(`shortcuts.${shortcut.header}`)
- })
-
- const entry = new Container({
- class: 'shortcut-header'
- })
-
- entry.append(label)
-
- shortcutsContainer.append(entry)
- } else {
- const key = new Label({
- class: 'shortcut-key',
- text: shortcut.key
- })
-
- const action = new Label({
- class: 'shortcut-action',
- text: localize(`shortcuts.${shortcut.action}`)
- })
-
- const entry = new Container({
- class: 'shortcut-entry'
- })
-
- entry.append(key)
- entry.append(action)
-
- shortcutsContainer.append(entry)
- }
- })
-
- const shortcutsPanel = new Panel({
- id: 'shortcuts-panel',
- headerText: localize('shortcuts.title')
- })
-
- shortcutsPanel.append(shortcutsContainer)
-
- this.append(shortcutsPanel)
- }
-}
-
-export { ShortcutsPopup }
diff --git a/mirror-2/splat/src/ui/spinner.ts b/mirror-2/splat/src/ui/spinner.ts
deleted file mode 100644
index 28c4b19a..00000000
--- a/mirror-2/splat/src/ui/spinner.ts
+++ /dev/null
@@ -1,84 +0,0 @@
-const css = `
-.static-spinner::before,
-.static-spinner::after {
- border: 2px solid;
- border-left: none;
- box-sizing: border-box;
- content: '';
- display: block;
- position: absolute;
- top: 50%;
- left: 50%;
- -webkit-transform: translateY(-50%);
- transform: translateY(-50%);
- -webkit-transform-origin: 0% 50%;
- transform-origin: 0% 50%;
- -webkit-animation: spinner-spin 1s linear 0s infinite;
- animation: spinner-spin 1s linear 0s infinite;
- border-width: 3px;
- border-color: #aaa;
-}
-
-.static-spinner::before {
- width: 15px;
- height: 30px;
- border-radius: 0 30px 30px 0;
-}
-
-.static-spinner::after {
- width: 8px;
- height: 16px;
- border-radius: 0 16px 16px 0;
- animation-direction: reverse;
-}
-
-@-webkit-keyframes spinner-spin {
- 0% {
- -webkit-transform: translateY(-50%) rotate(0deg);
- transform: translateY(-50%) rotate(0deg);
- }
-
- 100% {
- -webkit-transform: translateY(-50%) rotate(360deg);
- transform: translateY(-50%) rotate(360deg);
- }
-}
-
-@keyframes spinner-spin {
- 0% {
- -webkit-transform: translateY(-50%) rotate(0deg);
- transform: translateY(-50%) rotate(0deg);
- }
-
- 100% {
- -webkit-transform: translateY(-50%) rotate(360deg);
- transform: translateY(-50%) rotate(360deg);
- }
-}
-`;
-
-let container: HTMLElement;
-
-const startSpinner = () => {
- if (!container) {
- const style = document.createElement('style');
- style.innerText = css;
- container = document.createElement('div');
- container.appendChild(style);
- const spinner = document.createElement('div');
- spinner.className = 'static-spinner';
- container.appendChild(spinner);
- }
- document.body.appendChild(container);
-};
-
-const stopSpinner = () => {
- if (container) {
- document.body.removeChild(container);
- }
-};
-
-export {
- startSpinner,
- stopSpinner
-};
diff --git a/mirror-2/splat/src/ui/splat-list.scss b/mirror-2/splat/src/ui/splat-list.scss
deleted file mode 100644
index 5aff230b..00000000
--- a/mirror-2/splat/src/ui/splat-list.scss
+++ /dev/null
@@ -1,72 +0,0 @@
-.splat-list {
- min-height: 80px;
- padding: 4px 0px;
-}
-
-.splat-item {
- display: flex;
- flex-direction: row;
- padding: 2px;
-
- &:hover:not(.selected).visible {
- cursor: pointer;
- }
-
- &.selected {
- background-color: $bcg-darker;
- }
-}
-
-.splat-item-text {
- flex-grow: 1;
- flex-shrink: 1;
-
- .visible & {
- &:hover:not(.selected) {
- color: $text-primary;
- }
- }
-
- .selected & {
- color: $text-primary;
- }
-}
-
-.splat-item-visible {
- flex-grow: 0;
- flex-shrink: 0;
-
- width: 24px;
- height: 24px;
- line-height: 24px;
-
- color: $text-secondary;
-
- cursor: pointer;
-
- .visible & {
- color: $text-secondary;
- }
-
- &:hover {
- color: $text-primary;
- }
-}
-
-.splat-item-delete {
- flex-grow: 0;
- flex-shrink: 0;
-
- padding: 4px;
- width: 16px;
- height: 16px;
- line-height: 16px;
-
- color: $text-secondary;
-
- cursor: pointer;
-
- &:hover {
- color: $text-primary;
- }
-}
\ No newline at end of file
diff --git a/mirror-2/splat/src/ui/splat-list.ts b/mirror-2/splat/src/ui/splat-list.ts
deleted file mode 100644
index 0b57498b..00000000
--- a/mirror-2/splat/src/ui/splat-list.ts
+++ /dev/null
@@ -1,246 +0,0 @@
-import { Container, Label, Element as PcuiElement } from '@playcanvas/pcui'
-import { Events } from '../events'
-import { Splat } from '../splat'
-import { Element, ElementType } from '../element'
-
-import shownSvg from '../svg/shown.svg'
-import hiddenSvg from '../svg/hidden.svg'
-import deleteSvg from '../svg/delete.svg'
-
-const createSvg = (): HTMLElement => {
- const svgString = `
-
- `
- return new DOMParser().parseFromString(svgString, 'image/svg+xml')
- .documentElement as HTMLElement
-}
-
-class SplatItem extends Container {
- getSelected: () => boolean
- setSelected: (value: boolean) => void
- getVisible: () => boolean
- setVisible: (value: boolean) => void
- destroy: () => void
-
- constructor(name: string, args = {}) {
- args = {
- ...args,
- class: ['splat-item', 'visible']
- }
-
- super(args)
-
- const text = new Label({
- class: 'splat-item-text',
- text: name
- })
-
- const visible = new PcuiElement({
- dom: createSvg(),
- class: 'splat-item-visible'
- })
-
- const invisible = new PcuiElement({
- dom: createSvg(),
- class: 'splat-item-visible',
- hidden: true
- })
-
- const remove = new PcuiElement({
- dom: createSvg(),
- class: 'splat-item-delete'
- })
-
- this.append(text)
- this.append(visible)
- this.append(invisible)
- this.append(remove)
-
- this.getSelected = () => {
- return this.class.contains('selected')
- }
-
- this.setSelected = (value: boolean) => {
- if (value !== this.selected) {
- if (value) {
- this.class.add('selected')
- this.emit('select', this)
- } else {
- this.class.remove('selected')
- this.emit('unselect', this)
- }
- }
- }
-
- this.getVisible = () => {
- return this.class.contains('visible')
- }
-
- this.setVisible = (value: boolean) => {
- if (value !== this.visible) {
- visible.hidden = !value
- invisible.hidden = value
- if (value) {
- this.class.add('visible')
- this.emit('visible', this)
- } else {
- this.class.remove('visible')
- this.emit('invisible', this)
- }
- }
- }
-
- const toggleVisible = (event: MouseEvent) => {
- event.stopPropagation()
- this.visible = !this.visible
- }
-
- const handleRemove = (event: MouseEvent) => {
- event.stopPropagation()
- this.emit('removeClicked', this)
- }
-
- // handle clicks
- visible.dom.addEventListener('click', toggleVisible)
- invisible.dom.addEventListener('click', toggleVisible)
- remove.dom.addEventListener('click', handleRemove)
-
- this.destroy = () => {
- visible.dom.removeEventListener('click', toggleVisible)
- invisible.dom.removeEventListener('click', toggleVisible)
- remove.dom.removeEventListener('click', handleRemove)
- }
- }
-
- get selected() {
- return this.getSelected()
- }
-
- set selected(value) {
- this.setSelected(value)
- }
-
- get visible() {
- return this.getVisible()
- }
-
- set visible(value) {
- this.setVisible(value)
- }
-}
-
-class SplatList extends Container {
- constructor(events: Events, args = {}) {
- args = {
- ...args,
- class: 'splat-list'
- }
-
- super(args)
-
- const items = new Map()
-
- events.on('scene.elementAdded', (element: Element) => {
- if (element.type === ElementType.splat) {
- const splat = element as Splat
- const item = new SplatItem(splat.filename)
- this.append(item)
- items.set(splat, item)
-
- item.on('visible', () => {
- splat.visible = true
-
- // also select it if there is no other selection
- if (!events.invoke('selection')) {
- events.fire('selection', splat)
- }
- })
- item.on('invisible', () => (splat.visible = false))
- }
- })
-
- events.on('scene.elementRemoved', (element: Element) => {
- if (element.type === ElementType.splat) {
- const splat = element as Splat
- const item = items.get(splat)
- if (item) {
- this.remove(item)
- items.delete(splat)
- }
- }
- })
-
- events.on('selection.changed', (selection: Splat) => {
- items.forEach((value, key) => {
- value.selected = key === selection
- })
- })
-
- events.on('splat.visibility', (splat: Splat) => {
- const item = items.get(splat)
- if (item) {
- item.visible = splat.visible
- }
- })
-
- this.on('click', (item: SplatItem) => {
- for (const [key, value] of items) {
- if (item === value) {
- events.fire('selection', key)
- break
- }
- }
- })
-
- this.on('removeClicked', async (item: SplatItem) => {
- let splat
- for (const [key, value] of items) {
- if (item === value) {
- splat = key
- break
- }
- }
-
- if (!splat) {
- return
- }
-
- const result = await events.invoke('showPopup', {
- type: 'yesno',
- header: 'Remove Splat',
- message: `Are you sure you want to remove '${splat.filename}' from the scene? This operation can not be undone.`
- })
-
- if (result?.action === 'yes') {
- splat.destroy()
- }
- })
- }
-
- protected _onAppendChild(element: PcuiElement): void {
- super._onAppendChild(element)
-
- if (element instanceof SplatItem) {
- element.on('click', () => {
- this.emit('click', element)
- })
-
- element.on('removeClicked', () => {
- this.emit('removeClicked', element)
- })
- }
- }
-
- protected _onRemoveChild(element: PcuiElement): void {
- if (element instanceof SplatItem) {
- element.unbind('click')
- element.unbind('removeClicked')
- }
-
- super._onRemoveChild(element)
- }
-}
-
-export { SplatList, SplatItem }
diff --git a/mirror-2/splat/src/ui/style.scss b/mirror-2/splat/src/ui/style.scss
deleted file mode 100644
index d849433c..00000000
--- a/mirror-2/splat/src/ui/style.scss
+++ /dev/null
@@ -1,238 +0,0 @@
-@import 'pcui-theme-grey.scss';
-
-$clr-default: #b3aaac;
-$clr-disabled: #7c7678;
-$clr-active: white;
-$clr-hilight: #f60;
-
-$bcg-light: #555;
-$bcg-darkest: #181818;
-
-@import 'tooltips.scss';
-@import 'panel.scss';
-@import 'menu-panel.scss';
-@import 'menu.scss';
-@import 'scene-panel.scss';
-@import 'view-panel.scss';
-@import 'splat-list.scss';
-@import 'transform.scss';
-@import 'bottom-toolbar.scss';
-@import 'right-toolbar.scss';
-@import 'select-toolbar.scss';
-@import 'data-panel.scss';
-@import 'popup.scss';
-@import 'mode-toggle.scss';
-
-* {
- font-size: 12px;
- user-select: none;
-}
-
-html {
- height: 100%;
-}
-
-body {
- margin: 0;
- padding: 0;
- height: 100%;
- max-height: 100%;
- background-color: $bcg-primary;
- overflow: hidden;
- touch-action: none;
-}
-
-#app-container {
- width: 100%;
- height: 100%;
-}
-
-#editor-container {
- width: 100%;
- height: 100%;
- margin: 0;
- padding: 0;
- display: flex;
- flex-direction: row;
-}
-
-#main-container {
- width: 100%;
- height: 100%;
- display: flex;
- flex-direction: column;
- border: 0;
- padding: 0;
- margin: 0;
- flex-grow: 1;
-}
-
-#sep-container {
- background-color: $bcg-darker;
-}
-
-#sep-container > span {
- color: white;
-}
-
-#coord-space-toggle.active {
- background-color: $bcg-dark !important;
- color: #f60;
-}
-
-#file-selector {
- display: none;
-}
-
-#file-menu {
- position: absolute;
-}
-
-.file-menu-item span {
- padding: 6px;
- color: $text-secondary !important;
- font-size: 14px;
-}
-
-#shortcuts-panel {
- background-color: $bcg-dark;
-}
-
-#shortcuts-container {
- margin: 10px;
-}
-
-.shortcut-key {
- width: 80px;
- text-align: right;
-}
-
-.shortcut-header {
- background-color: $bcg-darker;
-}
-
-#app-label {
- position: absolute;
- right: 20px;
- bottom: 20px;
- color: $text-primary;
- text-shadow: 1px 1px 4px black;
-}
-
-.select-svg {
- display: none;
- position: absolute;
- width: 100%;
- height: 100%;
-}
-
-#view-cube-container {
- position: absolute;
- width: 140px;
- height: 140px;
- right: 0px;
- top: 0px;
- pointer-events: none;
-}
-
-#brush-select-canvas {
- display: none;
- position: absolute;
- opacity: 0.4;
-}
-
-#canvas-container {
- width: 100%;
- display: flex;
- border: 0;
- padding: 0;
- margin: 0;
- flex-grow: 1;
-}
-
-#tools-container {
- display: none;
- position: absolute;
- width: 100%;
- height: 100%;
- cursor: crosshair;
-}
-
-#canvas {
- width: 100%;
- height: 100%;
- image-rendering: pixelated;
-}
-
-#tooltips-container {
- position: fixed;
- left: 0;
- top: 0;
- width: 100%;
- height: 100%;
- pointer-events: none;
-}
-
-#top-container {
- position: fixed;
- left: 0;
- top: 0;
- width: 100%;
- height: 100%;
- pointer-events: none;
-}
-
-// placeholder
-.pcui-input-element[placeholder] {
- &::after {
- color: $text-darkest;
- }
-}
-
-.pcui-vector-input {
- margin-left: 6px;
- margin-right: 6px;
-}
-
-/* scrollbar styling */
-
-::-webkit-scrollbar {
- width: 8px;
- height: 8px;
-}
-::-webkit-scrollbar-track {
- background: #20292b;
-}
-::-webkit-scrollbar-thumb {
- background: #5b7073;
-}
-::-webkit-scrollbar-thumb:hover {
- background: #f60;
-}
-::-webkit-scrollbar-corner {
- background: #2c393c;
-}
-
-.font-thin {
- font-family: 'Proxima Nova Thin', 'Helvetica Neue', Arial, Helvetica, sans-serif;
- font-weight: 100;
- font-style: normal;
-}
-
-.font-light {
- font-family: 'Proxima Nova Light', 'Helvetica Neue', Arial, Helvetica, sans-serif;
- font-weight: 200;
- font-style: normal;
-}
-
-.font-regular {
- font-family: 'Proxima Nova Regular', 'Helvetica Neue', Arial, Helvetica, sans-serif;
- font-weight: normal;
- font-style: normal;
-}
-
-.font-bold {
- font-family: 'Proxima Nova Bold', 'Helvetica Neue', Arial, Helvetica, sans-serif;
- font-weight: bold;
- font-style: normal;
-}
diff --git a/mirror-2/splat/src/ui/tooltips.scss b/mirror-2/splat/src/ui/tooltips.scss
deleted file mode 100644
index 5202ed9c..00000000
--- a/mirror-2/splat/src/ui/tooltips.scss
+++ /dev/null
@@ -1,11 +0,0 @@
-.tooltips {
- position: absolute;
- background-color: $bcg-darkest;
- border-radius: 3px;
- padding: 1px;
-}
-
-.tooltips-content {
- color: $clr-default;
- margin: 2px;
-}
diff --git a/mirror-2/splat/src/ui/tooltips.ts b/mirror-2/splat/src/ui/tooltips.ts
deleted file mode 100644
index 9d2663a6..00000000
--- a/mirror-2/splat/src/ui/tooltips.ts
+++ /dev/null
@@ -1,127 +0,0 @@
-import { Container, Element, Label } from '@playcanvas/pcui'
-
-type Direction = 'left' | 'right' | 'top' | 'bottom'
-
-class Tooltips extends Container {
- register: (target: Element, text: string, direction?: Direction) => void
- unregister: (target: Element) => void
- destroy: () => void
-
- constructor(args: any = {}) {
- args = {
- ...args,
- class: 'tooltips',
- hidden: true
- }
-
- super(args)
-
- const text = new Label({
- class: 'tooltips-content'
- })
-
- this.append(text)
-
- const targets = new Map()
- const style = this.dom.style
- let timer: number = 0
-
- this.register = (
- target: Element,
- textString: string,
- direction: Direction = 'bottom'
- ) => {
- const activate = () => {
- const rect = target.dom.getBoundingClientRect()
- const midx = Math.floor((rect.left + rect.right) * 0.5)
- const midy = Math.floor((rect.top + rect.bottom) * 0.5)
-
- switch (direction) {
- case 'left':
- style.left = `${rect.left}px`
- style.top = `${midy}px`
- style.transform = `translate(calc(-100% - 10px), -50%)`
- break
- case 'right':
- style.left = `${rect.right}px`
- style.top = `${midy}px`
- style.transform = `translate(10px, -50%)`
- break
- case 'top':
- style.left = `${midx}px`
- style.top = `${rect.top}px`
- style.transform = `translate(-50%, calc(-100% - 10px))`
- break
- case 'bottom':
- style.left = `${midx}px`
- style.top = `${rect.bottom}px`
- style.transform = `translate(-50%, 10px)`
- break
- }
-
- text.text = textString
- style.display = 'inline'
- }
-
- const startTimer = (fn: () => void) => {
- timer = setTimeout(() => {
- fn()
- timer = -1
- }, 250)
- }
-
- const cancelTimer = () => {
- if (timer >= 0) {
- clearTimeout(timer)
- timer = -1
- }
- }
-
- const enter = () => {
- cancelTimer()
-
- if (style.display === 'inline') {
- activate()
- } else {
- startTimer(() => activate())
- }
- }
-
- const leave = () => {
- cancelTimer()
-
- if (style.display === 'inline') {
- startTimer(() => {
- style.display = 'none'
- })
- }
- }
-
- target.dom.addEventListener('pointerenter', enter)
- target.dom.addEventListener('pointerleave', leave)
-
- target.on('destroy', () => {
- this.unregister(target)
- })
-
- targets.set(target, { enter, leave })
- }
-
- this.unregister = (target: Element) => {
- const value = targets.get(target)
- if (value) {
- target.dom.removeEventListener('pointerenter', value.enter)
- target.dom.removeEventListener('pointerleave', value.leave)
- targets.delete(target)
- }
- }
-
- this.destroy = () => {
- for (const target of targets.keys()) {
- this.unregister(target)
- }
- }
- }
-}
-
-export { Tooltips }
diff --git a/mirror-2/splat/src/ui/transform.scss b/mirror-2/splat/src/ui/transform.scss
deleted file mode 100644
index edf3f815..00000000
--- a/mirror-2/splat/src/ui/transform.scss
+++ /dev/null
@@ -1,66 +0,0 @@
-
-#transform {
- display: flex;
- flex-direction: column;
-
- background-color: $bcg-primary;
-
- padding: 0px 6px 12px 6px;
-}
-
-.transform-row {
- height: 32px;
- line-height: 32px;
- width: 100%;
- display: flex;
- flex-direction: row;
- flex-grow: 1;
- align-items: center;
-}
-
-.transform-label {
- width: 70px;
- flex-shrink: 0;
- flex-grow: 0;
- margin: 0px;
-}
-
-.transform-axis-label {
- text-align: center;
-}
-
-.transform-expand {
- flex-grow: 1;
-}
-
-$height: 22px;
-
-#transform > div > div.pcui-vector-input {
- margin: 0px;
- gap: 10px;
- height: $height;
-}
-
-#transform > div > div.pcui-numeric-input {
- margin: 0px;
- height: $height;
- line-height: $height;
-
- & > input {
- padding: 0px;
- margin: 0px 0px 0px 4px;
- height: $height;
- }
-}
-
-#transform > div > div > div.pcui-numeric-input {
- margin: 0px;
- height: $height;
- line-height: $height;
-
- & > input {
- padding: 0px;
- margin: 0px 0px 0px 4px;
- height: $height;
- }
-}
\ No newline at end of file
diff --git a/mirror-2/splat/src/ui/transform.ts b/mirror-2/splat/src/ui/transform.ts
deleted file mode 100644
index aa9fc5a4..00000000
--- a/mirror-2/splat/src/ui/transform.ts
+++ /dev/null
@@ -1,213 +0,0 @@
-import {
- Container,
- ContainerArgs,
- Label,
- NumericInput,
- VectorInput
-} from '@playcanvas/pcui'
-import { Quat, Vec3 } from 'playcanvas'
-import { Events } from '../events'
-import { localize } from './localization'
-import { Pivot } from '../pivot'
-
-const v = new Vec3()
-
-class Transform extends Container {
- constructor(events: Events, args: ContainerArgs = {}) {
- args = {
- ...args,
- id: 'transform'
- }
-
- super(args)
-
- const axis = new Container({
- class: 'transform-row'
- })
-
- const axisLabel = new Label({
- class: 'transform-label',
- text: ''
- })
-
- const xLabel = new Label({
- class: ['transform-expand', 'transform-label', 'transform-axis-label'],
- text: 'x'
- })
-
- const yLabel = new Label({
- class: ['transform-expand', 'transform-label', 'transform-axis-label'],
- text: 'y'
- })
-
- const zLabel = new Label({
- class: ['transform-expand', 'transform-label', 'transform-axis-label'],
- text: 'z'
- })
-
- axis.append(axisLabel)
- axis.append(xLabel)
- axis.append(yLabel)
- axis.append(zLabel)
-
- // position
- const position = new Container({
- class: 'transform-row'
- })
-
- const positionLabel = new Label({
- class: 'transform-label',
- text: localize('position')
- })
-
- const positionVector = new VectorInput({
- class: 'transform-expand',
- precision: 2,
- dimensions: 3,
- value: [0, 0, 0],
- enabled: false
- })
-
- position.append(positionLabel)
- position.append(positionVector)
-
- // rotation
- const rotation = new Container({
- class: 'transform-row'
- })
-
- const rotationLabel = new Label({
- class: 'transform-label',
- text: localize('rotation')
- })
-
- const rotationVector = new VectorInput({
- class: 'transform-expand',
- precision: 2,
- dimensions: 3,
- value: [0, 0, 0],
- enabled: false
- })
-
- rotation.append(rotationLabel)
- rotation.append(rotationVector)
-
- // scale
- const scale = new Container({
- class: 'transform-row'
- })
-
- const scaleLabel = new Label({
- class: 'transform-label',
- text: localize('scale')
- })
-
- const scaleInput = new NumericInput({
- class: 'transform-expand',
- precision: 2,
- value: 1,
- min: 0.01,
- max: 10000,
- enabled: false
- })
-
- scale.append(scaleLabel)
- scale.append(scaleInput)
-
- this.append(axis)
- this.append(position)
- this.append(rotation)
- this.append(scale)
-
- const toArray = (v: Vec3) => {
- return [v.x, v.y, v.z]
- }
-
- let uiUpdating = false
- let mouseUpdating = false
-
- // update UI with pivot
- const updateUI = (pivot: Pivot) => {
- uiUpdating = true
- const transform = pivot.transform
- transform.rotation.getEulerAngles(v)
- positionVector.value = toArray(transform.position)
- rotationVector.value = toArray(v)
- scaleInput.value = transform.scale.x
- uiUpdating = false
- }
-
- // update pivot with UI
- const updatePivot = (pivot: Pivot) => {
- const p = positionVector.value
- const r = rotationVector.value
- const q = new Quat().setFromEulerAngles(r[0], r[1], r[2])
- const s = scaleInput.value
-
- if (q.w < 0) {
- q.mulScalar(-1)
- }
-
- pivot.moveTRS(new Vec3(p[0], p[1], p[2]), q, new Vec3(s, s, s))
- }
-
- // handle a change in the UI state
- const change = () => {
- if (!uiUpdating) {
- const pivot = events.invoke('pivot') as Pivot
- if (mouseUpdating) {
- updatePivot(pivot)
- } else {
- pivot.start()
- updatePivot(pivot)
- pivot.end()
- }
- }
- }
-
- const mousedown = () => {
- mouseUpdating = true
- const pivot = events.invoke('pivot') as Pivot
- pivot.start()
- }
-
- const mouseup = () => {
- const pivot = events.invoke('pivot') as Pivot
- updatePivot(pivot)
- mouseUpdating = false
- pivot.end()
- }
-
- ;[positionVector.inputs, rotationVector.inputs, scaleInput]
- .flat()
- .forEach((input) => {
- input.on('change', change)
- input.on('slider:mousedown', mousedown)
- input.on('slider:mouseup', mouseup)
- })
-
- // toggle ui availability based on selection
- events.on('selection.changed', (selection) => {
- positionVector.enabled =
- rotationVector.enabled =
- scaleInput.enabled =
- !!selection
- })
-
- events.on('pivot.placed', (pivot: Pivot) => {
- updateUI(pivot)
- })
-
- events.on('pivot.moved', (pivot: Pivot) => {
- if (!mouseUpdating) {
- updateUI(pivot)
- }
- })
-
- events.on('pivot.ended', (pivot: Pivot) => {
- updateUI(pivot)
- })
- }
-}
-
-export { Transform }
diff --git a/mirror-2/splat/src/ui/view-cube.ts b/mirror-2/splat/src/ui/view-cube.ts
deleted file mode 100644
index 61faccaf..00000000
--- a/mirror-2/splat/src/ui/view-cube.ts
+++ /dev/null
@@ -1,184 +0,0 @@
-import { Container } from '@playcanvas/pcui'
-import { Mat4, Vec3 } from 'playcanvas'
-import { Events } from '../events'
-
-const vecx = new Vec3()
-const vecy = new Vec3()
-const vecz = new Vec3()
-const mat4 = new Mat4()
-
-class ViewCube extends Container {
- update: (cameraMatrix: Mat4) => void
-
- constructor(events: Events, args = {}) {
- args = {
- ...args,
- id: 'view-cube-container'
- }
-
- super(args)
-
- // construct svg elements
- const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg')
- svg.id = 'view-cube-svg'
-
- const group = document.createElementNS(svg.namespaceURI, 'g')
- svg.appendChild(group)
-
- const circle = (color: string, fill: boolean, text?: string) => {
- const result = document.createElementNS(
- svg.namespaceURI,
- 'g'
- ) as SVGElement
-
- const circle = document.createElementNS(
- svg.namespaceURI,
- 'circle'
- ) as SVGCircleElement
- circle.setAttribute('fill', fill ? color : '#555')
- circle.setAttribute('stroke', color)
- circle.setAttribute('stroke-width', '2')
- circle.setAttribute('r', '10')
- circle.setAttribute('cx', '0')
- circle.setAttribute('cy', '0')
- circle.setAttribute('pointer-events', 'all')
-
- result.appendChild(circle)
-
- if (text) {
- const t = document.createElementNS(
- svg.namespaceURI,
- 'text'
- ) as SVGTextElement
- t.setAttribute('font-size', '10')
- t.setAttribute('font-family', 'Arial')
- t.setAttribute('font-weight', 'bold')
- t.setAttribute('text-anchor', 'middle')
- t.setAttribute('alignment-baseline', 'central')
- t.textContent = text
- result.appendChild(t)
- }
-
- result.setAttribute('cursor', 'pointer')
-
- group.appendChild(result)
-
- return result
- }
-
- const line = (color: string) => {
- const result = document.createElementNS(
- svg.namespaceURI,
- 'line'
- ) as SVGLineElement
- result.setAttribute('stroke', color)
- result.setAttribute('stroke-width', '2')
- group.appendChild(result)
- return result
- }
-
- const r = '#f44'
- const g = '#4f4'
- const b = '#77f'
-
- const shapes = {
- nx: circle(r, false),
- ny: circle(g, false),
- nz: circle(b, false),
- xaxis: line(r),
- yaxis: line(g),
- zaxis: line(b),
- px: circle(r, true, 'X'),
- py: circle(g, true, 'Y'),
- pz: circle(b, true, 'Z')
- }
-
- shapes.px.children[0].addEventListener('pointerdown', () => {
- events.fire('camera.align', 'px')
- })
- shapes.py.children[0].addEventListener('pointerdown', () => {
- events.fire('camera.align', 'py')
- })
- shapes.pz.children[0].addEventListener('pointerdown', () => {
- events.fire('camera.align', 'pz')
- })
- shapes.nx.children[0].addEventListener('pointerdown', () => {
- events.fire('camera.align', 'nx')
- })
- shapes.ny.children[0].addEventListener('pointerdown', () => {
- events.fire('camera.align', 'ny')
- })
- shapes.nz.children[0].addEventListener('pointerdown', () => {
- events.fire('camera.align', 'nz')
- })
-
- this.dom.appendChild(svg)
-
- let cw = 0
- let ch = 0
-
- this.update = (cameraMatrix: Mat4) => {
- const w = this.dom.clientWidth
- const h = this.dom.clientHeight
-
- if (w && h) {
- if (w !== cw || h !== ch) {
- // resize elements
- svg.setAttribute('width', w.toString())
- svg.setAttribute('height', h.toString())
- group.setAttribute('transform', `translate(${w * 0.5}, ${h * 0.5})`)
- cw = w
- ch = h
- }
-
- mat4.invert(cameraMatrix)
- mat4.getX(vecx)
- mat4.getY(vecy)
- mat4.getZ(vecz)
-
- const transform = (group: SVGElement, x: number, y: number) => {
- group.setAttribute('transform', `translate(${x * 40}, ${y * 40})`)
- }
-
- const x2y2 = (line: SVGLineElement, x: number, y: number) => {
- line.setAttribute('x2', (x * 40).toString())
- line.setAttribute('y2', (y * 40).toString())
- }
-
- transform(shapes.px, vecx.x, -vecx.y)
- transform(shapes.nx, -vecx.x, vecx.y)
- transform(shapes.py, vecy.x, -vecy.y)
- transform(shapes.ny, -vecy.x, vecy.y)
- transform(shapes.pz, vecz.x, -vecz.y)
- transform(shapes.nz, -vecz.x, vecz.y)
-
- x2y2(shapes.xaxis, vecx.x, -vecx.y)
- x2y2(shapes.yaxis, vecy.x, -vecy.y)
- x2y2(shapes.zaxis, vecz.x, -vecz.y)
-
- // reorder dom for the mighty svg painter's algorithm
- const order = [
- { n: ['xaxis', 'px'], value: vecx.z },
- { n: ['yaxis', 'py'], value: vecy.z },
- { n: ['zaxis', 'pz'], value: vecz.z },
- { n: ['nx'], value: -vecx.z },
- { n: ['ny'], value: -vecy.z },
- { n: ['nz'], value: -vecz.z }
- ].sort((a, b) => a.value - b.value)
-
- const fragment = document.createDocumentFragment()
-
- order.forEach((o) => {
- o.n.forEach((n) => {
- // @ts-ignore
- fragment.appendChild(shapes[n])
- })
- })
-
- group.appendChild(fragment)
- }
- }
- }
-}
-
-export { ViewCube }
diff --git a/mirror-2/splat/src/ui/view-panel.scss b/mirror-2/splat/src/ui/view-panel.scss
deleted file mode 100644
index 8cf8ded1..00000000
--- a/mirror-2/splat/src/ui/view-panel.scss
+++ /dev/null
@@ -1,84 +0,0 @@
-#view-panel {
- top: 50%;
- transform: translate(0, -50%);
- right: 102px;
- width: 320px;
-
- :not(.pcui-hidden) {
- display: flex;
- }
- flex-direction: column;
-
- & > .view-panel-row {
- display: flex;
- flex-direction: row;
- padding: 2px;
- height: 28px;
-
- & > .view-panel-row-label {
- flex-grow: 1;
- }
-
- & > .view-panel-row-toggle {
- background-color: $bcg-dark;
-
- &::after {
- background-color: $clr-default;
- }
-
- &.pcui-boolean-input-ticked {
- background-color: $clr-hilight;
-
- &::after {
- background-color: $clr-active;
- }
- }
- }
-
- & > .view-panel-row-slider {
- margin: 0px;
-
- & > .pcui-slider-container {
- & > .pcui-slider-bar {
- & > .pcui-slider-handle {
- background-color: $clr-default;
- border-radius: 3px;
- }
- }
- }
- }
- }
-
- > .view-panel-list-container {
- width: 100%;
- min-height: 80px;
- max-height: 220px;
-
- padding: 4px 0px;
-
- overflow-y: auto;
-
- > .view-panel-list {
- width: 100%;
- display: flex;
- flex-direction: column;
-
- > .view-panel-list-row {
- display: flex;
- flex-direction: row;
- flex-shrink: 0;
- flex-grow: 0;
-
- cursor: pointer;
-
- > .view-panel-list-row-text {
- flex-grow: 1;
- }
- }
- }
-
- .selected {
- background-color: $bcg-darker;
- }
- }
-}
diff --git a/mirror-2/splat/src/ui/view-panel.ts b/mirror-2/splat/src/ui/view-panel.ts
deleted file mode 100644
index 8572845c..00000000
--- a/mirror-2/splat/src/ui/view-panel.ts
+++ /dev/null
@@ -1,441 +0,0 @@
-import { Vec3 } from 'playcanvas'
-import { BooleanInput, Container, Label, SliderInput } from '@playcanvas/pcui'
-import { Events } from '../events'
-import { Tooltips } from './tooltips'
-import { localize } from './localization'
-
-class ViewPanel extends Container {
- constructor(events: Events, tooltips: Tooltips, args = {}) {
- args = {
- ...args,
- id: 'view-panel',
- class: 'panel',
- hidden: true
- }
-
- super(args)
-
- // stop pointer events bubbling
- ;['pointerdown', 'pointerup', 'pointermove', 'wheel', 'dblclick'].forEach(
- (eventName) => {
- this.dom.addEventListener(eventName, (event: Event) =>
- event.stopPropagation()
- )
- }
- )
-
- // header
-
- const header = new Container({
- class: `panel-header`
- })
-
- const icon = new Label({
- text: '\uE403',
- class: `panel-header-icon`
- })
-
- const label = new Label({
- text: localize('options'),
- class: `panel-header-label`
- })
-
- header.append(icon)
- header.append(label)
-
- // camera fov
-
- const fovRow = new Container({
- class: 'view-panel-row'
- })
-
- const fovLabel = new Label({
- text: localize('options.fov'),
- class: 'view-panel-row-label'
- })
-
- const fovSlider = new SliderInput({
- class: 'view-panel-row-slider',
- min: 10,
- max: 120,
- precision: 1,
- value: 60
- })
-
- fovRow.append(fovLabel)
- fovRow.append(fovSlider)
-
- // sh bands
- const shBandsRow = new Container({
- class: 'view-panel-row'
- })
-
- const shBandsLabel = new Label({
- text: localize('options.sh-bands'),
- class: 'view-panel-row-label'
- })
-
- const shBandsSlider = new SliderInput({
- class: 'view-panel-row-slider',
- min: 0,
- max: 3,
- precision: 0,
- value: 3
- })
-
- shBandsRow.append(shBandsLabel)
- shBandsRow.append(shBandsSlider)
-
- // centers size
-
- const centersSizeRow = new Container({
- class: 'view-panel-row'
- })
-
- const centersSizeLabel = new Label({
- text: localize('options.centers-size'),
- class: 'view-panel-row-label'
- })
-
- const centersSizeSlider = new SliderInput({
- class: 'view-panel-row-slider',
- min: 0,
- max: 10,
- precision: 1,
- value: 2
- })
-
- centersSizeRow.append(centersSizeLabel)
- centersSizeRow.append(centersSizeSlider)
-
- // show grid
-
- const showGridRow = new Container({
- class: 'view-panel-row'
- })
-
- const showGridLabel = new Label({
- text: localize('options.show-grid'),
- class: 'view-panel-row-label'
- })
-
- const showGridToggle = new BooleanInput({
- type: 'toggle',
- class: 'view-panel-row-toggle',
- value: true
- })
-
- showGridRow.append(showGridLabel)
- showGridRow.append(showGridToggle)
-
- // show bound
-
- const showBoundRow = new Container({
- class: 'view-panel-row'
- })
-
- const showBoundLabel = new Label({
- text: localize('options.show-bound'),
- class: 'view-panel-row-label'
- })
-
- const showBoundToggle = new BooleanInput({
- type: 'toggle',
- class: 'view-panel-row-toggle',
- value: true
- })
-
- showBoundRow.append(showBoundLabel)
- showBoundRow.append(showBoundToggle)
-
- // camera poses
-
- const poseHeader = new Container({
- class: 'panel-header'
- })
-
- const poseIcon = new Label({
- class: 'panel-header-icon',
- text: '\uE212'
- })
-
- const poseHeaderLabel = new Label({
- text: localize('options.pose-header'),
- class: 'panel-header-label'
- })
-
- const poseAdd = new Label({
- class: 'panel-header-button',
- text: '\uE120'
- })
-
- const posePrev = new Label({
- class: 'panel-header-button',
- text: '\uE162'
- })
-
- const poseNext = new Label({
- class: 'panel-header-button',
- text: '\uE164'
- })
-
- const posePlay = new Label({
- class: 'panel-header-button',
- text: '\uE131'
- })
-
- const poseClear = new Label({
- class: 'panel-header-button',
- text: '\uE125'
- })
-
- poseHeader.append(poseIcon)
- poseHeader.append(poseHeaderLabel)
- poseHeader.append(poseAdd)
- poseHeader.append(new Label({ class: 'panel-header-spacer' }))
- poseHeader.append(posePrev)
- poseHeader.append(poseNext)
- poseHeader.append(posePlay)
- poseHeader.append(new Label({ class: 'panel-header-spacer' }))
- poseHeader.append(poseClear)
-
- const poseListContainer = new Container({
- class: 'view-panel-list-container'
- })
-
- const poseList = new Container({
- class: 'view-panel-list'
- })
-
- poseListContainer.append(poseList)
-
- this.append(header)
- this.append(fovRow)
- this.append(shBandsRow)
- this.append(centersSizeRow)
- this.append(showGridRow)
- this.append(showBoundRow)
- this.append(poseHeader)
- this.append(poseListContainer)
-
- // handle panel visibility
-
- const setVisible = (visible: boolean) => {
- if (visible === this.hidden) {
- this.hidden = !visible
- events.fire('viewPanel.visible', visible)
- }
- }
-
- events.function('viewPanel.visible', () => {
- return !this.hidden
- })
-
- events.on('viewPanel.setVisible', (visible: boolean) => {
- setVisible(visible)
- })
-
- events.on('viewPanel.toggleVisible', () => {
- setVisible(this.hidden)
- })
-
- // sh bands
-
- events.on('view.bands', (bands: number) => {
- shBandsSlider.value = bands
- })
-
- shBandsSlider.on('change', (value: number) => {
- events.fire('view.setBands', value)
- })
-
- // splat size
-
- events.on('camera.splatSize', (value: number) => {
- centersSizeSlider.value = value
- })
-
- centersSizeSlider.on('change', (value: number) => {
- events.fire('camera.setSplatSize', value)
- events.fire('camera.setOverlay', true)
- events.fire('camera.setMode', 'centers')
- })
-
- // show grid
-
- events.on('grid.visible', (visible: boolean) => {
- showGridToggle.value = visible
- })
-
- showGridToggle.on('change', () => {
- events.fire('grid.setVisible', showGridToggle.value)
- })
-
- // show bound
-
- events.on('camera.bound', (visible: boolean) => {
- showBoundToggle.value = visible
- })
-
- showBoundToggle.on('change', () => {
- events.fire('camera.setBound', showBoundToggle.value)
- })
-
- // poses
-
- type Pose = {
- name: string
- position: Vec3
- target: Vec3
- }
- const poses: { pose: Pose; row: Container }[] = []
- let currentPose = -1
-
- const setPose = (index: number, speed = 1) => {
- if (index === currentPose) {
- return
- }
-
- if (index !== -1) {
- events.fire('camera.setPose', poses[index].pose, speed)
- }
-
- poses.forEach((p, i) => {
- if (i === index) {
- p.row.class.add('selected')
- p.row.dom.scrollIntoView({ block: 'nearest' })
- } else {
- p.row.class.remove('selected')
- }
- })
-
- currentPose = index
- }
-
- const addPose = (pose: Pose) => {
- const row = new Container({
- class: 'view-panel-list-row'
- })
-
- const label = new Label({
- text: pose.name ?? 'camera',
- class: 'view-panel-list-row-label'
- })
-
- row.append(label)
-
- row.on('click', () => {
- setPose(poses.findIndex((r) => r.pose === pose))
- })
-
- poseList.append(row)
- poses.push({ row, pose })
- }
-
- const removePose = (index: number) => {
- poseList.remove(poses[index].row)
- poses.splice(index, 1)
- }
-
- const nextPose = () => {
- if (poses.length > 0) {
- setPose((currentPose + 1) % poses.length, 2.5)
- }
- }
-
- const prevPose = () => {
- if (poses.length > 0) {
- setPose((currentPose - 1 + poses.length) % poses.length)
- }
- }
-
- poseAdd.on('click', () => {
- // get the current camera pose
- const pose = events.invoke('camera.getPose')
-
- addPose({
- name: `camera_${poses.length}`,
- position: pose.position,
- target: pose.target
- })
- })
-
- posePrev.on('click', () => {
- prevPose()
- })
-
- poseNext.on('click', () => {
- nextPose()
- })
-
- let timeout: number = null
-
- const stop = () => {
- posePlay.text = '\uE131'
- clearTimeout(timeout)
- timeout = null
- }
-
- posePlay.on('click', () => {
- if (timeout) {
- stop()
- } else if (poses.length > 0) {
- const next = () => {
- nextPose()
- timeout = setTimeout(next, 250)
- }
-
- posePlay.text = '\uE135'
- next()
- }
- })
-
- events.function('camera.poses', () => {
- return poses.map((p) => p.pose)
- })
-
- events.on('camera.addPose', (pose: Pose) => {
- addPose(pose)
- })
-
- events.on('camera.removePose', (index: number) => {
- removePose(index)
- })
-
- events.on('camera.controller', (type: string) => {
- if (type !== 'pointermove') {
- if (timeout) {
- stop()
- } else {
- setPose(-1)
- }
- }
- })
-
- poseClear.on('click', () => {
- while (poses.length > 0) {
- removePose(0)
- }
- })
-
- // camera fov
-
- events.on('camera.fov', (fov: number) => {
- fovSlider.value = fov
- })
-
- fovSlider.on('change', (value: number) => {
- events.fire('camera.setFov', value)
- })
-
- // tooltips
-
- tooltips.register(poseAdd, localize('options.add-pose'))
- tooltips.register(posePrev, localize('options.prev-pose'))
- tooltips.register(poseNext, localize('options.next-pose'))
- tooltips.register(posePlay, localize('options.play-poses'))
- tooltips.register(poseClear, localize('options.clear-poses'))
- }
-}
-
-export { ViewPanel }
diff --git a/mirror-2/splat/static/env/Echopark.png b/mirror-2/splat/static/env/Echopark.png
deleted file mode 100644
index 48a5dd5a..00000000
Binary files a/mirror-2/splat/static/env/Echopark.png and /dev/null differ
diff --git a/mirror-2/splat/static/env/VertebraeHDRI_v1_512.png b/mirror-2/splat/static/env/VertebraeHDRI_v1_512.png
deleted file mode 100644
index 12e313a7..00000000
Binary files a/mirror-2/splat/static/env/VertebraeHDRI_v1_512.png and /dev/null differ
diff --git a/mirror-2/splat/static/icons/logo-192.png b/mirror-2/splat/static/icons/logo-192.png
deleted file mode 100644
index 30f2a804..00000000
Binary files a/mirror-2/splat/static/icons/logo-192.png and /dev/null differ
diff --git a/mirror-2/splat/static/icons/logo-512.png b/mirror-2/splat/static/icons/logo-512.png
deleted file mode 100644
index 7414b336..00000000
Binary files a/mirror-2/splat/static/icons/logo-512.png and /dev/null differ
diff --git a/mirror-2/splat/static/images/header.webp b/mirror-2/splat/static/images/header.webp
deleted file mode 100644
index 8b88416f..00000000
Binary files a/mirror-2/splat/static/images/header.webp and /dev/null differ
diff --git a/mirror-2/splat/static/images/screenshot-narrow.jpg b/mirror-2/splat/static/images/screenshot-narrow.jpg
deleted file mode 100644
index 0e75f1c4..00000000
Binary files a/mirror-2/splat/static/images/screenshot-narrow.jpg and /dev/null differ
diff --git a/mirror-2/splat/static/images/screenshot-wide.jpg b/mirror-2/splat/static/images/screenshot-wide.jpg
deleted file mode 100644
index b0387436..00000000
Binary files a/mirror-2/splat/static/images/screenshot-wide.jpg and /dev/null differ
diff --git a/mirror-2/splat/tsconfig.json b/mirror-2/splat/tsconfig.json
deleted file mode 100644
index b7d2423c..00000000
--- a/mirror-2/splat/tsconfig.json
+++ /dev/null
@@ -1,21 +0,0 @@
-{
- "compilerOptions": {
- "noImplicitAny": true,
- "target": "es2017",
- "lib": ["es2020", "dom", "WebWorker"],
- "allowSyntheticDefaultImports": true,
- "sourceMap": true,
- "inlineSources": true,
- "module": "es2020",
- "moduleResolution": "Node",
- "resolveJsonModule": true,
- "baseUrl": ".",
- "paths": {
- "playcanvas": ["node_modules/playcanvas/build/playcanvas"],
- "pcui": ["node_modules/@playcanvas/pcui"]
- },
- "types": ["@types/wicg-file-system-access"]
- },
- "include": ["./src/**/*.ts", "src/ui/menu.tsx"],
- "exclude": ["node_modules", "**/*.js", "dist"]
-}
diff --git a/mirror-2/splat/yarn.lock b/mirror-2/splat/yarn.lock
deleted file mode 100644
index a3092aeb..00000000
--- a/mirror-2/splat/yarn.lock
+++ /dev/null
@@ -1,5119 +0,0 @@
-# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
-# yarn lockfile v1
-
-
-"@ampproject/remapping@^2.2.0":
- version "2.3.0"
- resolved "https://registry.yarnpkg.com/@ampproject/remapping/-/remapping-2.3.0.tgz#ed441b6fa600072520ce18b43d2c8cc8caecc7f4"
- integrity sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==
- dependencies:
- "@jridgewell/gen-mapping" "^0.3.5"
- "@jridgewell/trace-mapping" "^0.3.24"
-
-"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.25.7":
- version "7.25.7"
- resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.25.7.tgz#438f2c524071531d643c6f0188e1e28f130cebc7"
- integrity sha512-0xZJFNE5XMpENsgfHYTw8FbX4kv53mFLn2i3XPoq69LyhYSCBJtitaHx9QnsVTrsogI4Z3+HtEfZ2/GFPOtf5g==
- dependencies:
- "@babel/highlight" "^7.25.7"
- picocolors "^1.0.0"
-
-"@babel/compat-data@^7.25.7":
- version "7.25.8"
- resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.25.8.tgz#0376e83df5ab0eb0da18885c0140041f0747a402"
- integrity sha512-ZsysZyXY4Tlx+Q53XdnOFmqwfB9QDTHYxaZYajWRoBLuLEAwI2UIbtxOjWh/cFaa9IKUlcB+DDuoskLuKu56JA==
-
-"@babel/core@^7.11.6", "@babel/core@^7.12.3", "@babel/core@^7.23.9":
- version "7.25.8"
- resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.25.8.tgz#a57137d2a51bbcffcfaeba43cb4dd33ae3e0e1c6"
- integrity sha512-Oixnb+DzmRT30qu9d3tJSQkxuygWm32DFykT4bRoORPa9hZ/L4KhVB/XiRm6KG+roIEM7DBQlmg27kw2HZkdZg==
- dependencies:
- "@ampproject/remapping" "^2.2.0"
- "@babel/code-frame" "^7.25.7"
- "@babel/generator" "^7.25.7"
- "@babel/helper-compilation-targets" "^7.25.7"
- "@babel/helper-module-transforms" "^7.25.7"
- "@babel/helpers" "^7.25.7"
- "@babel/parser" "^7.25.8"
- "@babel/template" "^7.25.7"
- "@babel/traverse" "^7.25.7"
- "@babel/types" "^7.25.8"
- convert-source-map "^2.0.0"
- debug "^4.1.0"
- gensync "^1.0.0-beta.2"
- json5 "^2.2.3"
- semver "^6.3.1"
-
-"@babel/generator@^7.25.7", "@babel/generator@^7.7.2":
- version "7.25.7"
- resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.25.7.tgz#de86acbeb975a3e11ee92dd52223e6b03b479c56"
- integrity sha512-5Dqpl5fyV9pIAD62yK9P7fcA768uVPUyrQmqpqstHWgMma4feF1x/oFysBCVZLY5wJ2GkMUCdsNDnGZrPoR6rA==
- dependencies:
- "@babel/types" "^7.25.7"
- "@jridgewell/gen-mapping" "^0.3.5"
- "@jridgewell/trace-mapping" "^0.3.25"
- jsesc "^3.0.2"
-
-"@babel/helper-compilation-targets@^7.25.7":
- version "7.25.7"
- resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.25.7.tgz#11260ac3322dda0ef53edfae6e97b961449f5fa4"
- integrity sha512-DniTEax0sv6isaw6qSQSfV4gVRNtw2rte8HHM45t9ZR0xILaufBRNkpMifCRiAPyvL4ACD6v0gfCwCmtOQaV4A==
- dependencies:
- "@babel/compat-data" "^7.25.7"
- "@babel/helper-validator-option" "^7.25.7"
- browserslist "^4.24.0"
- lru-cache "^5.1.1"
- semver "^6.3.1"
-
-"@babel/helper-module-imports@^7.25.7":
- version "7.25.7"
- resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.25.7.tgz#dba00d9523539152906ba49263e36d7261040472"
- integrity sha512-o0xCgpNmRohmnoWKQ0Ij8IdddjyBFE4T2kagL/x6M3+4zUgc+4qTOUBoNe4XxDskt1HPKO007ZPiMgLDq2s7Kw==
- dependencies:
- "@babel/traverse" "^7.25.7"
- "@babel/types" "^7.25.7"
-
-"@babel/helper-module-transforms@^7.25.7":
- version "7.25.7"
- resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.25.7.tgz#2ac9372c5e001b19bc62f1fe7d96a18cb0901d1a"
- integrity sha512-k/6f8dKG3yDz/qCwSM+RKovjMix563SLxQFo0UhRNo239SP6n9u5/eLtKD6EAjwta2JHJ49CsD8pms2HdNiMMQ==
- dependencies:
- "@babel/helper-module-imports" "^7.25.7"
- "@babel/helper-simple-access" "^7.25.7"
- "@babel/helper-validator-identifier" "^7.25.7"
- "@babel/traverse" "^7.25.7"
-
-"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.25.7", "@babel/helper-plugin-utils@^7.8.0":
- version "7.25.7"
- resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.25.7.tgz#8ec5b21812d992e1ef88a9b068260537b6f0e36c"
- integrity sha512-eaPZai0PiqCi09pPs3pAFfl/zYgGaE6IdXtYvmf0qlcDTd3WCtO7JWCcRd64e0EQrcYgiHibEZnOGsSY4QSgaw==
-
-"@babel/helper-simple-access@^7.25.7":
- version "7.25.7"
- resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.25.7.tgz#5eb9f6a60c5d6b2e0f76057004f8dacbddfae1c0"
- integrity sha512-FPGAkJmyoChQeM+ruBGIDyrT2tKfZJO8NcxdC+CWNJi7N8/rZpSxK7yvBJ5O/nF1gfu5KzN7VKG3YVSLFfRSxQ==
- dependencies:
- "@babel/traverse" "^7.25.7"
- "@babel/types" "^7.25.7"
-
-"@babel/helper-string-parser@^7.25.7":
- version "7.25.7"
- resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.25.7.tgz#d50e8d37b1176207b4fe9acedec386c565a44a54"
- integrity sha512-CbkjYdsJNHFk8uqpEkpCvRs3YRp9tY6FmFY7wLMSYuGYkrdUi7r2lc4/wqsvlHoMznX3WJ9IP8giGPq68T/Y6g==
-
-"@babel/helper-validator-identifier@^7.25.7":
- version "7.25.7"
- resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.7.tgz#77b7f60c40b15c97df735b38a66ba1d7c3e93da5"
- integrity sha512-AM6TzwYqGChO45oiuPqwL2t20/HdMC1rTPAesnBCgPCSF1x3oN9MVUwQV2iyz4xqWrctwK5RNC8LV22kaQCNYg==
-
-"@babel/helper-validator-option@^7.25.7":
- version "7.25.7"
- resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.25.7.tgz#97d1d684448228b30b506d90cace495d6f492729"
- integrity sha512-ytbPLsm+GjArDYXJ8Ydr1c/KJuutjF2besPNbIZnZ6MKUxi/uTA22t2ymmA4WFjZFpjiAMO0xuuJPqK2nvDVfQ==
-
-"@babel/helpers@^7.25.7":
- version "7.25.7"
- resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.25.7.tgz#091b52cb697a171fe0136ab62e54e407211f09c2"
- integrity sha512-Sv6pASx7Esm38KQpF/U/OXLwPPrdGHNKoeblRxgZRLXnAtnkEe4ptJPDtAZM7fBLadbc1Q07kQpSiGQ0Jg6tRA==
- dependencies:
- "@babel/template" "^7.25.7"
- "@babel/types" "^7.25.7"
-
-"@babel/highlight@^7.25.7":
- version "7.25.7"
- resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.25.7.tgz#20383b5f442aa606e7b5e3043b0b1aafe9f37de5"
- integrity sha512-iYyACpW3iW8Fw+ZybQK+drQre+ns/tKpXbNESfrhNnPLIklLbXr7MYJ6gPEd0iETGLOK+SxMjVvKb/ffmk+FEw==
- dependencies:
- "@babel/helper-validator-identifier" "^7.25.7"
- chalk "^2.4.2"
- js-tokens "^4.0.0"
- picocolors "^1.0.0"
-
-"@babel/parser@^7.1.0", "@babel/parser@^7.14.7", "@babel/parser@^7.20.7", "@babel/parser@^7.23.9", "@babel/parser@^7.25.7", "@babel/parser@^7.25.8":
- version "7.25.8"
- resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.25.8.tgz#f6aaf38e80c36129460c1657c0762db584c9d5e2"
- integrity sha512-HcttkxzdPucv3nNFmfOOMfFf64KgdJVqm1KaCm25dPGMLElo9nsLvXeJECQg8UzPuBGLyTSA0ZzqCtDSzKTEoQ==
- dependencies:
- "@babel/types" "^7.25.8"
-
-"@babel/plugin-syntax-async-generators@^7.8.4":
- version "7.8.4"
- resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz#a983fb1aeb2ec3f6ed042a210f640e90e786fe0d"
- integrity sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==
- dependencies:
- "@babel/helper-plugin-utils" "^7.8.0"
-
-"@babel/plugin-syntax-bigint@^7.8.3":
- version "7.8.3"
- resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz#4c9a6f669f5d0cdf1b90a1671e9a146be5300cea"
- integrity sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==
- dependencies:
- "@babel/helper-plugin-utils" "^7.8.0"
-
-"@babel/plugin-syntax-class-properties@^7.12.13":
- version "7.12.13"
- resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz#b5c987274c4a3a82b89714796931a6b53544ae10"
- integrity sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==
- dependencies:
- "@babel/helper-plugin-utils" "^7.12.13"
-
-"@babel/plugin-syntax-class-static-block@^7.14.5":
- version "7.14.5"
- resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz#195df89b146b4b78b3bf897fd7a257c84659d406"
- integrity sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==
- dependencies:
- "@babel/helper-plugin-utils" "^7.14.5"
-
-"@babel/plugin-syntax-import-attributes@^7.24.7":
- version "7.25.7"
- resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.25.7.tgz#d78dd0499d30df19a598e63ab895e21b909bc43f"
- integrity sha512-AqVo+dguCgmpi/3mYBdu9lkngOBlQ2w2vnNpa6gfiCxQZLzV4ZbhsXitJ2Yblkoe1VQwtHSaNmIaGll/26YWRw==
- dependencies:
- "@babel/helper-plugin-utils" "^7.25.7"
-
-"@babel/plugin-syntax-import-meta@^7.10.4":
- version "7.10.4"
- resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz#ee601348c370fa334d2207be158777496521fd51"
- integrity sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==
- dependencies:
- "@babel/helper-plugin-utils" "^7.10.4"
-
-"@babel/plugin-syntax-json-strings@^7.8.3":
- version "7.8.3"
- resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz#01ca21b668cd8218c9e640cb6dd88c5412b2c96a"
- integrity sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==
- dependencies:
- "@babel/helper-plugin-utils" "^7.8.0"
-
-"@babel/plugin-syntax-jsx@^7.7.2":
- version "7.25.7"
- resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.25.7.tgz#5352d398d11ea5e7ef330c854dea1dae0bf18165"
- integrity sha512-ruZOnKO+ajVL/MVx+PwNBPOkrnXTXoWMtte1MBpegfCArhqOe3Bj52avVj1huLLxNKYKXYaSxZ2F+woK1ekXfw==
- dependencies:
- "@babel/helper-plugin-utils" "^7.25.7"
-
-"@babel/plugin-syntax-logical-assignment-operators@^7.10.4":
- version "7.10.4"
- resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz#ca91ef46303530448b906652bac2e9fe9941f699"
- integrity sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==
- dependencies:
- "@babel/helper-plugin-utils" "^7.10.4"
-
-"@babel/plugin-syntax-nullish-coalescing-operator@^7.8.3":
- version "7.8.3"
- resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz#167ed70368886081f74b5c36c65a88c03b66d1a9"
- integrity sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==
- dependencies:
- "@babel/helper-plugin-utils" "^7.8.0"
-
-"@babel/plugin-syntax-numeric-separator@^7.10.4":
- version "7.10.4"
- resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz#b9b070b3e33570cd9fd07ba7fa91c0dd37b9af97"
- integrity sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==
- dependencies:
- "@babel/helper-plugin-utils" "^7.10.4"
-
-"@babel/plugin-syntax-object-rest-spread@^7.8.3":
- version "7.8.3"
- resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz#60e225edcbd98a640332a2e72dd3e66f1af55871"
- integrity sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==
- dependencies:
- "@babel/helper-plugin-utils" "^7.8.0"
-
-"@babel/plugin-syntax-optional-catch-binding@^7.8.3":
- version "7.8.3"
- resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz#6111a265bcfb020eb9efd0fdfd7d26402b9ed6c1"
- integrity sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==
- dependencies:
- "@babel/helper-plugin-utils" "^7.8.0"
-
-"@babel/plugin-syntax-optional-chaining@^7.8.3":
- version "7.8.3"
- resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz#4f69c2ab95167e0180cd5336613f8c5788f7d48a"
- integrity sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==
- dependencies:
- "@babel/helper-plugin-utils" "^7.8.0"
-
-"@babel/plugin-syntax-private-property-in-object@^7.14.5":
- version "7.14.5"
- resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz#0dc6671ec0ea22b6e94a1114f857970cd39de1ad"
- integrity sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==
- dependencies:
- "@babel/helper-plugin-utils" "^7.14.5"
-
-"@babel/plugin-syntax-top-level-await@^7.14.5":
- version "7.14.5"
- resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz#c1cfdadc35a646240001f06138247b741c34d94c"
- integrity sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==
- dependencies:
- "@babel/helper-plugin-utils" "^7.14.5"
-
-"@babel/plugin-syntax-typescript@^7.7.2":
- version "7.25.7"
- resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.25.7.tgz#bfc05b0cc31ebd8af09964650cee723bb228108b"
- integrity sha512-rR+5FDjpCHqqZN2bzZm18bVYGaejGq5ZkpVCJLXor/+zlSrSoc4KWcHI0URVWjl/68Dyr1uwZUz/1njycEAv9g==
- dependencies:
- "@babel/helper-plugin-utils" "^7.25.7"
-
-"@babel/runtime@^7.23.2":
- version "7.25.7"
- resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.25.7.tgz#7ffb53c37a8f247c8c4d335e89cdf16a2e0d0fb6"
- integrity sha512-FjoyLe754PMiYsFaN5C94ttGiOmBNYTf6pLr4xXHAT5uctHb092PBszndLDR5XA/jghQvn4n7JMHl7dmTgbm9w==
- dependencies:
- regenerator-runtime "^0.14.0"
-
-"@babel/template@^7.25.7", "@babel/template@^7.3.3":
- version "7.25.7"
- resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.25.7.tgz#27f69ce382855d915b14ab0fe5fb4cbf88fa0769"
- integrity sha512-wRwtAgI3bAS+JGU2upWNL9lSlDcRCqD05BZ1n3X2ONLH1WilFP6O1otQjeMK/1g0pvYcXC7b/qVUB1keofjtZA==
- dependencies:
- "@babel/code-frame" "^7.25.7"
- "@babel/parser" "^7.25.7"
- "@babel/types" "^7.25.7"
-
-"@babel/traverse@^7.25.7":
- version "7.25.7"
- resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.25.7.tgz#83e367619be1cab8e4f2892ef30ba04c26a40fa8"
- integrity sha512-jatJPT1Zjqvh/1FyJs6qAHL+Dzb7sTb+xr7Q+gM1b+1oBsMsQQ4FkVKb6dFlJvLlVssqkRzV05Jzervt9yhnzg==
- dependencies:
- "@babel/code-frame" "^7.25.7"
- "@babel/generator" "^7.25.7"
- "@babel/parser" "^7.25.7"
- "@babel/template" "^7.25.7"
- "@babel/types" "^7.25.7"
- debug "^4.3.1"
- globals "^11.1.0"
-
-"@babel/types@^7.0.0", "@babel/types@^7.20.7", "@babel/types@^7.25.7", "@babel/types@^7.25.8", "@babel/types@^7.3.3":
- version "7.25.8"
- resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.25.8.tgz#5cf6037258e8a9bcad533f4979025140cb9993e1"
- integrity sha512-JWtuCu8VQsMladxVz/P4HzHUGCAwpuqacmowgXFs5XjxIgKuNjnLokQzuVjlTvIzODaDmpjT3oxcC48vyk9EWg==
- dependencies:
- "@babel/helper-string-parser" "^7.25.7"
- "@babel/helper-validator-identifier" "^7.25.7"
- to-fast-properties "^2.0.0"
-
-"@bcoe/v8-coverage@^0.2.3":
- version "0.2.3"
- resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39"
- integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==
-
-"@es-joy/jsdoccomment@~0.41.0":
- version "0.41.0"
- resolved "https://registry.yarnpkg.com/@es-joy/jsdoccomment/-/jsdoccomment-0.41.0.tgz#4a2f7db42209c0425c71a1476ef1bdb6dcd836f6"
- integrity sha512-aKUhyn1QI5Ksbqcr3fFJj16p99QdjUxXAEuFst1Z47DRyoiMwivIH9MV/ARcJOCXVjPfjITciej8ZD2O/6qUmw==
- dependencies:
- comment-parser "1.4.1"
- esquery "^1.5.0"
- jsdoc-type-pratt-parser "~4.0.0"
-
-"@eslint-community/eslint-utils@^4.2.0", "@eslint-community/eslint-utils@^4.4.0":
- version "4.4.0"
- resolved "https://registry.yarnpkg.com/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz#a23514e8fb9af1269d5f7788aa556798d61c6b59"
- integrity sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==
- dependencies:
- eslint-visitor-keys "^3.3.0"
-
-"@eslint-community/regexpp@^4.10.0", "@eslint-community/regexpp@^4.6.1", "@eslint-community/regexpp@^4.8.0", "@eslint-community/regexpp@^4.9.1":
- version "4.11.1"
- resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.11.1.tgz#a547badfc719eb3e5f4b556325e542fbe9d7a18f"
- integrity sha512-m4DVN9ZqskZoLU5GlWZadwDnYo3vAEydiUayB9widCl9ffWx2IvPnp6n3on5rJmziJSw9Bv+Z3ChDVdMwXCY8Q==
-
-"@eslint/eslintrc@^2.1.4":
- version "2.1.4"
- resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-2.1.4.tgz#388a269f0f25c1b6adc317b5a2c55714894c70ad"
- integrity sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==
- dependencies:
- ajv "^6.12.4"
- debug "^4.3.2"
- espree "^9.6.0"
- globals "^13.19.0"
- ignore "^5.2.0"
- import-fresh "^3.2.1"
- js-yaml "^4.1.0"
- minimatch "^3.1.2"
- strip-json-comments "^3.1.1"
-
-"@eslint/js@8.57.1":
- version "8.57.1"
- resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.57.1.tgz#de633db3ec2ef6a3c89e2f19038063e8a122e2c2"
- integrity sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==
-
-"@humanwhocodes/config-array@^0.13.0":
- version "0.13.0"
- resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.13.0.tgz#fb907624df3256d04b9aa2df50d7aa97ec648748"
- integrity sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==
- dependencies:
- "@humanwhocodes/object-schema" "^2.0.3"
- debug "^4.3.1"
- minimatch "^3.0.5"
-
-"@humanwhocodes/module-importer@^1.0.1":
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz#af5b2691a22b44be847b0ca81641c5fb6ad0172c"
- integrity sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==
-
-"@humanwhocodes/object-schema@^2.0.3":
- version "2.0.3"
- resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz#4a2868d75d6d6963e423bcf90b7fd1be343409d3"
- integrity sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==
-
-"@istanbuljs/load-nyc-config@^1.0.0":
- version "1.1.0"
- resolved "https://registry.yarnpkg.com/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz#fd3db1d59ecf7cf121e80650bb86712f9b55eced"
- integrity sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==
- dependencies:
- camelcase "^5.3.1"
- find-up "^4.1.0"
- get-package-type "^0.1.0"
- js-yaml "^3.13.1"
- resolve-from "^5.0.0"
-
-"@istanbuljs/schema@^0.1.2", "@istanbuljs/schema@^0.1.3":
- version "0.1.3"
- resolved "https://registry.yarnpkg.com/@istanbuljs/schema/-/schema-0.1.3.tgz#e45e384e4b8ec16bce2fd903af78450f6bf7ec98"
- integrity sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==
-
-"@jest/console@^29.7.0":
- version "29.7.0"
- resolved "https://registry.yarnpkg.com/@jest/console/-/console-29.7.0.tgz#cd4822dbdb84529265c5a2bdb529a3c9cc950ffc"
- integrity sha512-5Ni4CU7XHQi32IJ398EEP4RrB8eV09sXP2ROqD4bksHrnTree52PsxvX8tpL8LvTZ3pFzXyPbNQReSN41CAhOg==
- dependencies:
- "@jest/types" "^29.6.3"
- "@types/node" "*"
- chalk "^4.0.0"
- jest-message-util "^29.7.0"
- jest-util "^29.7.0"
- slash "^3.0.0"
-
-"@jest/core@^29.7.0":
- version "29.7.0"
- resolved "https://registry.yarnpkg.com/@jest/core/-/core-29.7.0.tgz#b6cccc239f30ff36609658c5a5e2291757ce448f"
- integrity sha512-n7aeXWKMnGtDA48y8TLWJPJmLmmZ642Ceo78cYWEpiD7FzDgmNDV/GCVRorPABdXLJZ/9wzzgZAlHjXjxDHGsg==
- dependencies:
- "@jest/console" "^29.7.0"
- "@jest/reporters" "^29.7.0"
- "@jest/test-result" "^29.7.0"
- "@jest/transform" "^29.7.0"
- "@jest/types" "^29.6.3"
- "@types/node" "*"
- ansi-escapes "^4.2.1"
- chalk "^4.0.0"
- ci-info "^3.2.0"
- exit "^0.1.2"
- graceful-fs "^4.2.9"
- jest-changed-files "^29.7.0"
- jest-config "^29.7.0"
- jest-haste-map "^29.7.0"
- jest-message-util "^29.7.0"
- jest-regex-util "^29.6.3"
- jest-resolve "^29.7.0"
- jest-resolve-dependencies "^29.7.0"
- jest-runner "^29.7.0"
- jest-runtime "^29.7.0"
- jest-snapshot "^29.7.0"
- jest-util "^29.7.0"
- jest-validate "^29.7.0"
- jest-watcher "^29.7.0"
- micromatch "^4.0.4"
- pretty-format "^29.7.0"
- slash "^3.0.0"
- strip-ansi "^6.0.0"
-
-"@jest/environment@^29.7.0":
- version "29.7.0"
- resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-29.7.0.tgz#24d61f54ff1f786f3cd4073b4b94416383baf2a7"
- integrity sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw==
- dependencies:
- "@jest/fake-timers" "^29.7.0"
- "@jest/types" "^29.6.3"
- "@types/node" "*"
- jest-mock "^29.7.0"
-
-"@jest/expect-utils@^29.7.0":
- version "29.7.0"
- resolved "https://registry.yarnpkg.com/@jest/expect-utils/-/expect-utils-29.7.0.tgz#023efe5d26a8a70f21677d0a1afc0f0a44e3a1c6"
- integrity sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA==
- dependencies:
- jest-get-type "^29.6.3"
-
-"@jest/expect@^29.7.0":
- version "29.7.0"
- resolved "https://registry.yarnpkg.com/@jest/expect/-/expect-29.7.0.tgz#76a3edb0cb753b70dfbfe23283510d3d45432bf2"
- integrity sha512-8uMeAMycttpva3P1lBHB8VciS9V0XAr3GymPpipdyQXbBcuhkLQOSe8E/p92RyAdToS6ZD1tFkX+CkhoECE0dQ==
- dependencies:
- expect "^29.7.0"
- jest-snapshot "^29.7.0"
-
-"@jest/fake-timers@^29.7.0":
- version "29.7.0"
- resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-29.7.0.tgz#fd91bf1fffb16d7d0d24a426ab1a47a49881a565"
- integrity sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ==
- dependencies:
- "@jest/types" "^29.6.3"
- "@sinonjs/fake-timers" "^10.0.2"
- "@types/node" "*"
- jest-message-util "^29.7.0"
- jest-mock "^29.7.0"
- jest-util "^29.7.0"
-
-"@jest/globals@^29.7.0":
- version "29.7.0"
- resolved "https://registry.yarnpkg.com/@jest/globals/-/globals-29.7.0.tgz#8d9290f9ec47ff772607fa864ca1d5a2efae1d4d"
- integrity sha512-mpiz3dutLbkW2MNFubUGUEVLkTGiqW6yLVTA+JbP6fI6J5iL9Y0Nlg8k95pcF8ctKwCS7WVxteBs29hhfAotzQ==
- dependencies:
- "@jest/environment" "^29.7.0"
- "@jest/expect" "^29.7.0"
- "@jest/types" "^29.6.3"
- jest-mock "^29.7.0"
-
-"@jest/reporters@^29.7.0":
- version "29.7.0"
- resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-29.7.0.tgz#04b262ecb3b8faa83b0b3d321623972393e8f4c7"
- integrity sha512-DApq0KJbJOEzAFYjHADNNxAE3KbhxQB1y5Kplb5Waqw6zVbuWatSnMjE5gs8FUgEPmNsnZA3NCWl9NG0ia04Pg==
- dependencies:
- "@bcoe/v8-coverage" "^0.2.3"
- "@jest/console" "^29.7.0"
- "@jest/test-result" "^29.7.0"
- "@jest/transform" "^29.7.0"
- "@jest/types" "^29.6.3"
- "@jridgewell/trace-mapping" "^0.3.18"
- "@types/node" "*"
- chalk "^4.0.0"
- collect-v8-coverage "^1.0.0"
- exit "^0.1.2"
- glob "^7.1.3"
- graceful-fs "^4.2.9"
- istanbul-lib-coverage "^3.0.0"
- istanbul-lib-instrument "^6.0.0"
- istanbul-lib-report "^3.0.0"
- istanbul-lib-source-maps "^4.0.0"
- istanbul-reports "^3.1.3"
- jest-message-util "^29.7.0"
- jest-util "^29.7.0"
- jest-worker "^29.7.0"
- slash "^3.0.0"
- string-length "^4.0.1"
- strip-ansi "^6.0.0"
- v8-to-istanbul "^9.0.1"
-
-"@jest/schemas@^29.6.3":
- version "29.6.3"
- resolved "https://registry.yarnpkg.com/@jest/schemas/-/schemas-29.6.3.tgz#430b5ce8a4e0044a7e3819663305a7b3091c8e03"
- integrity sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==
- dependencies:
- "@sinclair/typebox" "^0.27.8"
-
-"@jest/source-map@^29.6.3":
- version "29.6.3"
- resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-29.6.3.tgz#d90ba772095cf37a34a5eb9413f1b562a08554c4"
- integrity sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw==
- dependencies:
- "@jridgewell/trace-mapping" "^0.3.18"
- callsites "^3.0.0"
- graceful-fs "^4.2.9"
-
-"@jest/test-result@^29.7.0":
- version "29.7.0"
- resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-29.7.0.tgz#8db9a80aa1a097bb2262572686734baed9b1657c"
- integrity sha512-Fdx+tv6x1zlkJPcWXmMDAG2HBnaR9XPSd5aDWQVsfrZmLVT3lU1cwyxLgRmXR9yrq4NBoEm9BMsfgFzTQAbJYA==
- dependencies:
- "@jest/console" "^29.7.0"
- "@jest/types" "^29.6.3"
- "@types/istanbul-lib-coverage" "^2.0.0"
- collect-v8-coverage "^1.0.0"
-
-"@jest/test-sequencer@^29.7.0":
- version "29.7.0"
- resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-29.7.0.tgz#6cef977ce1d39834a3aea887a1726628a6f072ce"
- integrity sha512-GQwJ5WZVrKnOJuiYiAF52UNUJXgTZx1NHjFSEB0qEMmSZKAkdMoIzw/Cj6x6NF4AvV23AUqDpFzQkN/eYCYTxw==
- dependencies:
- "@jest/test-result" "^29.7.0"
- graceful-fs "^4.2.9"
- jest-haste-map "^29.7.0"
- slash "^3.0.0"
-
-"@jest/transform@^29.7.0":
- version "29.7.0"
- resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-29.7.0.tgz#df2dd9c346c7d7768b8a06639994640c642e284c"
- integrity sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==
- dependencies:
- "@babel/core" "^7.11.6"
- "@jest/types" "^29.6.3"
- "@jridgewell/trace-mapping" "^0.3.18"
- babel-plugin-istanbul "^6.1.1"
- chalk "^4.0.0"
- convert-source-map "^2.0.0"
- fast-json-stable-stringify "^2.1.0"
- graceful-fs "^4.2.9"
- jest-haste-map "^29.7.0"
- jest-regex-util "^29.6.3"
- jest-util "^29.7.0"
- micromatch "^4.0.4"
- pirates "^4.0.4"
- slash "^3.0.0"
- write-file-atomic "^4.0.2"
-
-"@jest/types@^29.6.3":
- version "29.6.3"
- resolved "https://registry.yarnpkg.com/@jest/types/-/types-29.6.3.tgz#1131f8cf634e7e84c5e77bab12f052af585fba59"
- integrity sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==
- dependencies:
- "@jest/schemas" "^29.6.3"
- "@types/istanbul-lib-coverage" "^2.0.0"
- "@types/istanbul-reports" "^3.0.0"
- "@types/node" "*"
- "@types/yargs" "^17.0.8"
- chalk "^4.0.0"
-
-"@jridgewell/gen-mapping@^0.3.5":
- version "0.3.5"
- resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz#dcce6aff74bdf6dad1a95802b69b04a2fcb1fb36"
- integrity sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==
- dependencies:
- "@jridgewell/set-array" "^1.2.1"
- "@jridgewell/sourcemap-codec" "^1.4.10"
- "@jridgewell/trace-mapping" "^0.3.24"
-
-"@jridgewell/resolve-uri@^3.1.0":
- version "3.1.2"
- resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz#7a0ee601f60f99a20c7c7c5ff0c80388c1189bd6"
- integrity sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==
-
-"@jridgewell/set-array@^1.2.1":
- version "1.2.1"
- resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.2.1.tgz#558fb6472ed16a4c850b889530e6b36438c49280"
- integrity sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==
-
-"@jridgewell/source-map@^0.3.3":
- version "0.3.6"
- resolved "https://registry.yarnpkg.com/@jridgewell/source-map/-/source-map-0.3.6.tgz#9d71ca886e32502eb9362c9a74a46787c36df81a"
- integrity sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==
- dependencies:
- "@jridgewell/gen-mapping" "^0.3.5"
- "@jridgewell/trace-mapping" "^0.3.25"
-
-"@jridgewell/sourcemap-codec@^1.4.10", "@jridgewell/sourcemap-codec@^1.4.14", "@jridgewell/sourcemap-codec@^1.5.0":
- version "1.5.0"
- resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz#3188bcb273a414b0d215fd22a58540b989b9409a"
- integrity sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==
-
-"@jridgewell/trace-mapping@^0.3.12", "@jridgewell/trace-mapping@^0.3.18", "@jridgewell/trace-mapping@^0.3.24", "@jridgewell/trace-mapping@^0.3.25":
- version "0.3.25"
- resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz#15f190e98895f3fc23276ee14bc76b675c2e50f0"
- integrity sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==
- dependencies:
- "@jridgewell/resolve-uri" "^3.1.0"
- "@jridgewell/sourcemap-codec" "^1.4.14"
-
-"@nodelib/fs.scandir@2.1.5":
- version "2.1.5"
- resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5"
- integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==
- dependencies:
- "@nodelib/fs.stat" "2.0.5"
- run-parallel "^1.1.9"
-
-"@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2":
- version "2.0.5"
- resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b"
- integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==
-
-"@nodelib/fs.walk@^1.2.3", "@nodelib/fs.walk@^1.2.8":
- version "1.2.8"
- resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz#e95737e8bb6746ddedf69c556953494f196fe69a"
- integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==
- dependencies:
- "@nodelib/fs.scandir" "2.1.5"
- fastq "^1.6.0"
-
-"@parcel/watcher-android-arm64@2.4.1":
- version "2.4.1"
- resolved "https://registry.yarnpkg.com/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.4.1.tgz#c2c19a3c442313ff007d2d7a9c2c1dd3e1c9ca84"
- integrity sha512-LOi/WTbbh3aTn2RYddrO8pnapixAziFl6SMxHM69r3tvdSm94JtCenaKgk1GRg5FJ5wpMCpHeW+7yqPlvZv7kg==
-
-"@parcel/watcher-darwin-arm64@2.4.1":
- version "2.4.1"
- resolved "https://registry.yarnpkg.com/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.4.1.tgz#c817c7a3b4f3a79c1535bfe54a1c2818d9ffdc34"
- integrity sha512-ln41eihm5YXIY043vBrrHfn94SIBlqOWmoROhsMVTSXGh0QahKGy77tfEywQ7v3NywyxBBkGIfrWRHm0hsKtzA==
-
-"@parcel/watcher-darwin-x64@2.4.1":
- version "2.4.1"
- resolved "https://registry.yarnpkg.com/@parcel/watcher-darwin-x64/-/watcher-darwin-x64-2.4.1.tgz#1a3f69d9323eae4f1c61a5f480a59c478d2cb020"
- integrity sha512-yrw81BRLjjtHyDu7J61oPuSoeYWR3lDElcPGJyOvIXmor6DEo7/G2u1o7I38cwlcoBHQFULqF6nesIX3tsEXMg==
-
-"@parcel/watcher-freebsd-x64@2.4.1":
- version "2.4.1"
- resolved "https://registry.yarnpkg.com/@parcel/watcher-freebsd-x64/-/watcher-freebsd-x64-2.4.1.tgz#0d67fef1609f90ba6a8a662bc76a55fc93706fc8"
- integrity sha512-TJa3Pex/gX3CWIx/Co8k+ykNdDCLx+TuZj3f3h7eOjgpdKM+Mnix37RYsYU4LHhiYJz3DK5nFCCra81p6g050w==
-
-"@parcel/watcher-linux-arm-glibc@2.4.1":
- version "2.4.1"
- resolved "https://registry.yarnpkg.com/@parcel/watcher-linux-arm-glibc/-/watcher-linux-arm-glibc-2.4.1.tgz#ce5b340da5829b8e546bd00f752ae5292e1c702d"
- integrity sha512-4rVYDlsMEYfa537BRXxJ5UF4ddNwnr2/1O4MHM5PjI9cvV2qymvhwZSFgXqbS8YoTk5i/JR0L0JDs69BUn45YA==
-
-"@parcel/watcher-linux-arm64-glibc@2.4.1":
- version "2.4.1"
- resolved "https://registry.yarnpkg.com/@parcel/watcher-linux-arm64-glibc/-/watcher-linux-arm64-glibc-2.4.1.tgz#6d7c00dde6d40608f9554e73998db11b2b1ff7c7"
- integrity sha512-BJ7mH985OADVLpbrzCLgrJ3TOpiZggE9FMblfO65PlOCdG++xJpKUJ0Aol74ZUIYfb8WsRlUdgrZxKkz3zXWYA==
-
-"@parcel/watcher-linux-arm64-musl@2.4.1":
- version "2.4.1"
- resolved "https://registry.yarnpkg.com/@parcel/watcher-linux-arm64-musl/-/watcher-linux-arm64-musl-2.4.1.tgz#bd39bc71015f08a4a31a47cd89c236b9d6a7f635"
- integrity sha512-p4Xb7JGq3MLgAfYhslU2SjoV9G0kI0Xry0kuxeG/41UfpjHGOhv7UoUDAz/jb1u2elbhazy4rRBL8PegPJFBhA==
-
-"@parcel/watcher-linux-x64-glibc@2.4.1":
- version "2.4.1"
- resolved "https://registry.yarnpkg.com/@parcel/watcher-linux-x64-glibc/-/watcher-linux-x64-glibc-2.4.1.tgz#0ce29966b082fb6cdd3de44f2f74057eef2c9e39"
- integrity sha512-s9O3fByZ/2pyYDPoLM6zt92yu6P4E39a03zvO0qCHOTjxmt3GHRMLuRZEWhWLASTMSrrnVNWdVI/+pUElJBBBg==
-
-"@parcel/watcher-linux-x64-musl@2.4.1":
- version "2.4.1"
- resolved "https://registry.yarnpkg.com/@parcel/watcher-linux-x64-musl/-/watcher-linux-x64-musl-2.4.1.tgz#d2ebbf60e407170bb647cd6e447f4f2bab19ad16"
- integrity sha512-L2nZTYR1myLNST0O632g0Dx9LyMNHrn6TOt76sYxWLdff3cB22/GZX2UPtJnaqQPdCRoszoY5rcOj4oMTtp5fQ==
-
-"@parcel/watcher-win32-arm64@2.4.1":
- version "2.4.1"
- resolved "https://registry.yarnpkg.com/@parcel/watcher-win32-arm64/-/watcher-win32-arm64-2.4.1.tgz#eb4deef37e80f0b5e2f215dd6d7a6d40a85f8adc"
- integrity sha512-Uq2BPp5GWhrq/lcuItCHoqxjULU1QYEcyjSO5jqqOK8RNFDBQnenMMx4gAl3v8GiWa59E9+uDM7yZ6LxwUIfRg==
-
-"@parcel/watcher-win32-ia32@2.4.1":
- version "2.4.1"
- resolved "https://registry.yarnpkg.com/@parcel/watcher-win32-ia32/-/watcher-win32-ia32-2.4.1.tgz#94fbd4b497be39fd5c8c71ba05436927842c9df7"
- integrity sha512-maNRit5QQV2kgHFSYwftmPBxiuK5u4DXjbXx7q6eKjq5dsLXZ4FJiVvlcw35QXzk0KrUecJmuVFbj4uV9oYrcw==
-
-"@parcel/watcher-win32-x64@2.4.1":
- version "2.4.1"
- resolved "https://registry.yarnpkg.com/@parcel/watcher-win32-x64/-/watcher-win32-x64-2.4.1.tgz#4bf920912f67cae5f2d264f58df81abfea68dadf"
- integrity sha512-+DvS92F9ezicfswqrvIRM2njcYJbd5mb9CUgtrHCHmvn7pPPa+nMDRu1o1bYYz/l5IB2NVGNJWiH7h1E58IF2A==
-
-"@parcel/watcher@^2.4.1":
- version "2.4.1"
- resolved "https://registry.yarnpkg.com/@parcel/watcher/-/watcher-2.4.1.tgz#a50275151a1bb110879c6123589dba90c19f1bf8"
- integrity sha512-HNjmfLQEVRZmHRET336f20H/8kOozUGwk7yajvsonjNxbj2wBTK1WsQuHkD5yYh9RxFGL2EyDHryOihOwUoKDA==
- dependencies:
- detect-libc "^1.0.3"
- is-glob "^4.0.3"
- micromatch "^4.0.5"
- node-addon-api "^7.0.0"
- optionalDependencies:
- "@parcel/watcher-android-arm64" "2.4.1"
- "@parcel/watcher-darwin-arm64" "2.4.1"
- "@parcel/watcher-darwin-x64" "2.4.1"
- "@parcel/watcher-freebsd-x64" "2.4.1"
- "@parcel/watcher-linux-arm-glibc" "2.4.1"
- "@parcel/watcher-linux-arm64-glibc" "2.4.1"
- "@parcel/watcher-linux-arm64-musl" "2.4.1"
- "@parcel/watcher-linux-x64-glibc" "2.4.1"
- "@parcel/watcher-linux-x64-musl" "2.4.1"
- "@parcel/watcher-win32-arm64" "2.4.1"
- "@parcel/watcher-win32-ia32" "2.4.1"
- "@parcel/watcher-win32-x64" "2.4.1"
-
-"@playcanvas/eslint-config@^1.7.4":
- version "1.7.4"
- resolved "https://registry.yarnpkg.com/@playcanvas/eslint-config/-/eslint-config-1.7.4.tgz#6cae138eaef534602e2f12e3c461d0b6655f8b49"
- integrity sha512-vsjFX3aQ0Zn8LvVyoOvTAnT44qoXYmpbwPtOMuxhCJxMPaM4mWUVgDWBgt7/x32lhD+zKxHnZbHvYBs6d3FZ9g==
- dependencies:
- eslint-plugin-import "^2.28.0"
- eslint-plugin-jsdoc "^46.4.6"
- eslint-plugin-regexp "^2.6.0"
-
-"@playcanvas/observer@^1.4.0":
- version "1.5.1"
- resolved "https://registry.yarnpkg.com/@playcanvas/observer/-/observer-1.5.1.tgz#69c33a0f264ed7d32aad5f844db35fc8377a0fa4"
- integrity sha512-0y4OQOtwhgCvFaNlhLgi4ycSeOdnp0Frf4R+8eewxtfZQW1Muox2lkUGoMywoRRLhaRjUMdaxQN1o53lNjlB9w==
-
-"@playcanvas/pcui@^4.5.0":
- version "4.5.0"
- resolved "https://registry.yarnpkg.com/@playcanvas/pcui/-/pcui-4.5.0.tgz#5516c34decb00571f10e321dbee6548c8e0550a4"
- integrity sha512-djuHqiRUlQcXHjNk/oi7B9tOInv1BEd8FPvqLBLpsVQ2q/4CfpuIPWsCJMMGADnrqHXVK5YaqnuxE8BzcUx7iw==
- dependencies:
- "@playcanvas/observer" "^1.4.0"
-
-"@rollup/plugin-alias@^5.1.1":
- version "5.1.1"
- resolved "https://registry.yarnpkg.com/@rollup/plugin-alias/-/plugin-alias-5.1.1.tgz#53601d88cda8b1577aa130b4a6e452283605bf26"
- integrity sha512-PR9zDb+rOzkRb2VD+EuKB7UC41vU5DIwZ5qqCpk0KJudcWAyi8rvYOhS7+L5aZCspw1stTViLgN5v6FF1p5cgQ==
-
-"@rollup/plugin-image@^3.0.3":
- version "3.0.3"
- resolved "https://registry.yarnpkg.com/@rollup/plugin-image/-/plugin-image-3.0.3.tgz#025b557180bae20f2349ff5130ef2114169feaac"
- integrity sha512-qXWQwsXpvD4trSb8PeFPFajp8JLpRtqqOeNYRUKnEQNHm7e5UP7fuSRcbjQAJ7wDZBbnJvSdY5ujNBQd9B1iFg==
- dependencies:
- "@rollup/pluginutils" "^5.0.1"
- mini-svg-data-uri "^1.4.4"
-
-"@rollup/plugin-json@^6.1.0":
- version "6.1.0"
- resolved "https://registry.yarnpkg.com/@rollup/plugin-json/-/plugin-json-6.1.0.tgz#fbe784e29682e9bb6dee28ea75a1a83702e7b805"
- integrity sha512-EGI2te5ENk1coGeADSIwZ7G2Q8CJS2sF120T7jLw4xFw9n7wIOXHo+kIYRAoVpJAN+kmqZSoO3Fp4JtoNF4ReA==
- dependencies:
- "@rollup/pluginutils" "^5.1.0"
-
-"@rollup/plugin-node-resolve@^15.3.0":
- version "15.3.0"
- resolved "https://registry.yarnpkg.com/@rollup/plugin-node-resolve/-/plugin-node-resolve-15.3.0.tgz#efbb35515c9672e541c08d59caba2eff492a55d5"
- integrity sha512-9eO5McEICxMzJpDW9OnMYSv4Sta3hmt7VtBFz5zR9273suNOydOyq/FrGeGy+KsTRFm8w0SLVhzig2ILFT63Ag==
- dependencies:
- "@rollup/pluginutils" "^5.0.1"
- "@types/resolve" "1.20.2"
- deepmerge "^4.2.2"
- is-module "^1.0.0"
- resolve "^1.22.1"
-
-"@rollup/plugin-strip@^3.0.4":
- version "3.0.4"
- resolved "https://registry.yarnpkg.com/@rollup/plugin-strip/-/plugin-strip-3.0.4.tgz#ad623cc18cf305b484f8bf38fde4ae855c1229e4"
- integrity sha512-LDRV49ZaavxUo2YoKKMQjCxzCxugu1rCPQa0lDYBOWLj6vtzBMr8DcoJjsmg+s450RbKbe3qI9ZLaSO+O1oNbg==
- dependencies:
- "@rollup/pluginutils" "^5.0.1"
- estree-walker "^2.0.2"
- magic-string "^0.30.3"
-
-"@rollup/plugin-terser@^0.4.4":
- version "0.4.4"
- resolved "https://registry.yarnpkg.com/@rollup/plugin-terser/-/plugin-terser-0.4.4.tgz#15dffdb3f73f121aa4fbb37e7ca6be9aeea91962"
- integrity sha512-XHeJC5Bgvs8LfukDwWZp7yeqin6ns8RTl2B9avbejt6tZqsqvVoWI7ZTQrcNsfKEDWBTnTxM8nMDkO2IFFbd0A==
- dependencies:
- serialize-javascript "^6.0.1"
- smob "^1.0.0"
- terser "^5.17.4"
-
-"@rollup/plugin-typescript@^12.1.0":
- version "12.1.1"
- resolved "https://registry.yarnpkg.com/@rollup/plugin-typescript/-/plugin-typescript-12.1.1.tgz#008d16b8283a422650c463f99ae0c610cf6c9727"
- integrity sha512-t7O653DpfB5MbFrqPe/VcKFFkvRuFNp9qId3xq4Eth5xlyymzxNpye2z8Hrl0RIMuXTSr5GGcFpkdlMeacUiFQ==
- dependencies:
- "@rollup/pluginutils" "^5.1.0"
- resolve "^1.22.1"
-
-"@rollup/pluginutils@^5.0.1", "@rollup/pluginutils@^5.1.0":
- version "5.1.2"
- resolved "https://registry.yarnpkg.com/@rollup/pluginutils/-/pluginutils-5.1.2.tgz#d3bc9f0fea4fd4086aaac6aa102f3fa587ce8bd9"
- integrity sha512-/FIdS3PyZ39bjZlwqFnWqCOVnW7o963LtKMwQOD0NhQqw22gSr2YY1afu3FxRip4ZCZNsD5jq6Aaz6QV3D/Njw==
- dependencies:
- "@types/estree" "^1.0.0"
- estree-walker "^2.0.2"
- picomatch "^2.3.1"
-
-"@rollup/rollup-android-arm-eabi@4.24.0":
- version "4.24.0"
- resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.24.0.tgz#1661ff5ea9beb362795304cb916049aba7ac9c54"
- integrity sha512-Q6HJd7Y6xdB48x8ZNVDOqsbh2uByBhgK8PiQgPhwkIw/HC/YX5Ghq2mQY5sRMZWHb3VsFkWooUVOZHKr7DmDIA==
-
-"@rollup/rollup-android-arm64@4.24.0":
- version "4.24.0"
- resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.24.0.tgz#2ffaa91f1b55a0082b8a722525741aadcbd3971e"
- integrity sha512-ijLnS1qFId8xhKjT81uBHuuJp2lU4x2yxa4ctFPtG+MqEE6+C5f/+X/bStmxapgmwLwiL3ih122xv8kVARNAZA==
-
-"@rollup/rollup-darwin-arm64@4.24.0":
- version "4.24.0"
- resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.24.0.tgz#627007221b24b8cc3063703eee0b9177edf49c1f"
- integrity sha512-bIv+X9xeSs1XCk6DVvkO+S/z8/2AMt/2lMqdQbMrmVpgFvXlmde9mLcbQpztXm1tajC3raFDqegsH18HQPMYtA==
-
-"@rollup/rollup-darwin-x64@4.24.0":
- version "4.24.0"
- resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.24.0.tgz#0605506142b9e796c370d59c5984ae95b9758724"
- integrity sha512-X6/nOwoFN7RT2svEQWUsW/5C/fYMBe4fnLK9DQk4SX4mgVBiTA9h64kjUYPvGQ0F/9xwJ5U5UfTbl6BEjaQdBQ==
-
-"@rollup/rollup-linux-arm-gnueabihf@4.24.0":
- version "4.24.0"
- resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.24.0.tgz#62dfd196d4b10c0c2db833897164d2d319ee0cbb"
- integrity sha512-0KXvIJQMOImLCVCz9uvvdPgfyWo93aHHp8ui3FrtOP57svqrF/roSSR5pjqL2hcMp0ljeGlU4q9o/rQaAQ3AYA==
-
-"@rollup/rollup-linux-arm-musleabihf@4.24.0":
- version "4.24.0"
- resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.24.0.tgz#53ce72aeb982f1f34b58b380baafaf6a240fddb3"
- integrity sha512-it2BW6kKFVh8xk/BnHfakEeoLPv8STIISekpoF+nBgWM4d55CZKc7T4Dx1pEbTnYm/xEKMgy1MNtYuoA8RFIWw==
-
-"@rollup/rollup-linux-arm64-gnu@4.24.0":
- version "4.24.0"
- resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.24.0.tgz#1632990f62a75c74f43e4b14ab3597d7ed416496"
- integrity sha512-i0xTLXjqap2eRfulFVlSnM5dEbTVque/3Pi4g2y7cxrs7+a9De42z4XxKLYJ7+OhE3IgxvfQM7vQc43bwTgPwA==
-
-"@rollup/rollup-linux-arm64-musl@4.24.0":
- version "4.24.0"
- resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.24.0.tgz#8c03a996efb41e257b414b2e0560b7a21f2d9065"
- integrity sha512-9E6MKUJhDuDh604Qco5yP/3qn3y7SLXYuiC0Rpr89aMScS2UAmK1wHP2b7KAa1nSjWJc/f/Lc0Wl1L47qjiyQw==
-
-"@rollup/rollup-linux-powerpc64le-gnu@4.24.0":
- version "4.24.0"
- resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.24.0.tgz#5b98729628d5bcc8f7f37b58b04d6845f85c7b5d"
- integrity sha512-2XFFPJ2XMEiF5Zi2EBf4h73oR1V/lycirxZxHZNc93SqDN/IWhYYSYj8I9381ikUFXZrz2v7r2tOVk2NBwxrWw==
-
-"@rollup/rollup-linux-riscv64-gnu@4.24.0":
- version "4.24.0"
- resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.24.0.tgz#48e42e41f4cabf3573cfefcb448599c512e22983"
- integrity sha512-M3Dg4hlwuntUCdzU7KjYqbbd+BLq3JMAOhCKdBE3TcMGMZbKkDdJ5ivNdehOssMCIokNHFOsv7DO4rlEOfyKpg==
-
-"@rollup/rollup-linux-s390x-gnu@4.24.0":
- version "4.24.0"
- resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.24.0.tgz#e0b4f9a966872cb7d3e21b9e412a4b7efd7f0b58"
- integrity sha512-mjBaoo4ocxJppTorZVKWFpy1bfFj9FeCMJqzlMQGjpNPY9JwQi7OuS1axzNIk0nMX6jSgy6ZURDZ2w0QW6D56g==
-
-"@rollup/rollup-linux-x64-gnu@4.24.0":
- version "4.24.0"
- resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.24.0.tgz#78144741993100f47bd3da72fce215e077ae036b"
- integrity sha512-ZXFk7M72R0YYFN5q13niV0B7G8/5dcQ9JDp8keJSfr3GoZeXEoMHP/HlvqROA3OMbMdfr19IjCeNAnPUG93b6A==
-
-"@rollup/rollup-linux-x64-musl@4.24.0":
- version "4.24.0"
- resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.24.0.tgz#d9fe32971883cd1bd858336bd33a1c3ca6146127"
- integrity sha512-w1i+L7kAXZNdYl+vFvzSZy8Y1arS7vMgIy8wusXJzRrPyof5LAb02KGr1PD2EkRcl73kHulIID0M501lN+vobQ==
-
-"@rollup/rollup-win32-arm64-msvc@4.24.0":
- version "4.24.0"
- resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.24.0.tgz#71fa3ea369316db703a909c790743972e98afae5"
- integrity sha512-VXBrnPWgBpVDCVY6XF3LEW0pOU51KbaHhccHw6AS6vBWIC60eqsH19DAeeObl+g8nKAz04QFdl/Cefta0xQtUQ==
-
-"@rollup/rollup-win32-ia32-msvc@4.24.0":
- version "4.24.0"
- resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.24.0.tgz#653f5989a60658e17d7576a3996deb3902e342e2"
- integrity sha512-xrNcGDU0OxVcPTH/8n/ShH4UevZxKIO6HJFK0e15XItZP2UcaiLFd5kiX7hJnqCbSztUF8Qot+JWBC/QXRPYWQ==
-
-"@rollup/rollup-win32-x64-msvc@4.24.0":
- version "4.24.0"
- resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.24.0.tgz#0574d7e87b44ee8511d08cc7f914bcb802b70818"
- integrity sha512-fbMkAF7fufku0N2dE5TBXcNlg0pt0cJue4xBRE2Qc5Vqikxr4VCgKj/ht6SMdFcOacVA9rqF70APJ8RN/4vMJw==
-
-"@rtsao/scc@^1.1.0":
- version "1.1.0"
- resolved "https://registry.yarnpkg.com/@rtsao/scc/-/scc-1.1.0.tgz#927dd2fae9bc3361403ac2c7a00c32ddce9ad7e8"
- integrity sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==
-
-"@sinclair/typebox@^0.27.8":
- version "0.27.8"
- resolved "https://registry.yarnpkg.com/@sinclair/typebox/-/typebox-0.27.8.tgz#6667fac16c436b5434a387a34dedb013198f6e6e"
- integrity sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==
-
-"@sinonjs/commons@^3.0.0":
- version "3.0.1"
- resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-3.0.1.tgz#1029357e44ca901a615585f6d27738dbc89084cd"
- integrity sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==
- dependencies:
- type-detect "4.0.8"
-
-"@sinonjs/fake-timers@^10.0.2":
- version "10.3.0"
- resolved "https://registry.yarnpkg.com/@sinonjs/fake-timers/-/fake-timers-10.3.0.tgz#55fdff1ecab9f354019129daf4df0dd4d923ea66"
- integrity sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==
- dependencies:
- "@sinonjs/commons" "^3.0.0"
-
-"@trysound/sax@0.2.0":
- version "0.2.0"
- resolved "https://registry.yarnpkg.com/@trysound/sax/-/sax-0.2.0.tgz#cccaab758af56761eb7bf37af6f03f326dd798ad"
- integrity sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==
-
-"@types/babel__core@^7.1.14":
- version "7.20.5"
- resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.20.5.tgz#3df15f27ba85319caa07ba08d0721889bb39c017"
- integrity sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==
- dependencies:
- "@babel/parser" "^7.20.7"
- "@babel/types" "^7.20.7"
- "@types/babel__generator" "*"
- "@types/babel__template" "*"
- "@types/babel__traverse" "*"
-
-"@types/babel__generator@*":
- version "7.6.8"
- resolved "https://registry.yarnpkg.com/@types/babel__generator/-/babel__generator-7.6.8.tgz#f836c61f48b1346e7d2b0d93c6dacc5b9535d3ab"
- integrity sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==
- dependencies:
- "@babel/types" "^7.0.0"
-
-"@types/babel__template@*":
- version "7.4.4"
- resolved "https://registry.yarnpkg.com/@types/babel__template/-/babel__template-7.4.4.tgz#5672513701c1b2199bc6dad636a9d7491586766f"
- integrity sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==
- dependencies:
- "@babel/parser" "^7.1.0"
- "@babel/types" "^7.0.0"
-
-"@types/babel__traverse@*", "@types/babel__traverse@^7.0.6":
- version "7.20.6"
- resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.20.6.tgz#8dc9f0ae0f202c08d8d4dab648912c8d6038e3f7"
- integrity sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg==
- dependencies:
- "@babel/types" "^7.20.7"
-
-"@types/estree@1.0.6", "@types/estree@^1.0.0":
- version "1.0.6"
- resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.6.tgz#628effeeae2064a1b4e79f78e81d87b7e5fc7b50"
- integrity sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==
-
-"@types/graceful-fs@^4.1.3":
- version "4.1.9"
- resolved "https://registry.yarnpkg.com/@types/graceful-fs/-/graceful-fs-4.1.9.tgz#2a06bc0f68a20ab37b3e36aa238be6abdf49e8b4"
- integrity sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==
- dependencies:
- "@types/node" "*"
-
-"@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0", "@types/istanbul-lib-coverage@^2.0.1":
- version "2.0.6"
- resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz#7739c232a1fee9b4d3ce8985f314c0c6d33549d7"
- integrity sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==
-
-"@types/istanbul-lib-report@*":
- version "3.0.3"
- resolved "https://registry.yarnpkg.com/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz#53047614ae72e19fc0401d872de3ae2b4ce350bf"
- integrity sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==
- dependencies:
- "@types/istanbul-lib-coverage" "*"
-
-"@types/istanbul-reports@^3.0.0":
- version "3.0.4"
- resolved "https://registry.yarnpkg.com/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz#0f03e3d2f670fbdac586e34b433783070cc16f54"
- integrity sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==
- dependencies:
- "@types/istanbul-lib-report" "*"
-
-"@types/json5@^0.0.29":
- version "0.0.29"
- resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee"
- integrity sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==
-
-"@types/node@*":
- version "22.7.7"
- resolved "https://registry.yarnpkg.com/@types/node/-/node-22.7.7.tgz#6cd9541c3dccb4f7e8b141b491443f4a1570e307"
- integrity sha512-SRxCrrg9CL/y54aiMCG3edPKdprgMVGDXjA3gB8UmmBW5TcXzRUYAh8EWzTnSJFAd1rgImPELza+A3bJ+qxz8Q==
- dependencies:
- undici-types "~6.19.2"
-
-"@types/resolve@1.20.2":
- version "1.20.2"
- resolved "https://registry.yarnpkg.com/@types/resolve/-/resolve-1.20.2.tgz#97d26e00cd4a0423b4af620abecf3e6f442b7975"
- integrity sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==
-
-"@types/stack-utils@^2.0.0":
- version "2.0.3"
- resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-2.0.3.tgz#6209321eb2c1712a7e7466422b8cb1fc0d9dd5d8"
- integrity sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==
-
-"@types/webxr@^0.5.16":
- version "0.5.20"
- resolved "https://registry.yarnpkg.com/@types/webxr/-/webxr-0.5.20.tgz#b16b681af314ec011b2e8221b0a072d691c04953"
- integrity sha512-JGpU6qiIJQKUuVSKx1GtQnHJGxRjtfGIhzO2ilq43VZZS//f1h1Sgexbdk+Lq+7569a6EYhOWrUpIruR/1Enmg==
-
-"@types/wicg-file-system-access@^2023.10.5":
- version "2023.10.5"
- resolved "https://registry.yarnpkg.com/@types/wicg-file-system-access/-/wicg-file-system-access-2023.10.5.tgz#14b3c25eb4d914b5734795bdea71da229f918b9d"
- integrity sha512-e9kZO9kCdLqT2h9Tw38oGv9UNzBBWaR1MzuAavxPcsV/7FJ3tWbU6RI3uB+yKIDPGLkGVbplS52ub0AcRLvrhA==
-
-"@types/yargs-parser@*":
- version "21.0.3"
- resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-21.0.3.tgz#815e30b786d2e8f0dcd85fd5bcf5e1a04d008f15"
- integrity sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==
-
-"@types/yargs@^17.0.8":
- version "17.0.33"
- resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-17.0.33.tgz#8c32303da83eec050a84b3c7ae7b9f922d13e32d"
- integrity sha512-WpxBCKWPLr4xSsHgz511rFJAM+wS28w2zEO1QDNY5zM/S8ok70NNfztH0xwhqKyaK0OHCbN98LDAZuy1ctxDkA==
- dependencies:
- "@types/yargs-parser" "*"
-
-"@typescript-eslint/eslint-plugin@^7.15.0":
- version "7.18.0"
- resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.18.0.tgz#b16d3cf3ee76bf572fdf511e79c248bdec619ea3"
- integrity sha512-94EQTWZ40mzBc42ATNIBimBEDltSJ9RQHCC8vc/PDbxi4k8dVwUAv4o98dk50M1zB+JGFxp43FP7f8+FP8R6Sw==
- dependencies:
- "@eslint-community/regexpp" "^4.10.0"
- "@typescript-eslint/scope-manager" "7.18.0"
- "@typescript-eslint/type-utils" "7.18.0"
- "@typescript-eslint/utils" "7.18.0"
- "@typescript-eslint/visitor-keys" "7.18.0"
- graphemer "^1.4.0"
- ignore "^5.3.1"
- natural-compare "^1.4.0"
- ts-api-utils "^1.3.0"
-
-"@typescript-eslint/parser@^7.15.0":
- version "7.18.0"
- resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-7.18.0.tgz#83928d0f1b7f4afa974098c64b5ce6f9051f96a0"
- integrity sha512-4Z+L8I2OqhZV8qA132M4wNL30ypZGYOQVBfMgxDH/K5UX0PNqTu1c6za9ST5r9+tavvHiTWmBnKzpCJ/GlVFtg==
- dependencies:
- "@typescript-eslint/scope-manager" "7.18.0"
- "@typescript-eslint/types" "7.18.0"
- "@typescript-eslint/typescript-estree" "7.18.0"
- "@typescript-eslint/visitor-keys" "7.18.0"
- debug "^4.3.4"
-
-"@typescript-eslint/scope-manager@7.18.0":
- version "7.18.0"
- resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-7.18.0.tgz#c928e7a9fc2c0b3ed92ab3112c614d6bd9951c83"
- integrity sha512-jjhdIE/FPF2B7Z1uzc6i3oWKbGcHb87Qw7AWj6jmEqNOfDFbJWtjt/XfwCpvNkpGWlcJaog5vTR+VV8+w9JflA==
- dependencies:
- "@typescript-eslint/types" "7.18.0"
- "@typescript-eslint/visitor-keys" "7.18.0"
-
-"@typescript-eslint/type-utils@7.18.0":
- version "7.18.0"
- resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-7.18.0.tgz#2165ffaee00b1fbbdd2d40aa85232dab6998f53b"
- integrity sha512-XL0FJXuCLaDuX2sYqZUUSOJ2sG5/i1AAze+axqmLnSkNEVMVYLF+cbwlB2w8D1tinFuSikHmFta+P+HOofrLeA==
- dependencies:
- "@typescript-eslint/typescript-estree" "7.18.0"
- "@typescript-eslint/utils" "7.18.0"
- debug "^4.3.4"
- ts-api-utils "^1.3.0"
-
-"@typescript-eslint/types@7.18.0":
- version "7.18.0"
- resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-7.18.0.tgz#b90a57ccdea71797ffffa0321e744f379ec838c9"
- integrity sha512-iZqi+Ds1y4EDYUtlOOC+aUmxnE9xS/yCigkjA7XpTKV6nCBd3Hp/PRGGmdwnfkV2ThMyYldP1wRpm/id99spTQ==
-
-"@typescript-eslint/typescript-estree@7.18.0":
- version "7.18.0"
- resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-7.18.0.tgz#b5868d486c51ce8f312309ba79bdb9f331b37931"
- integrity sha512-aP1v/BSPnnyhMHts8cf1qQ6Q1IFwwRvAQGRvBFkWlo3/lH29OXA3Pts+c10nxRxIBrDnoMqzhgdwVe5f2D6OzA==
- dependencies:
- "@typescript-eslint/types" "7.18.0"
- "@typescript-eslint/visitor-keys" "7.18.0"
- debug "^4.3.4"
- globby "^11.1.0"
- is-glob "^4.0.3"
- minimatch "^9.0.4"
- semver "^7.6.0"
- ts-api-utils "^1.3.0"
-
-"@typescript-eslint/utils@7.18.0":
- version "7.18.0"
- resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-7.18.0.tgz#bca01cde77f95fc6a8d5b0dbcbfb3d6ca4be451f"
- integrity sha512-kK0/rNa2j74XuHVcoCZxdFBMF+aq/vH83CXAOHieC+2Gis4mF8jJXT5eAfyD3K0sAxtPuwxaIOIOvhwzVDt/kw==
- dependencies:
- "@eslint-community/eslint-utils" "^4.4.0"
- "@typescript-eslint/scope-manager" "7.18.0"
- "@typescript-eslint/types" "7.18.0"
- "@typescript-eslint/typescript-estree" "7.18.0"
-
-"@typescript-eslint/visitor-keys@7.18.0":
- version "7.18.0"
- resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-7.18.0.tgz#0564629b6124d67607378d0f0332a0495b25e7d7"
- integrity sha512-cDF0/Gf81QpY3xYyJKDV14Zwdmid5+uuENhjH2EqFaF0ni+yAyq/LzMaIJdhNJXZI7uLzwIlA+V7oWoyn6Curg==
- dependencies:
- "@typescript-eslint/types" "7.18.0"
- eslint-visitor-keys "^3.4.3"
-
-"@ungap/structured-clone@^1.2.0":
- version "1.2.0"
- resolved "https://registry.yarnpkg.com/@ungap/structured-clone/-/structured-clone-1.2.0.tgz#756641adb587851b5ccb3e095daf27ae581c8406"
- integrity sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==
-
-"@webgpu/types@^0.1.40":
- version "0.1.49"
- resolved "https://registry.yarnpkg.com/@webgpu/types/-/types-0.1.49.tgz#eb9f6535e321214e5c6e9dcc6c7d17e0f7584707"
- integrity sha512-NMmS8/DofhH/IFeW+876XrHVWel+J/vdcFCHLDqeJgkH9x0DeiwjVd8LcBdaxdG/T7Rf8VUAYsA8X1efMzLjRQ==
-
-"@zeit/schemas@2.36.0":
- version "2.36.0"
- resolved "https://registry.yarnpkg.com/@zeit/schemas/-/schemas-2.36.0.tgz#7a1b53f4091e18d0b404873ea3e3c83589c765f2"
- integrity sha512-7kjMwcChYEzMKjeex9ZFXkt1AyNov9R5HZtjBKVsmVpw7pa7ZtlCGvCBC2vnnXctaYN+aRI61HjIqeetZW5ROg==
-
-accepts@~1.3.5:
- version "1.3.8"
- resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.8.tgz#0bf0be125b67014adcb0b0921e62db7bffe16b2e"
- integrity sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==
- dependencies:
- mime-types "~2.1.34"
- negotiator "0.6.3"
-
-acorn-jsx@^5.3.2:
- version "5.3.2"
- resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937"
- integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==
-
-acorn@^8.8.2, acorn@^8.9.0:
- version "8.13.0"
- resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.13.0.tgz#2a30d670818ad16ddd6a35d3842dacec9e5d7ca3"
- integrity sha512-8zSiw54Oxrdym50NlZ9sUusyO1Z1ZchgRLWRaK6c86XJFClyCgFKetdowBg5bKxyp/u+CDBJG4Mpp0m3HLZl9w==
-
-ajv@8.12.0:
- version "8.12.0"
- resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.12.0.tgz#d1a0527323e22f53562c567c00991577dfbe19d1"
- integrity sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==
- dependencies:
- fast-deep-equal "^3.1.1"
- json-schema-traverse "^1.0.0"
- require-from-string "^2.0.2"
- uri-js "^4.2.2"
-
-ajv@^6.12.4:
- version "6.12.6"
- resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4"
- integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==
- dependencies:
- fast-deep-equal "^3.1.1"
- fast-json-stable-stringify "^2.0.0"
- json-schema-traverse "^0.4.1"
- uri-js "^4.2.2"
-
-ansi-align@^3.0.1:
- version "3.0.1"
- resolved "https://registry.yarnpkg.com/ansi-align/-/ansi-align-3.0.1.tgz#0cdf12e111ace773a86e9a1fad1225c43cb19a59"
- integrity sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==
- dependencies:
- string-width "^4.1.0"
-
-ansi-escapes@^4.2.1:
- version "4.3.2"
- resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.2.tgz#6b2291d1db7d98b6521d5f1efa42d0f3a9feb65e"
- integrity sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==
- dependencies:
- type-fest "^0.21.3"
-
-ansi-regex@^5.0.1:
- version "5.0.1"
- resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304"
- integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==
-
-ansi-regex@^6.0.1:
- version "6.1.0"
- resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-6.1.0.tgz#95ec409c69619d6cb1b8b34f14b660ef28ebd654"
- integrity sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==
-
-ansi-styles@^3.2.1:
- version "3.2.1"
- resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d"
- integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==
- dependencies:
- color-convert "^1.9.0"
-
-ansi-styles@^4.0.0, ansi-styles@^4.1.0:
- version "4.3.0"
- resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937"
- integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==
- dependencies:
- color-convert "^2.0.1"
-
-ansi-styles@^5.0.0:
- version "5.2.0"
- resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-5.2.0.tgz#07449690ad45777d1924ac2abb2fc8895dba836b"
- integrity sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==
-
-ansi-styles@^6.1.0:
- version "6.2.1"
- resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-6.2.1.tgz#0e62320cf99c21afff3b3012192546aacbfb05c5"
- integrity sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==
-
-anymatch@^3.0.3:
- version "3.1.3"
- resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.3.tgz#790c58b19ba1720a84205b57c618d5ad8524973e"
- integrity sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==
- dependencies:
- normalize-path "^3.0.0"
- picomatch "^2.0.4"
-
-arch@^2.2.0:
- version "2.2.0"
- resolved "https://registry.yarnpkg.com/arch/-/arch-2.2.0.tgz#1bc47818f305764f23ab3306b0bfc086c5a29d11"
- integrity sha512-Of/R0wqp83cgHozfIYLbBMnej79U/SVGOOyuB3VVFv1NRM/PSFMK12x9KVtiYzJqmnU5WR2qp0Z5rHb7sWGnFQ==
-
-are-docs-informative@^0.0.2:
- version "0.0.2"
- resolved "https://registry.yarnpkg.com/are-docs-informative/-/are-docs-informative-0.0.2.tgz#387f0e93f5d45280373d387a59d34c96db321963"
- integrity sha512-ixiS0nLNNG5jNQzgZJNoUpBKdo9yTYZMGJ+QgT2jmjR7G7+QHRCc4v6LQ3NgE7EBJq+o0ams3waJwkrlBom8Ig==
-
-arg@5.0.2:
- version "5.0.2"
- resolved "https://registry.yarnpkg.com/arg/-/arg-5.0.2.tgz#c81433cc427c92c4dcf4865142dbca6f15acd59c"
- integrity sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==
-
-argparse@^1.0.7:
- version "1.0.10"
- resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911"
- integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==
- dependencies:
- sprintf-js "~1.0.2"
-
-argparse@^2.0.1:
- version "2.0.1"
- resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38"
- integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==
-
-array-buffer-byte-length@^1.0.1:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz#1e5583ec16763540a27ae52eed99ff899223568f"
- integrity sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==
- dependencies:
- call-bind "^1.0.5"
- is-array-buffer "^3.0.4"
-
-array-includes@^3.1.8:
- version "3.1.8"
- resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.1.8.tgz#5e370cbe172fdd5dd6530c1d4aadda25281ba97d"
- integrity sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ==
- dependencies:
- call-bind "^1.0.7"
- define-properties "^1.2.1"
- es-abstract "^1.23.2"
- es-object-atoms "^1.0.0"
- get-intrinsic "^1.2.4"
- is-string "^1.0.7"
-
-array-union@^2.1.0:
- version "2.1.0"
- resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d"
- integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==
-
-array.prototype.findlastindex@^1.2.5:
- version "1.2.5"
- resolved "https://registry.yarnpkg.com/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.5.tgz#8c35a755c72908719453f87145ca011e39334d0d"
- integrity sha512-zfETvRFA8o7EiNn++N5f/kaCw221hrpGsDmcpndVupkPzEc1Wuf3VgC0qby1BbHs7f5DVYjgtEU2LLh5bqeGfQ==
- dependencies:
- call-bind "^1.0.7"
- define-properties "^1.2.1"
- es-abstract "^1.23.2"
- es-errors "^1.3.0"
- es-object-atoms "^1.0.0"
- es-shim-unscopables "^1.0.2"
-
-array.prototype.flat@^1.3.2:
- version "1.3.2"
- resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz#1476217df8cff17d72ee8f3ba06738db5b387d18"
- integrity sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==
- dependencies:
- call-bind "^1.0.2"
- define-properties "^1.2.0"
- es-abstract "^1.22.1"
- es-shim-unscopables "^1.0.0"
-
-array.prototype.flatmap@^1.3.2:
- version "1.3.2"
- resolved "https://registry.yarnpkg.com/array.prototype.flatmap/-/array.prototype.flatmap-1.3.2.tgz#c9a7c6831db8e719d6ce639190146c24bbd3e527"
- integrity sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==
- dependencies:
- call-bind "^1.0.2"
- define-properties "^1.2.0"
- es-abstract "^1.22.1"
- es-shim-unscopables "^1.0.0"
-
-arraybuffer.prototype.slice@^1.0.3:
- version "1.0.3"
- resolved "https://registry.yarnpkg.com/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.3.tgz#097972f4255e41bc3425e37dc3f6421cf9aefde6"
- integrity sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==
- dependencies:
- array-buffer-byte-length "^1.0.1"
- call-bind "^1.0.5"
- define-properties "^1.2.1"
- es-abstract "^1.22.3"
- es-errors "^1.2.1"
- get-intrinsic "^1.2.3"
- is-array-buffer "^3.0.4"
- is-shared-array-buffer "^1.0.2"
-
-autoprefixer@^10.4.20:
- version "10.4.20"
- resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-10.4.20.tgz#5caec14d43976ef42e32dcb4bd62878e96be5b3b"
- integrity sha512-XY25y5xSv/wEoqzDyXXME4AFfkZI0P23z6Fs3YgymDnKJkCGOnkL0iTxCa85UTqaSgfcqyf3UA6+c7wUvx/16g==
- dependencies:
- browserslist "^4.23.3"
- caniuse-lite "^1.0.30001646"
- fraction.js "^4.3.7"
- normalize-range "^0.1.2"
- picocolors "^1.0.1"
- postcss-value-parser "^4.2.0"
-
-available-typed-arrays@^1.0.7:
- version "1.0.7"
- resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz#a5cc375d6a03c2efc87a553f3e0b1522def14846"
- integrity sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==
- dependencies:
- possible-typed-array-names "^1.0.0"
-
-babel-jest@^29.7.0:
- version "29.7.0"
- resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-29.7.0.tgz#f4369919225b684c56085998ac63dbd05be020d5"
- integrity sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==
- dependencies:
- "@jest/transform" "^29.7.0"
- "@types/babel__core" "^7.1.14"
- babel-plugin-istanbul "^6.1.1"
- babel-preset-jest "^29.6.3"
- chalk "^4.0.0"
- graceful-fs "^4.2.9"
- slash "^3.0.0"
-
-babel-plugin-istanbul@^6.1.1:
- version "6.1.1"
- resolved "https://registry.yarnpkg.com/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz#fa88ec59232fd9b4e36dbbc540a8ec9a9b47da73"
- integrity sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==
- dependencies:
- "@babel/helper-plugin-utils" "^7.0.0"
- "@istanbuljs/load-nyc-config" "^1.0.0"
- "@istanbuljs/schema" "^0.1.2"
- istanbul-lib-instrument "^5.0.4"
- test-exclude "^6.0.0"
-
-babel-plugin-jest-hoist@^29.6.3:
- version "29.6.3"
- resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.6.3.tgz#aadbe943464182a8922c3c927c3067ff40d24626"
- integrity sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==
- dependencies:
- "@babel/template" "^7.3.3"
- "@babel/types" "^7.3.3"
- "@types/babel__core" "^7.1.14"
- "@types/babel__traverse" "^7.0.6"
-
-babel-preset-current-node-syntax@^1.0.0:
- version "1.1.0"
- resolved "https://registry.yarnpkg.com/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.1.0.tgz#9a929eafece419612ef4ae4f60b1862ebad8ef30"
- integrity sha512-ldYss8SbBlWva1bs28q78Ju5Zq1F+8BrqBZZ0VFhLBvhh6lCpC2o3gDJi/5DRLs9FgYZCnmPYIVFU4lRXCkyUw==
- dependencies:
- "@babel/plugin-syntax-async-generators" "^7.8.4"
- "@babel/plugin-syntax-bigint" "^7.8.3"
- "@babel/plugin-syntax-class-properties" "^7.12.13"
- "@babel/plugin-syntax-class-static-block" "^7.14.5"
- "@babel/plugin-syntax-import-attributes" "^7.24.7"
- "@babel/plugin-syntax-import-meta" "^7.10.4"
- "@babel/plugin-syntax-json-strings" "^7.8.3"
- "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4"
- "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3"
- "@babel/plugin-syntax-numeric-separator" "^7.10.4"
- "@babel/plugin-syntax-object-rest-spread" "^7.8.3"
- "@babel/plugin-syntax-optional-catch-binding" "^7.8.3"
- "@babel/plugin-syntax-optional-chaining" "^7.8.3"
- "@babel/plugin-syntax-private-property-in-object" "^7.14.5"
- "@babel/plugin-syntax-top-level-await" "^7.14.5"
-
-babel-preset-jest@^29.6.3:
- version "29.6.3"
- resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-29.6.3.tgz#fa05fa510e7d493896d7b0dd2033601c840f171c"
- integrity sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA==
- dependencies:
- babel-plugin-jest-hoist "^29.6.3"
- babel-preset-current-node-syntax "^1.0.0"
-
-balanced-match@^1.0.0:
- version "1.0.2"
- resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee"
- integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==
-
-boolbase@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e"
- integrity sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==
-
-boxen@7.0.0:
- version "7.0.0"
- resolved "https://registry.yarnpkg.com/boxen/-/boxen-7.0.0.tgz#9e5f8c26e716793fc96edcf7cf754cdf5e3fbf32"
- integrity sha512-j//dBVuyacJbvW+tvZ9HuH03fZ46QcaKvvhZickZqtB271DxJ7SNRSNxrV/dZX0085m7hISRZWbzWlJvx/rHSg==
- dependencies:
- ansi-align "^3.0.1"
- camelcase "^7.0.0"
- chalk "^5.0.1"
- cli-boxes "^3.0.0"
- string-width "^5.1.2"
- type-fest "^2.13.0"
- widest-line "^4.0.1"
- wrap-ansi "^8.0.1"
-
-brace-expansion@^1.1.7:
- version "1.1.11"
- resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd"
- integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==
- dependencies:
- balanced-match "^1.0.0"
- concat-map "0.0.1"
-
-brace-expansion@^2.0.1:
- version "2.0.1"
- resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.0.1.tgz#1edc459e0f0c548486ecf9fc99f2221364b9a0ae"
- integrity sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==
- dependencies:
- balanced-match "^1.0.0"
-
-braces@^3.0.3:
- version "3.0.3"
- resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.3.tgz#490332f40919452272d55a8480adc0c441358789"
- integrity sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==
- dependencies:
- fill-range "^7.1.1"
-
-browserslist@^4.0.0, browserslist@^4.21.4, browserslist@^4.23.3, browserslist@^4.24.0:
- version "4.24.0"
- resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.24.0.tgz#a1325fe4bc80b64fda169629fc01b3d6cecd38d4"
- integrity sha512-Rmb62sR1Zpjql25eSanFGEhAxcFwfA1K0GuQcLoaJBAcENegrQut3hYdhXFF1obQfiDyqIW/cLM5HSJ/9k884A==
- dependencies:
- caniuse-lite "^1.0.30001663"
- electron-to-chromium "^1.5.28"
- node-releases "^2.0.18"
- update-browserslist-db "^1.1.0"
-
-bser@2.1.1:
- version "2.1.1"
- resolved "https://registry.yarnpkg.com/bser/-/bser-2.1.1.tgz#e6787da20ece9d07998533cfd9de6f5c38f4bc05"
- integrity sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==
- dependencies:
- node-int64 "^0.4.0"
-
-buffer-from@^1.0.0:
- version "1.1.2"
- resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5"
- integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==
-
-builtin-modules@^3.3.0:
- version "3.3.0"
- resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-3.3.0.tgz#cae62812b89801e9656336e46223e030386be7b6"
- integrity sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==
-
-bytes@3.0.0:
- version "3.0.0"
- resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048"
- integrity sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==
-
-call-bind@^1.0.2, call-bind@^1.0.5, call-bind@^1.0.6, call-bind@^1.0.7:
- version "1.0.7"
- resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.7.tgz#06016599c40c56498c18769d2730be242b6fa3b9"
- integrity sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==
- dependencies:
- es-define-property "^1.0.0"
- es-errors "^1.3.0"
- function-bind "^1.1.2"
- get-intrinsic "^1.2.4"
- set-function-length "^1.2.1"
-
-callsites@^3.0.0:
- version "3.1.0"
- resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73"
- integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==
-
-camelcase@^5.3.1:
- version "5.3.1"
- resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320"
- integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==
-
-camelcase@^6.2.0:
- version "6.3.0"
- resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a"
- integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==
-
-camelcase@^7.0.0:
- version "7.0.1"
- resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-7.0.1.tgz#f02e50af9fd7782bc8b88a3558c32fd3a388f048"
- integrity sha512-xlx1yCK2Oc1APsPXDL2LdlNP6+uu8OCDdhOBSVT279M/S+y75O30C2VuD8T2ogdePBBl7PfPF4504tnLgX3zfw==
-
-caniuse-api@^3.0.0:
- version "3.0.0"
- resolved "https://registry.yarnpkg.com/caniuse-api/-/caniuse-api-3.0.0.tgz#5e4d90e2274961d46291997df599e3ed008ee4c0"
- integrity sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==
- dependencies:
- browserslist "^4.0.0"
- caniuse-lite "^1.0.0"
- lodash.memoize "^4.1.2"
- lodash.uniq "^4.5.0"
-
-caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001646, caniuse-lite@^1.0.30001663:
- version "1.0.30001669"
- resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001669.tgz#fda8f1d29a8bfdc42de0c170d7f34a9cf19ed7a3"
- integrity sha512-DlWzFDJqstqtIVx1zeSpIMLjunf5SmwOw0N2Ck/QSQdS8PLS4+9HrLaYei4w8BIAL7IB/UEDu889d8vhCTPA0w==
-
-chalk-template@0.4.0:
- version "0.4.0"
- resolved "https://registry.yarnpkg.com/chalk-template/-/chalk-template-0.4.0.tgz#692c034d0ed62436b9062c1707fadcd0f753204b"
- integrity sha512-/ghrgmhfY8RaSdeo43hNXxpoHAtxdbskUHjPpfqUWGttFgycUhYPGx3YZBCnUCvOa7Doivn1IZec3DEGFoMgLg==
- dependencies:
- chalk "^4.1.2"
-
-chalk@5.0.1:
- version "5.0.1"
- resolved "https://registry.yarnpkg.com/chalk/-/chalk-5.0.1.tgz#ca57d71e82bb534a296df63bbacc4a1c22b2a4b6"
- integrity sha512-Fo07WOYGqMfCWHOzSXOt2CxDbC6skS/jO9ynEcmpANMoPrD+W1r1K6Vx7iNm+AQmETU1Xr2t+n8nzkV9t6xh3w==
-
-chalk@^2.4.2:
- version "2.4.2"
- resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424"
- integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==
- dependencies:
- ansi-styles "^3.2.1"
- escape-string-regexp "^1.0.5"
- supports-color "^5.3.0"
-
-chalk@^4.0.0, chalk@^4.1.0, chalk@^4.1.2:
- version "4.1.2"
- resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01"
- integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==
- dependencies:
- ansi-styles "^4.1.0"
- supports-color "^7.1.0"
-
-chalk@^5.0.1:
- version "5.3.0"
- resolved "https://registry.yarnpkg.com/chalk/-/chalk-5.3.0.tgz#67c20a7ebef70e7f3970a01f90fa210cb6860385"
- integrity sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==
-
-char-regex@^1.0.2:
- version "1.0.2"
- resolved "https://registry.yarnpkg.com/char-regex/-/char-regex-1.0.2.tgz#d744358226217f981ed58f479b1d6bcc29545dcf"
- integrity sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==
-
-chokidar@^4.0.0:
- version "4.0.1"
- resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-4.0.1.tgz#4a6dff66798fb0f72a94f616abbd7e1a19f31d41"
- integrity sha512-n8enUVCED/KVRQlab1hr3MVpcVMvxtZjmEa956u+4YijlmQED223XMSYj2tLuKvr4jcCTzNNMpQDUer72MMmzA==
- dependencies:
- readdirp "^4.0.1"
-
-ci-info@^3.2.0:
- version "3.9.0"
- resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.9.0.tgz#4279a62028a7b1f262f3473fc9605f5e218c59b4"
- integrity sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==
-
-cjs-module-lexer@^1.0.0:
- version "1.4.1"
- resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-1.4.1.tgz#707413784dbb3a72aa11c2f2b042a0bef4004170"
- integrity sha512-cuSVIHi9/9E/+821Qjdvngor+xpnlwnuwIyZOaLmHBVdXL+gP+I6QQB9VkO7RI77YIcTV+S1W9AreJ5eN63JBA==
-
-cli-boxes@^3.0.0:
- version "3.0.0"
- resolved "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-3.0.0.tgz#71a10c716feeba005e4504f36329ef0b17cf3145"
- integrity sha512-/lzGpEWL/8PfI0BmBOPRwp0c/wFNX1RdUML3jK/RcSBA9T8mZDdQpqYBKtCFTOfQbwPqWEOpjqW+Fnayc0969g==
-
-clipboardy@3.0.0:
- version "3.0.0"
- resolved "https://registry.yarnpkg.com/clipboardy/-/clipboardy-3.0.0.tgz#f3876247404d334c9ed01b6f269c11d09a5e3092"
- integrity sha512-Su+uU5sr1jkUy1sGRpLKjKrvEOVXgSgiSInwa/qeID6aJ07yh+5NWc3h2QfjHjBnfX4LhtFcuAWKUsJ3r+fjbg==
- dependencies:
- arch "^2.2.0"
- execa "^5.1.1"
- is-wsl "^2.2.0"
-
-cliui@^8.0.1:
- version "8.0.1"
- resolved "https://registry.yarnpkg.com/cliui/-/cliui-8.0.1.tgz#0c04b075db02cbfe60dc8e6cf2f5486b1a3608aa"
- integrity sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==
- dependencies:
- string-width "^4.2.0"
- strip-ansi "^6.0.1"
- wrap-ansi "^7.0.0"
-
-co@^4.6.0:
- version "4.6.0"
- resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184"
- integrity sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==
-
-collect-v8-coverage@^1.0.0:
- version "1.0.2"
- resolved "https://registry.yarnpkg.com/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz#c0b29bcd33bcd0779a1344c2136051e6afd3d9e9"
- integrity sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==
-
-color-convert@^1.9.0:
- version "1.9.3"
- resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8"
- integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==
- dependencies:
- color-name "1.1.3"
-
-color-convert@^2.0.1:
- version "2.0.1"
- resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3"
- integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==
- dependencies:
- color-name "~1.1.4"
-
-color-name@1.1.3:
- version "1.1.3"
- resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25"
- integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==
-
-color-name@~1.1.4:
- version "1.1.4"
- resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2"
- integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==
-
-colord@^2.9.1:
- version "2.9.3"
- resolved "https://registry.yarnpkg.com/colord/-/colord-2.9.3.tgz#4f8ce919de456f1d5c1c368c307fe20f3e59fb43"
- integrity sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==
-
-commander@^2.20.0:
- version "2.20.3"
- resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33"
- integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==
-
-commander@^7.2.0:
- version "7.2.0"
- resolved "https://registry.yarnpkg.com/commander/-/commander-7.2.0.tgz#a36cb57d0b501ce108e4d20559a150a391d97ab7"
- integrity sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==
-
-comment-parser@1.4.1, comment-parser@^1.4.0:
- version "1.4.1"
- resolved "https://registry.yarnpkg.com/comment-parser/-/comment-parser-1.4.1.tgz#bdafead37961ac079be11eb7ec65c4d021eaf9cc"
- integrity sha512-buhp5kePrmda3vhc5B9t7pUQXAb2Tnd0qgpkIhPhkHXxJpiPJ11H0ZEU0oBpJ2QztSbzG/ZxMj/CHsYJqRHmyg==
-
-compressible@~2.0.16:
- version "2.0.18"
- resolved "https://registry.yarnpkg.com/compressible/-/compressible-2.0.18.tgz#af53cca6b070d4c3c0750fbd77286a6d7cc46fba"
- integrity sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==
- dependencies:
- mime-db ">= 1.43.0 < 2"
-
-compression@1.7.4:
- version "1.7.4"
- resolved "https://registry.yarnpkg.com/compression/-/compression-1.7.4.tgz#95523eff170ca57c29a0ca41e6fe131f41e5bb8f"
- integrity sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==
- dependencies:
- accepts "~1.3.5"
- bytes "3.0.0"
- compressible "~2.0.16"
- debug "2.6.9"
- on-headers "~1.0.2"
- safe-buffer "5.1.2"
- vary "~1.1.2"
-
-concat-map@0.0.1:
- version "0.0.1"
- resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
- integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==
-
-concat-with-sourcemaps@^1.1.0:
- version "1.1.0"
- resolved "https://registry.yarnpkg.com/concat-with-sourcemaps/-/concat-with-sourcemaps-1.1.0.tgz#d4ea93f05ae25790951b99e7b3b09e3908a4082e"
- integrity sha512-4gEjHJFT9e+2W/77h/DS5SGUgwDaOwprX8L/gl5+3ixnzkVJJsZWDSelmN3Oilw3LNDZjZV0yqH1hLG3k6nghg==
- dependencies:
- source-map "^0.6.1"
-
-concurrently@^9.0.1:
- version "9.0.1"
- resolved "https://registry.yarnpkg.com/concurrently/-/concurrently-9.0.1.tgz#01e171bf6c7af0c022eb85daef95bff04d8185aa"
- integrity sha512-wYKvCd/f54sTXJMSfV6Ln/B8UrfLBKOYa+lzc6CHay3Qek+LorVSBdMVfyewFhRbH0Rbabsk4D+3PL/VjQ5gzg==
- dependencies:
- chalk "^4.1.2"
- lodash "^4.17.21"
- rxjs "^7.8.1"
- shell-quote "^1.8.1"
- supports-color "^8.1.1"
- tree-kill "^1.2.2"
- yargs "^17.7.2"
-
-content-disposition@0.5.2:
- version "0.5.2"
- resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.2.tgz#0cf68bb9ddf5f2be7961c3a85178cb85dba78cb4"
- integrity sha512-kRGRZw3bLlFISDBgwTSA1TMBFN6J6GWDeubmDE3AF+3+yXL8hTWv8r5rkLbqYXY4RjPk/EzHnClI3zQf1cFmHA==
-
-convert-source-map@^2.0.0:
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-2.0.0.tgz#4b560f649fc4e918dd0ab75cf4961e8bc882d82a"
- integrity sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==
-
-cors@^2.8.5:
- version "2.8.5"
- resolved "https://registry.yarnpkg.com/cors/-/cors-2.8.5.tgz#eac11da51592dd86b9f06f6e7ac293b3df875d29"
- integrity sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==
- dependencies:
- object-assign "^4"
- vary "^1"
-
-create-jest@^29.7.0:
- version "29.7.0"
- resolved "https://registry.yarnpkg.com/create-jest/-/create-jest-29.7.0.tgz#a355c5b3cb1e1af02ba177fe7afd7feee49a5320"
- integrity sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q==
- dependencies:
- "@jest/types" "^29.6.3"
- chalk "^4.0.0"
- exit "^0.1.2"
- graceful-fs "^4.2.9"
- jest-config "^29.7.0"
- jest-util "^29.7.0"
- prompts "^2.0.1"
-
-cross-env@^7.0.3:
- version "7.0.3"
- resolved "https://registry.yarnpkg.com/cross-env/-/cross-env-7.0.3.tgz#865264b29677dc015ba8418918965dd232fc54cf"
- integrity sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==
- dependencies:
- cross-spawn "^7.0.1"
-
-cross-spawn@^7.0.1, cross-spawn@^7.0.2, cross-spawn@^7.0.3:
- version "7.0.3"
- resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6"
- integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==
- dependencies:
- path-key "^3.1.0"
- shebang-command "^2.0.0"
- which "^2.0.1"
-
-css-declaration-sorter@^6.3.1:
- version "6.4.1"
- resolved "https://registry.yarnpkg.com/css-declaration-sorter/-/css-declaration-sorter-6.4.1.tgz#28beac7c20bad7f1775be3a7129d7eae409a3a71"
- integrity sha512-rtdthzxKuyq6IzqX6jEcIzQF/YqccluefyCYheovBOLhFT/drQA9zj/UbRAa9J7C0o6EG6u3E6g+vKkay7/k3g==
-
-css-select@^4.1.3:
- version "4.3.0"
- resolved "https://registry.yarnpkg.com/css-select/-/css-select-4.3.0.tgz#db7129b2846662fd8628cfc496abb2b59e41529b"
- integrity sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==
- dependencies:
- boolbase "^1.0.0"
- css-what "^6.0.1"
- domhandler "^4.3.1"
- domutils "^2.8.0"
- nth-check "^2.0.1"
-
-css-tree@^1.1.2, css-tree@^1.1.3:
- version "1.1.3"
- resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-1.1.3.tgz#eb4870fb6fd7707327ec95c2ff2ab09b5e8db91d"
- integrity sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==
- dependencies:
- mdn-data "2.0.14"
- source-map "^0.6.1"
-
-css-what@^6.0.1:
- version "6.1.0"
- resolved "https://registry.yarnpkg.com/css-what/-/css-what-6.1.0.tgz#fb5effcf76f1ddea2c81bdfaa4de44e79bac70f4"
- integrity sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==
-
-cssesc@^3.0.0:
- version "3.0.0"
- resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee"
- integrity sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==
-
-cssnano-preset-default@^5.2.14:
- version "5.2.14"
- resolved "https://registry.yarnpkg.com/cssnano-preset-default/-/cssnano-preset-default-5.2.14.tgz#309def4f7b7e16d71ab2438052093330d9ab45d8"
- integrity sha512-t0SFesj/ZV2OTylqQVOrFgEh5uanxbO6ZAdeCrNsUQ6fVuXwYTxJPNAGvGTxHbD68ldIJNec7PyYZDBrfDQ+6A==
- dependencies:
- css-declaration-sorter "^6.3.1"
- cssnano-utils "^3.1.0"
- postcss-calc "^8.2.3"
- postcss-colormin "^5.3.1"
- postcss-convert-values "^5.1.3"
- postcss-discard-comments "^5.1.2"
- postcss-discard-duplicates "^5.1.0"
- postcss-discard-empty "^5.1.1"
- postcss-discard-overridden "^5.1.0"
- postcss-merge-longhand "^5.1.7"
- postcss-merge-rules "^5.1.4"
- postcss-minify-font-values "^5.1.0"
- postcss-minify-gradients "^5.1.1"
- postcss-minify-params "^5.1.4"
- postcss-minify-selectors "^5.2.1"
- postcss-normalize-charset "^5.1.0"
- postcss-normalize-display-values "^5.1.0"
- postcss-normalize-positions "^5.1.1"
- postcss-normalize-repeat-style "^5.1.1"
- postcss-normalize-string "^5.1.0"
- postcss-normalize-timing-functions "^5.1.0"
- postcss-normalize-unicode "^5.1.1"
- postcss-normalize-url "^5.1.0"
- postcss-normalize-whitespace "^5.1.1"
- postcss-ordered-values "^5.1.3"
- postcss-reduce-initial "^5.1.2"
- postcss-reduce-transforms "^5.1.0"
- postcss-svgo "^5.1.0"
- postcss-unique-selectors "^5.1.1"
-
-cssnano-utils@^3.1.0:
- version "3.1.0"
- resolved "https://registry.yarnpkg.com/cssnano-utils/-/cssnano-utils-3.1.0.tgz#95684d08c91511edfc70d2636338ca37ef3a6861"
- integrity sha512-JQNR19/YZhz4psLX/rQ9M83e3z2Wf/HdJbryzte4a3NSuafyp9w/I4U+hx5C2S9g41qlstH7DEWnZaaj83OuEA==
-
-cssnano@^5.0.1:
- version "5.1.15"
- resolved "https://registry.yarnpkg.com/cssnano/-/cssnano-5.1.15.tgz#ded66b5480d5127fcb44dac12ea5a983755136bf"
- integrity sha512-j+BKgDcLDQA+eDifLx0EO4XSA56b7uut3BQFH+wbSaSTuGLuiyTa/wbRYthUXX8LC9mLg+WWKe8h+qJuwTAbHw==
- dependencies:
- cssnano-preset-default "^5.2.14"
- lilconfig "^2.0.3"
- yaml "^1.10.2"
-
-csso@^4.2.0:
- version "4.2.0"
- resolved "https://registry.yarnpkg.com/csso/-/csso-4.2.0.tgz#ea3a561346e8dc9f546d6febedd50187cf389529"
- integrity sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA==
- dependencies:
- css-tree "^1.1.2"
-
-data-view-buffer@^1.0.1:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/data-view-buffer/-/data-view-buffer-1.0.1.tgz#8ea6326efec17a2e42620696e671d7d5a8bc66b2"
- integrity sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==
- dependencies:
- call-bind "^1.0.6"
- es-errors "^1.3.0"
- is-data-view "^1.0.1"
-
-data-view-byte-length@^1.0.1:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/data-view-byte-length/-/data-view-byte-length-1.0.1.tgz#90721ca95ff280677eb793749fce1011347669e2"
- integrity sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==
- dependencies:
- call-bind "^1.0.7"
- es-errors "^1.3.0"
- is-data-view "^1.0.1"
-
-data-view-byte-offset@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/data-view-byte-offset/-/data-view-byte-offset-1.0.0.tgz#5e0bbfb4828ed2d1b9b400cd8a7d119bca0ff18a"
- integrity sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==
- dependencies:
- call-bind "^1.0.6"
- es-errors "^1.3.0"
- is-data-view "^1.0.1"
-
-debug@2.6.9:
- version "2.6.9"
- resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f"
- integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==
- dependencies:
- ms "2.0.0"
-
-debug@^3.2.7:
- version "3.2.7"
- resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a"
- integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==
- dependencies:
- ms "^2.1.1"
-
-debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.4:
- version "4.3.7"
- resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.7.tgz#87945b4151a011d76d95a198d7111c865c360a52"
- integrity sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==
- dependencies:
- ms "^2.1.3"
-
-dedent@^1.0.0:
- version "1.5.3"
- resolved "https://registry.yarnpkg.com/dedent/-/dedent-1.5.3.tgz#99aee19eb9bae55a67327717b6e848d0bf777e5a"
- integrity sha512-NHQtfOOW68WD8lgypbLA5oT+Bt0xXJhiYvoR6SmmNXZfpzOGXwdKWmcwG8N7PwVVWV3eF/68nmD9BaJSsTBhyQ==
-
-deep-extend@^0.6.0:
- version "0.6.0"
- resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac"
- integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==
-
-deep-is@^0.1.3:
- version "0.1.4"
- resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831"
- integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==
-
-deepmerge@^4.2.2:
- version "4.3.1"
- resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.3.1.tgz#44b5f2147cd3b00d4b56137685966f26fd25dd4a"
- integrity sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==
-
-define-data-property@^1.0.1, define-data-property@^1.1.4:
- version "1.1.4"
- resolved "https://registry.yarnpkg.com/define-data-property/-/define-data-property-1.1.4.tgz#894dc141bb7d3060ae4366f6a0107e68fbe48c5e"
- integrity sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==
- dependencies:
- es-define-property "^1.0.0"
- es-errors "^1.3.0"
- gopd "^1.0.1"
-
-define-lazy-prop@^2.0.0:
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz#3f7ae421129bcaaac9bc74905c98a0009ec9ee7f"
- integrity sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==
-
-define-properties@^1.2.0, define-properties@^1.2.1:
- version "1.2.1"
- resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.2.1.tgz#10781cc616eb951a80a034bafcaa7377f6af2b6c"
- integrity sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==
- dependencies:
- define-data-property "^1.0.1"
- has-property-descriptors "^1.0.0"
- object-keys "^1.1.1"
-
-detect-libc@^1.0.3:
- version "1.0.3"
- resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b"
- integrity sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==
-
-detect-newline@^3.0.0:
- version "3.1.0"
- resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-3.1.0.tgz#576f5dfc63ae1a192ff192d8ad3af6308991b651"
- integrity sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==
-
-diff-sequences@^29.6.3:
- version "29.6.3"
- resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-29.6.3.tgz#4deaf894d11407c51efc8418012f9e70b84ea921"
- integrity sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==
-
-dir-glob@^3.0.1:
- version "3.0.1"
- resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f"
- integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==
- dependencies:
- path-type "^4.0.0"
-
-doctrine@^2.1.0:
- version "2.1.0"
- resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.1.0.tgz#5cd01fc101621b42c4cd7f5d1a66243716d3f39d"
- integrity sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==
- dependencies:
- esutils "^2.0.2"
-
-doctrine@^3.0.0:
- version "3.0.0"
- resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961"
- integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==
- dependencies:
- esutils "^2.0.2"
-
-dom-serializer@^1.0.1:
- version "1.4.1"
- resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-1.4.1.tgz#de5d41b1aea290215dc45a6dae8adcf1d32e2d30"
- integrity sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==
- dependencies:
- domelementtype "^2.0.1"
- domhandler "^4.2.0"
- entities "^2.0.0"
-
-domelementtype@^2.0.1, domelementtype@^2.2.0:
- version "2.3.0"
- resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.3.0.tgz#5c45e8e869952626331d7aab326d01daf65d589d"
- integrity sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==
-
-domhandler@^4.2.0, domhandler@^4.3.1:
- version "4.3.1"
- resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-4.3.1.tgz#8d792033416f59d68bc03a5aa7b018c1ca89279c"
- integrity sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==
- dependencies:
- domelementtype "^2.2.0"
-
-domutils@^2.8.0:
- version "2.8.0"
- resolved "https://registry.yarnpkg.com/domutils/-/domutils-2.8.0.tgz#4437def5db6e2d1f5d6ee859bd95ca7d02048135"
- integrity sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==
- dependencies:
- dom-serializer "^1.0.1"
- domelementtype "^2.2.0"
- domhandler "^4.2.0"
-
-eastasianwidth@^0.2.0:
- version "0.2.0"
- resolved "https://registry.yarnpkg.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz#696ce2ec0aa0e6ea93a397ffcf24aa7840c827cb"
- integrity sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==
-
-electron-to-chromium@^1.5.28:
- version "1.5.41"
- resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.41.tgz#eae1ba6c49a1a61d84cf8263351d3513b2bcc534"
- integrity sha512-dfdv/2xNjX0P8Vzme4cfzHqnPm5xsZXwsolTYr0eyW18IUmNyG08vL+fttvinTfhKfIKdRoqkDIC9e9iWQCNYQ==
-
-emittery@^0.13.1:
- version "0.13.1"
- resolved "https://registry.yarnpkg.com/emittery/-/emittery-0.13.1.tgz#c04b8c3457490e0847ae51fced3af52d338e3dad"
- integrity sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==
-
-emoji-regex@^8.0.0:
- version "8.0.0"
- resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37"
- integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==
-
-emoji-regex@^9.2.2:
- version "9.2.2"
- resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-9.2.2.tgz#840c8803b0d8047f4ff0cf963176b32d4ef3ed72"
- integrity sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==
-
-entities@^2.0.0:
- version "2.2.0"
- resolved "https://registry.yarnpkg.com/entities/-/entities-2.2.0.tgz#098dc90ebb83d8dffa089d55256b351d34c4da55"
- integrity sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==
-
-error-ex@^1.3.1:
- version "1.3.2"
- resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf"
- integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==
- dependencies:
- is-arrayish "^0.2.1"
-
-es-abstract@^1.22.1, es-abstract@^1.22.3, es-abstract@^1.23.0, es-abstract@^1.23.2:
- version "1.23.3"
- resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.23.3.tgz#8f0c5a35cd215312573c5a27c87dfd6c881a0aa0"
- integrity sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==
- dependencies:
- array-buffer-byte-length "^1.0.1"
- arraybuffer.prototype.slice "^1.0.3"
- available-typed-arrays "^1.0.7"
- call-bind "^1.0.7"
- data-view-buffer "^1.0.1"
- data-view-byte-length "^1.0.1"
- data-view-byte-offset "^1.0.0"
- es-define-property "^1.0.0"
- es-errors "^1.3.0"
- es-object-atoms "^1.0.0"
- es-set-tostringtag "^2.0.3"
- es-to-primitive "^1.2.1"
- function.prototype.name "^1.1.6"
- get-intrinsic "^1.2.4"
- get-symbol-description "^1.0.2"
- globalthis "^1.0.3"
- gopd "^1.0.1"
- has-property-descriptors "^1.0.2"
- has-proto "^1.0.3"
- has-symbols "^1.0.3"
- hasown "^2.0.2"
- internal-slot "^1.0.7"
- is-array-buffer "^3.0.4"
- is-callable "^1.2.7"
- is-data-view "^1.0.1"
- is-negative-zero "^2.0.3"
- is-regex "^1.1.4"
- is-shared-array-buffer "^1.0.3"
- is-string "^1.0.7"
- is-typed-array "^1.1.13"
- is-weakref "^1.0.2"
- object-inspect "^1.13.1"
- object-keys "^1.1.1"
- object.assign "^4.1.5"
- regexp.prototype.flags "^1.5.2"
- safe-array-concat "^1.1.2"
- safe-regex-test "^1.0.3"
- string.prototype.trim "^1.2.9"
- string.prototype.trimend "^1.0.8"
- string.prototype.trimstart "^1.0.8"
- typed-array-buffer "^1.0.2"
- typed-array-byte-length "^1.0.1"
- typed-array-byte-offset "^1.0.2"
- typed-array-length "^1.0.6"
- unbox-primitive "^1.0.2"
- which-typed-array "^1.1.15"
-
-es-define-property@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/es-define-property/-/es-define-property-1.0.0.tgz#c7faefbdff8b2696cf5f46921edfb77cc4ba3845"
- integrity sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==
- dependencies:
- get-intrinsic "^1.2.4"
-
-es-errors@^1.2.1, es-errors@^1.3.0:
- version "1.3.0"
- resolved "https://registry.yarnpkg.com/es-errors/-/es-errors-1.3.0.tgz#05f75a25dab98e4fb1dcd5e1472c0546d5057c8f"
- integrity sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==
-
-es-object-atoms@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/es-object-atoms/-/es-object-atoms-1.0.0.tgz#ddb55cd47ac2e240701260bc2a8e31ecb643d941"
- integrity sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==
- dependencies:
- es-errors "^1.3.0"
-
-es-set-tostringtag@^2.0.3:
- version "2.0.3"
- resolved "https://registry.yarnpkg.com/es-set-tostringtag/-/es-set-tostringtag-2.0.3.tgz#8bb60f0a440c2e4281962428438d58545af39777"
- integrity sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==
- dependencies:
- get-intrinsic "^1.2.4"
- has-tostringtag "^1.0.2"
- hasown "^2.0.1"
-
-es-shim-unscopables@^1.0.0, es-shim-unscopables@^1.0.2:
- version "1.0.2"
- resolved "https://registry.yarnpkg.com/es-shim-unscopables/-/es-shim-unscopables-1.0.2.tgz#1f6942e71ecc7835ed1c8a83006d8771a63a3763"
- integrity sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==
- dependencies:
- hasown "^2.0.0"
-
-es-to-primitive@^1.2.1:
- version "1.2.1"
- resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.1.tgz#e55cd4c9cdc188bcefb03b366c736323fc5c898a"
- integrity sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==
- dependencies:
- is-callable "^1.1.4"
- is-date-object "^1.0.1"
- is-symbol "^1.0.2"
-
-escalade@^3.1.1, escalade@^3.2.0:
- version "3.2.0"
- resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.2.0.tgz#011a3f69856ba189dffa7dc8fcce99d2a87903e5"
- integrity sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==
-
-escape-string-regexp@^1.0.5:
- version "1.0.5"
- resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4"
- integrity sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==
-
-escape-string-regexp@^2.0.0:
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz#a30304e99daa32e23b2fd20f51babd07cffca344"
- integrity sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==
-
-escape-string-regexp@^4.0.0:
- version "4.0.0"
- resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34"
- integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==
-
-eslint-import-resolver-node@^0.3.9:
- version "0.3.9"
- resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz#d4eaac52b8a2e7c3cd1903eb00f7e053356118ac"
- integrity sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==
- dependencies:
- debug "^3.2.7"
- is-core-module "^2.13.0"
- resolve "^1.22.4"
-
-eslint-module-utils@^2.12.0:
- version "2.12.0"
- resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.12.0.tgz#fe4cfb948d61f49203d7b08871982b65b9af0b0b"
- integrity sha512-wALZ0HFoytlyh/1+4wuZ9FJCD/leWHQzzrxJ8+rebyReSLk7LApMyd3WJaLVoN+D5+WIdJyDK1c6JnE65V4Zyg==
- dependencies:
- debug "^3.2.7"
-
-eslint-plugin-import@^2.28.0:
- version "2.31.0"
- resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.31.0.tgz#310ce7e720ca1d9c0bb3f69adfd1c6bdd7d9e0e7"
- integrity sha512-ixmkI62Rbc2/w8Vfxyh1jQRTdRTF52VxwRVHl/ykPAmqG+Nb7/kNn+byLP0LxPgI7zWA16Jt82SybJInmMia3A==
- dependencies:
- "@rtsao/scc" "^1.1.0"
- array-includes "^3.1.8"
- array.prototype.findlastindex "^1.2.5"
- array.prototype.flat "^1.3.2"
- array.prototype.flatmap "^1.3.2"
- debug "^3.2.7"
- doctrine "^2.1.0"
- eslint-import-resolver-node "^0.3.9"
- eslint-module-utils "^2.12.0"
- hasown "^2.0.2"
- is-core-module "^2.15.1"
- is-glob "^4.0.3"
- minimatch "^3.1.2"
- object.fromentries "^2.0.8"
- object.groupby "^1.0.3"
- object.values "^1.2.0"
- semver "^6.3.1"
- string.prototype.trimend "^1.0.8"
- tsconfig-paths "^3.15.0"
-
-eslint-plugin-jsdoc@^46.4.6:
- version "46.10.1"
- resolved "https://registry.yarnpkg.com/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-46.10.1.tgz#77c871309c4ed93758a3b2fdf384dc6189cf8605"
- integrity sha512-x8wxIpv00Y50NyweDUpa+58ffgSAI5sqe+zcZh33xphD0AVh+1kqr1ombaTRb7Fhpove1zfUuujlX9DWWBP5ag==
- dependencies:
- "@es-joy/jsdoccomment" "~0.41.0"
- are-docs-informative "^0.0.2"
- comment-parser "1.4.1"
- debug "^4.3.4"
- escape-string-regexp "^4.0.0"
- esquery "^1.5.0"
- is-builtin-module "^3.2.1"
- semver "^7.5.4"
- spdx-expression-parse "^4.0.0"
-
-eslint-plugin-regexp@^2.6.0:
- version "2.6.0"
- resolved "https://registry.yarnpkg.com/eslint-plugin-regexp/-/eslint-plugin-regexp-2.6.0.tgz#54b9ca535662ca2c59ca211b7723ef22e2b6681b"
- integrity sha512-FCL851+kislsTEQEMioAlpDuK5+E5vs0hi1bF8cFlPlHcEjeRhuAzEsGikXRreE+0j4WhW2uO54MqTjXtYOi3A==
- dependencies:
- "@eslint-community/eslint-utils" "^4.2.0"
- "@eslint-community/regexpp" "^4.9.1"
- comment-parser "^1.4.0"
- jsdoc-type-pratt-parser "^4.0.0"
- refa "^0.12.1"
- regexp-ast-analysis "^0.7.1"
- scslre "^0.3.0"
-
-eslint-scope@^7.2.2:
- version "7.2.2"
- resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-7.2.2.tgz#deb4f92563390f32006894af62a22dba1c46423f"
- integrity sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==
- dependencies:
- esrecurse "^4.3.0"
- estraverse "^5.2.0"
-
-eslint-visitor-keys@^3.3.0, eslint-visitor-keys@^3.4.1, eslint-visitor-keys@^3.4.3:
- version "3.4.3"
- resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz#0cd72fe8550e3c2eae156a96a4dddcd1c8ac5800"
- integrity sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==
-
-eslint@^8.56.0:
- version "8.57.1"
- resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.57.1.tgz#7df109654aba7e3bbe5c8eae533c5e461d3c6ca9"
- integrity sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==
- dependencies:
- "@eslint-community/eslint-utils" "^4.2.0"
- "@eslint-community/regexpp" "^4.6.1"
- "@eslint/eslintrc" "^2.1.4"
- "@eslint/js" "8.57.1"
- "@humanwhocodes/config-array" "^0.13.0"
- "@humanwhocodes/module-importer" "^1.0.1"
- "@nodelib/fs.walk" "^1.2.8"
- "@ungap/structured-clone" "^1.2.0"
- ajv "^6.12.4"
- chalk "^4.0.0"
- cross-spawn "^7.0.2"
- debug "^4.3.2"
- doctrine "^3.0.0"
- escape-string-regexp "^4.0.0"
- eslint-scope "^7.2.2"
- eslint-visitor-keys "^3.4.3"
- espree "^9.6.1"
- esquery "^1.4.2"
- esutils "^2.0.2"
- fast-deep-equal "^3.1.3"
- file-entry-cache "^6.0.1"
- find-up "^5.0.0"
- glob-parent "^6.0.2"
- globals "^13.19.0"
- graphemer "^1.4.0"
- ignore "^5.2.0"
- imurmurhash "^0.1.4"
- is-glob "^4.0.0"
- is-path-inside "^3.0.3"
- js-yaml "^4.1.0"
- json-stable-stringify-without-jsonify "^1.0.1"
- levn "^0.4.1"
- lodash.merge "^4.6.2"
- minimatch "^3.1.2"
- natural-compare "^1.4.0"
- optionator "^0.9.3"
- strip-ansi "^6.0.1"
- text-table "^0.2.0"
-
-espree@^9.6.0, espree@^9.6.1:
- version "9.6.1"
- resolved "https://registry.yarnpkg.com/espree/-/espree-9.6.1.tgz#a2a17b8e434690a5432f2f8018ce71d331a48c6f"
- integrity sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==
- dependencies:
- acorn "^8.9.0"
- acorn-jsx "^5.3.2"
- eslint-visitor-keys "^3.4.1"
-
-esprima@^4.0.0:
- version "4.0.1"
- resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71"
- integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==
-
-esquery@^1.4.2, esquery@^1.5.0:
- version "1.6.0"
- resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.6.0.tgz#91419234f804d852a82dceec3e16cdc22cf9dae7"
- integrity sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==
- dependencies:
- estraverse "^5.1.0"
-
-esrecurse@^4.3.0:
- version "4.3.0"
- resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921"
- integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==
- dependencies:
- estraverse "^5.2.0"
-
-estraverse@^5.1.0, estraverse@^5.2.0:
- version "5.3.0"
- resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123"
- integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==
-
-estree-walker@^0.6.1:
- version "0.6.1"
- resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-0.6.1.tgz#53049143f40c6eb918b23671d1fe3219f3a1b362"
- integrity sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w==
-
-estree-walker@^2.0.2:
- version "2.0.2"
- resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-2.0.2.tgz#52f010178c2a4c117a7757cfe942adb7d2da4cac"
- integrity sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==
-
-esutils@^2.0.2:
- version "2.0.3"
- resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64"
- integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==
-
-eventemitter3@^4.0.4:
- version "4.0.7"
- resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f"
- integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==
-
-execa@^5.0.0, execa@^5.1.1:
- version "5.1.1"
- resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd"
- integrity sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==
- dependencies:
- cross-spawn "^7.0.3"
- get-stream "^6.0.0"
- human-signals "^2.1.0"
- is-stream "^2.0.0"
- merge-stream "^2.0.0"
- npm-run-path "^4.0.1"
- onetime "^5.1.2"
- signal-exit "^3.0.3"
- strip-final-newline "^2.0.0"
-
-exit@^0.1.2:
- version "0.1.2"
- resolved "https://registry.yarnpkg.com/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c"
- integrity sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==
-
-expect@^29.7.0:
- version "29.7.0"
- resolved "https://registry.yarnpkg.com/expect/-/expect-29.7.0.tgz#578874590dcb3214514084c08115d8aee61e11bc"
- integrity sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==
- dependencies:
- "@jest/expect-utils" "^29.7.0"
- jest-get-type "^29.6.3"
- jest-matcher-utils "^29.7.0"
- jest-message-util "^29.7.0"
- jest-util "^29.7.0"
-
-fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3:
- version "3.1.3"
- resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525"
- integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==
-
-fast-glob@^3.2.9:
- version "3.3.2"
- resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.3.2.tgz#a904501e57cfdd2ffcded45e99a54fef55e46129"
- integrity sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==
- dependencies:
- "@nodelib/fs.stat" "^2.0.2"
- "@nodelib/fs.walk" "^1.2.3"
- glob-parent "^5.1.2"
- merge2 "^1.3.0"
- micromatch "^4.0.4"
-
-fast-json-stable-stringify@^2.0.0, fast-json-stable-stringify@^2.1.0:
- version "2.1.0"
- resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633"
- integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==
-
-fast-levenshtein@^2.0.6:
- version "2.0.6"
- resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917"
- integrity sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==
-
-fastq@^1.6.0:
- version "1.17.1"
- resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.17.1.tgz#2a523f07a4e7b1e81a42b91b8bf2254107753b47"
- integrity sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==
- dependencies:
- reusify "^1.0.4"
-
-fb-watchman@^2.0.0:
- version "2.0.2"
- resolved "https://registry.yarnpkg.com/fb-watchman/-/fb-watchman-2.0.2.tgz#e9524ee6b5c77e9e5001af0f85f3adbb8623255c"
- integrity sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==
- dependencies:
- bser "2.1.1"
-
-file-entry-cache@^6.0.1:
- version "6.0.1"
- resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-6.0.1.tgz#211b2dd9659cb0394b073e7323ac3c933d522027"
- integrity sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==
- dependencies:
- flat-cache "^3.0.4"
-
-fill-range@^7.1.1:
- version "7.1.1"
- resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.1.1.tgz#44265d3cac07e3ea7dc247516380643754a05292"
- integrity sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==
- dependencies:
- to-regex-range "^5.0.1"
-
-find-up@^4.0.0, find-up@^4.1.0:
- version "4.1.0"
- resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19"
- integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==
- dependencies:
- locate-path "^5.0.0"
- path-exists "^4.0.0"
-
-find-up@^5.0.0:
- version "5.0.0"
- resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc"
- integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==
- dependencies:
- locate-path "^6.0.0"
- path-exists "^4.0.0"
-
-flat-cache@^3.0.4:
- version "3.2.0"
- resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-3.2.0.tgz#2c0c2d5040c99b1632771a9d105725c0115363ee"
- integrity sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==
- dependencies:
- flatted "^3.2.9"
- keyv "^4.5.3"
- rimraf "^3.0.2"
-
-flatted@^3.2.9:
- version "3.3.1"
- resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.3.1.tgz#21db470729a6734d4997002f439cb308987f567a"
- integrity sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==
-
-for-each@^0.3.3:
- version "0.3.3"
- resolved "https://registry.yarnpkg.com/for-each/-/for-each-0.3.3.tgz#69b447e88a0a5d32c3e7084f3f1710034b21376e"
- integrity sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==
- dependencies:
- is-callable "^1.1.3"
-
-fraction.js@^4.3.7:
- version "4.3.7"
- resolved "https://registry.yarnpkg.com/fraction.js/-/fraction.js-4.3.7.tgz#06ca0085157e42fda7f9e726e79fefc4068840f7"
- integrity sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==
-
-fs.realpath@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f"
- integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==
-
-fsevents@^2.3.2, fsevents@~2.3.2:
- version "2.3.3"
- resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6"
- integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==
-
-function-bind@^1.1.2:
- version "1.1.2"
- resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.2.tgz#2c02d864d97f3ea6c8830c464cbd11ab6eab7a1c"
- integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==
-
-function.prototype.name@^1.1.6:
- version "1.1.6"
- resolved "https://registry.yarnpkg.com/function.prototype.name/-/function.prototype.name-1.1.6.tgz#cdf315b7d90ee77a4c6ee216c3c3362da07533fd"
- integrity sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==
- dependencies:
- call-bind "^1.0.2"
- define-properties "^1.2.0"
- es-abstract "^1.22.1"
- functions-have-names "^1.2.3"
-
-functions-have-names@^1.2.3:
- version "1.2.3"
- resolved "https://registry.yarnpkg.com/functions-have-names/-/functions-have-names-1.2.3.tgz#0404fe4ee2ba2f607f0e0ec3c80bae994133b834"
- integrity sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==
-
-generic-names@^4.0.0:
- version "4.0.0"
- resolved "https://registry.yarnpkg.com/generic-names/-/generic-names-4.0.0.tgz#0bd8a2fd23fe8ea16cbd0a279acd69c06933d9a3"
- integrity sha512-ySFolZQfw9FoDb3ed9d80Cm9f0+r7qj+HJkWjeD9RBfpxEVTlVhol+gvaQB/78WbwYfbnNh8nWHHBSlg072y6A==
- dependencies:
- loader-utils "^3.2.0"
-
-gensync@^1.0.0-beta.2:
- version "1.0.0-beta.2"
- resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0"
- integrity sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==
-
-get-caller-file@^2.0.5:
- version "2.0.5"
- resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e"
- integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==
-
-get-intrinsic@^1.1.3, get-intrinsic@^1.2.1, get-intrinsic@^1.2.3, get-intrinsic@^1.2.4:
- version "1.2.4"
- resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.4.tgz#e385f5a4b5227d449c3eabbad05494ef0abbeadd"
- integrity sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==
- dependencies:
- es-errors "^1.3.0"
- function-bind "^1.1.2"
- has-proto "^1.0.1"
- has-symbols "^1.0.3"
- hasown "^2.0.0"
-
-get-package-type@^0.1.0:
- version "0.1.0"
- resolved "https://registry.yarnpkg.com/get-package-type/-/get-package-type-0.1.0.tgz#8de2d803cff44df3bc6c456e6668b36c3926e11a"
- integrity sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==
-
-get-stream@^6.0.0:
- version "6.0.1"
- resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7"
- integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==
-
-get-symbol-description@^1.0.2:
- version "1.0.2"
- resolved "https://registry.yarnpkg.com/get-symbol-description/-/get-symbol-description-1.0.2.tgz#533744d5aa20aca4e079c8e5daf7fd44202821f5"
- integrity sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==
- dependencies:
- call-bind "^1.0.5"
- es-errors "^1.3.0"
- get-intrinsic "^1.2.4"
-
-glob-parent@^5.1.2:
- version "5.1.2"
- resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4"
- integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==
- dependencies:
- is-glob "^4.0.1"
-
-glob-parent@^6.0.2:
- version "6.0.2"
- resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-6.0.2.tgz#6d237d99083950c79290f24c7642a3de9a28f9e3"
- integrity sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==
- dependencies:
- is-glob "^4.0.3"
-
-glob@^7.1.3, glob@^7.1.4:
- version "7.2.3"
- resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b"
- integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==
- dependencies:
- fs.realpath "^1.0.0"
- inflight "^1.0.4"
- inherits "2"
- minimatch "^3.1.1"
- once "^1.3.0"
- path-is-absolute "^1.0.0"
-
-globals@^11.1.0:
- version "11.12.0"
- resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e"
- integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==
-
-globals@^13.19.0:
- version "13.24.0"
- resolved "https://registry.yarnpkg.com/globals/-/globals-13.24.0.tgz#8432a19d78ce0c1e833949c36adb345400bb1171"
- integrity sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==
- dependencies:
- type-fest "^0.20.2"
-
-globalthis@^1.0.3:
- version "1.0.4"
- resolved "https://registry.yarnpkg.com/globalthis/-/globalthis-1.0.4.tgz#7430ed3a975d97bfb59bcce41f5cabbafa651236"
- integrity sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==
- dependencies:
- define-properties "^1.2.1"
- gopd "^1.0.1"
-
-globby@^11.1.0:
- version "11.1.0"
- resolved "https://registry.yarnpkg.com/globby/-/globby-11.1.0.tgz#bd4be98bb042f83d796f7e3811991fbe82a0d34b"
- integrity sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==
- dependencies:
- array-union "^2.1.0"
- dir-glob "^3.0.1"
- fast-glob "^3.2.9"
- ignore "^5.2.0"
- merge2 "^1.4.1"
- slash "^3.0.0"
-
-gopd@^1.0.1:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/gopd/-/gopd-1.0.1.tgz#29ff76de69dac7489b7c0918a5788e56477c332c"
- integrity sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==
- dependencies:
- get-intrinsic "^1.1.3"
-
-graceful-fs@^4.2.9:
- version "4.2.11"
- resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3"
- integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==
-
-graphemer@^1.4.0:
- version "1.4.0"
- resolved "https://registry.yarnpkg.com/graphemer/-/graphemer-1.4.0.tgz#fb2f1d55e0e3a1849aeffc90c4fa0dd53a0e66c6"
- integrity sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==
-
-has-bigints@^1.0.1, has-bigints@^1.0.2:
- version "1.0.2"
- resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.0.2.tgz#0871bd3e3d51626f6ca0966668ba35d5602d6eaa"
- integrity sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==
-
-has-flag@^3.0.0:
- version "3.0.0"
- resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd"
- integrity sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==
-
-has-flag@^4.0.0:
- version "4.0.0"
- resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b"
- integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==
-
-has-property-descriptors@^1.0.0, has-property-descriptors@^1.0.2:
- version "1.0.2"
- resolved "https://registry.yarnpkg.com/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz#963ed7d071dc7bf5f084c5bfbe0d1b6222586854"
- integrity sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==
- dependencies:
- es-define-property "^1.0.0"
-
-has-proto@^1.0.1, has-proto@^1.0.3:
- version "1.0.3"
- resolved "https://registry.yarnpkg.com/has-proto/-/has-proto-1.0.3.tgz#b31ddfe9b0e6e9914536a6ab286426d0214f77fd"
- integrity sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==
-
-has-symbols@^1.0.2, has-symbols@^1.0.3:
- version "1.0.3"
- resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8"
- integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==
-
-has-tostringtag@^1.0.0, has-tostringtag@^1.0.2:
- version "1.0.2"
- resolved "https://registry.yarnpkg.com/has-tostringtag/-/has-tostringtag-1.0.2.tgz#2cdc42d40bef2e5b4eeab7c01a73c54ce7ab5abc"
- integrity sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==
- dependencies:
- has-symbols "^1.0.3"
-
-hasown@^2.0.0, hasown@^2.0.1, hasown@^2.0.2:
- version "2.0.2"
- resolved "https://registry.yarnpkg.com/hasown/-/hasown-2.0.2.tgz#003eaf91be7adc372e84ec59dc37252cedb80003"
- integrity sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==
- dependencies:
- function-bind "^1.1.2"
-
-html-escaper@^2.0.0:
- version "2.0.2"
- resolved "https://registry.yarnpkg.com/html-escaper/-/html-escaper-2.0.2.tgz#dfd60027da36a36dfcbe236262c00a5822681453"
- integrity sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==
-
-human-signals@^2.1.0:
- version "2.1.0"
- resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0"
- integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==
-
-i18next-browser-languagedetector@^8.0.0:
- version "8.0.0"
- resolved "https://registry.yarnpkg.com/i18next-browser-languagedetector/-/i18next-browser-languagedetector-8.0.0.tgz#b6fdd9b43af67c47f2c26c9ba27710a1eaf31e2f"
- integrity sha512-zhXdJXTTCoG39QsrOCiOabnWj2jecouOqbchu3EfhtSHxIB5Uugnm9JaizenOy39h7ne3+fLikIjeW88+rgszw==
- dependencies:
- "@babel/runtime" "^7.23.2"
-
-i18next@^23.15.1:
- version "23.16.2"
- resolved "https://registry.yarnpkg.com/i18next/-/i18next-23.16.2.tgz#ef6868ef6ac7bcaee4f5fe35132021d44e8d1063"
- integrity sha512-dFyxwLXxEQK32f6tITBMaRht25mZPJhQ0WbC0p3bO2mWBal9lABTMqSka5k+GLSRWLzeJBKDpH7BeIA9TZI7Jg==
- dependencies:
- "@babel/runtime" "^7.23.2"
-
-icss-replace-symbols@^1.1.0:
- version "1.1.0"
- resolved "https://registry.yarnpkg.com/icss-replace-symbols/-/icss-replace-symbols-1.1.0.tgz#06ea6f83679a7749e386cfe1fe812ae5db223ded"
- integrity sha512-chIaY3Vh2mh2Q3RGXttaDIzeiPvaVXJ+C4DAh/w3c37SKZ/U6PGMmuicR2EQQp9bKG8zLMCl7I+PtIoOOPp8Gg==
-
-icss-utils@^5.0.0:
- version "5.1.0"
- resolved "https://registry.yarnpkg.com/icss-utils/-/icss-utils-5.1.0.tgz#c6be6858abd013d768e98366ae47e25d5887b1ae"
- integrity sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==
-
-ignore@^5.2.0, ignore@^5.3.1:
- version "5.3.2"
- resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.3.2.tgz#3cd40e729f3643fd87cb04e50bf0eb722bc596f5"
- integrity sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==
-
-immutable@^4.0.0:
- version "4.3.7"
- resolved "https://registry.yarnpkg.com/immutable/-/immutable-4.3.7.tgz#c70145fc90d89fb02021e65c84eb0226e4e5a381"
- integrity sha512-1hqclzwYwjRDFLjcFxOM5AYkkG0rpFPpr1RLPMEuGczoS7YA8gLhy8SWXYRAA/XwfEHpfo3cw5JGioS32fnMRw==
-
-import-cwd@^3.0.0:
- version "3.0.0"
- resolved "https://registry.yarnpkg.com/import-cwd/-/import-cwd-3.0.0.tgz#20845547718015126ea9b3676b7592fb8bd4cf92"
- integrity sha512-4pnzH16plW+hgvRECbDWpQl3cqtvSofHWh44met7ESfZ8UZOWWddm8hEyDTqREJ9RbYHY8gi8DqmaelApoOGMg==
- dependencies:
- import-from "^3.0.0"
-
-import-fresh@^3.2.1:
- version "3.3.0"
- resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b"
- integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==
- dependencies:
- parent-module "^1.0.0"
- resolve-from "^4.0.0"
-
-import-from@^3.0.0:
- version "3.0.0"
- resolved "https://registry.yarnpkg.com/import-from/-/import-from-3.0.0.tgz#055cfec38cd5a27d8057ca51376d7d3bf0891966"
- integrity sha512-CiuXOFFSzkU5x/CR0+z7T91Iht4CXgfCxVOFRhh2Zyhg5wOpWvvDLQUsWl+gcN+QscYBjez8hDCt85O7RLDttQ==
- dependencies:
- resolve-from "^5.0.0"
-
-import-local@^3.0.2:
- version "3.2.0"
- resolved "https://registry.yarnpkg.com/import-local/-/import-local-3.2.0.tgz#c3d5c745798c02a6f8b897726aba5100186ee260"
- integrity sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA==
- dependencies:
- pkg-dir "^4.2.0"
- resolve-cwd "^3.0.0"
-
-imurmurhash@^0.1.4:
- version "0.1.4"
- resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea"
- integrity sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==
-
-inflight@^1.0.4:
- version "1.0.6"
- resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9"
- integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==
- dependencies:
- once "^1.3.0"
- wrappy "1"
-
-inherits@2:
- version "2.0.4"
- resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c"
- integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
-
-ini@~1.3.0:
- version "1.3.8"
- resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c"
- integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==
-
-internal-slot@^1.0.7:
- version "1.0.7"
- resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.7.tgz#c06dcca3ed874249881007b0a5523b172a190802"
- integrity sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==
- dependencies:
- es-errors "^1.3.0"
- hasown "^2.0.0"
- side-channel "^1.0.4"
-
-is-array-buffer@^3.0.4:
- version "3.0.4"
- resolved "https://registry.yarnpkg.com/is-array-buffer/-/is-array-buffer-3.0.4.tgz#7a1f92b3d61edd2bc65d24f130530ea93d7fae98"
- integrity sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==
- dependencies:
- call-bind "^1.0.2"
- get-intrinsic "^1.2.1"
-
-is-arrayish@^0.2.1:
- version "0.2.1"
- resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d"
- integrity sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==
-
-is-bigint@^1.0.1:
- version "1.0.4"
- resolved "https://registry.yarnpkg.com/is-bigint/-/is-bigint-1.0.4.tgz#08147a1875bc2b32005d41ccd8291dffc6691df3"
- integrity sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==
- dependencies:
- has-bigints "^1.0.1"
-
-is-boolean-object@^1.1.0:
- version "1.1.2"
- resolved "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.1.2.tgz#5c6dc200246dd9321ae4b885a114bb1f75f63719"
- integrity sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==
- dependencies:
- call-bind "^1.0.2"
- has-tostringtag "^1.0.0"
-
-is-builtin-module@^3.2.1:
- version "3.2.1"
- resolved "https://registry.yarnpkg.com/is-builtin-module/-/is-builtin-module-3.2.1.tgz#f03271717d8654cfcaf07ab0463faa3571581169"
- integrity sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A==
- dependencies:
- builtin-modules "^3.3.0"
-
-is-callable@^1.1.3, is-callable@^1.1.4, is-callable@^1.2.7:
- version "1.2.7"
- resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.7.tgz#3bc2a85ea742d9e36205dcacdd72ca1fdc51b055"
- integrity sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==
-
-is-core-module@^2.13.0, is-core-module@^2.15.1:
- version "2.15.1"
- resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.15.1.tgz#a7363a25bee942fefab0de13bf6aa372c82dcc37"
- integrity sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==
- dependencies:
- hasown "^2.0.2"
-
-is-data-view@^1.0.1:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/is-data-view/-/is-data-view-1.0.1.tgz#4b4d3a511b70f3dc26d42c03ca9ca515d847759f"
- integrity sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w==
- dependencies:
- is-typed-array "^1.1.13"
-
-is-date-object@^1.0.1:
- version "1.0.5"
- resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.5.tgz#0841d5536e724c25597bf6ea62e1bd38298df31f"
- integrity sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==
- dependencies:
- has-tostringtag "^1.0.0"
-
-is-docker@^2.0.0, is-docker@^2.1.1:
- version "2.2.1"
- resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-2.2.1.tgz#33eeabe23cfe86f14bde4408a02c0cfb853acdaa"
- integrity sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==
-
-is-extglob@^2.1.1:
- version "2.1.1"
- resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2"
- integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==
-
-is-fullwidth-code-point@^3.0.0:
- version "3.0.0"
- resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d"
- integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==
-
-is-generator-fn@^2.0.0:
- version "2.1.0"
- resolved "https://registry.yarnpkg.com/is-generator-fn/-/is-generator-fn-2.1.0.tgz#7d140adc389aaf3011a8f2a2a4cfa6faadffb118"
- integrity sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==
-
-is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3:
- version "4.0.3"
- resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084"
- integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==
- dependencies:
- is-extglob "^2.1.1"
-
-is-module@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/is-module/-/is-module-1.0.0.tgz#3258fb69f78c14d5b815d664336b4cffb6441591"
- integrity sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==
-
-is-negative-zero@^2.0.3:
- version "2.0.3"
- resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.3.tgz#ced903a027aca6381b777a5743069d7376a49747"
- integrity sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==
-
-is-number-object@^1.0.4:
- version "1.0.7"
- resolved "https://registry.yarnpkg.com/is-number-object/-/is-number-object-1.0.7.tgz#59d50ada4c45251784e9904f5246c742f07a42fc"
- integrity sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==
- dependencies:
- has-tostringtag "^1.0.0"
-
-is-number@^7.0.0:
- version "7.0.0"
- resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b"
- integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==
-
-is-path-inside@^3.0.3:
- version "3.0.3"
- resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.3.tgz#d231362e53a07ff2b0e0ea7fed049161ffd16283"
- integrity sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==
-
-is-port-reachable@4.0.0:
- version "4.0.0"
- resolved "https://registry.yarnpkg.com/is-port-reachable/-/is-port-reachable-4.0.0.tgz#dac044091ef15319c8ab2f34604d8794181f8c2d"
- integrity sha512-9UoipoxYmSk6Xy7QFgRv2HDyaysmgSG75TFQs6S+3pDM7ZhKTF/bskZV+0UlABHzKjNVhPjYCLfeZUEg1wXxig==
-
-is-regex@^1.1.4:
- version "1.1.4"
- resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.4.tgz#eef5663cd59fa4c0ae339505323df6854bb15958"
- integrity sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==
- dependencies:
- call-bind "^1.0.2"
- has-tostringtag "^1.0.0"
-
-is-shared-array-buffer@^1.0.2, is-shared-array-buffer@^1.0.3:
- version "1.0.3"
- resolved "https://registry.yarnpkg.com/is-shared-array-buffer/-/is-shared-array-buffer-1.0.3.tgz#1237f1cba059cdb62431d378dcc37d9680181688"
- integrity sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==
- dependencies:
- call-bind "^1.0.7"
-
-is-stream@^2.0.0:
- version "2.0.1"
- resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077"
- integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==
-
-is-string@^1.0.5, is-string@^1.0.7:
- version "1.0.7"
- resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.7.tgz#0dd12bf2006f255bb58f695110eff7491eebc0fd"
- integrity sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==
- dependencies:
- has-tostringtag "^1.0.0"
-
-is-symbol@^1.0.2, is-symbol@^1.0.3:
- version "1.0.4"
- resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.4.tgz#a6dac93b635b063ca6872236de88910a57af139c"
- integrity sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==
- dependencies:
- has-symbols "^1.0.2"
-
-is-typed-array@^1.1.13:
- version "1.1.13"
- resolved "https://registry.yarnpkg.com/is-typed-array/-/is-typed-array-1.1.13.tgz#d6c5ca56df62334959322d7d7dd1cca50debe229"
- integrity sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==
- dependencies:
- which-typed-array "^1.1.14"
-
-is-weakref@^1.0.2:
- version "1.0.2"
- resolved "https://registry.yarnpkg.com/is-weakref/-/is-weakref-1.0.2.tgz#9529f383a9338205e89765e0392efc2f100f06f2"
- integrity sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==
- dependencies:
- call-bind "^1.0.2"
-
-is-wsl@^2.2.0:
- version "2.2.0"
- resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-2.2.0.tgz#74a4c76e77ca9fd3f932f290c17ea326cd157271"
- integrity sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==
- dependencies:
- is-docker "^2.0.0"
-
-isarray@^2.0.5:
- version "2.0.5"
- resolved "https://registry.yarnpkg.com/isarray/-/isarray-2.0.5.tgz#8af1e4c1221244cc62459faf38940d4e644a5723"
- integrity sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==
-
-isexe@^2.0.0:
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10"
- integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==
-
-istanbul-lib-coverage@^3.0.0, istanbul-lib-coverage@^3.2.0:
- version "3.2.2"
- resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz#2d166c4b0644d43a39f04bf6c2edd1e585f31756"
- integrity sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==
-
-istanbul-lib-instrument@^5.0.4:
- version "5.2.1"
- resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz#d10c8885c2125574e1c231cacadf955675e1ce3d"
- integrity sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==
- dependencies:
- "@babel/core" "^7.12.3"
- "@babel/parser" "^7.14.7"
- "@istanbuljs/schema" "^0.1.2"
- istanbul-lib-coverage "^3.2.0"
- semver "^6.3.0"
-
-istanbul-lib-instrument@^6.0.0:
- version "6.0.3"
- resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.3.tgz#fa15401df6c15874bcb2105f773325d78c666765"
- integrity sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q==
- dependencies:
- "@babel/core" "^7.23.9"
- "@babel/parser" "^7.23.9"
- "@istanbuljs/schema" "^0.1.3"
- istanbul-lib-coverage "^3.2.0"
- semver "^7.5.4"
-
-istanbul-lib-report@^3.0.0:
- version "3.0.1"
- resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz#908305bac9a5bd175ac6a74489eafd0fc2445a7d"
- integrity sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==
- dependencies:
- istanbul-lib-coverage "^3.0.0"
- make-dir "^4.0.0"
- supports-color "^7.1.0"
-
-istanbul-lib-source-maps@^4.0.0:
- version "4.0.1"
- resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz#895f3a709fcfba34c6de5a42939022f3e4358551"
- integrity sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==
- dependencies:
- debug "^4.1.1"
- istanbul-lib-coverage "^3.0.0"
- source-map "^0.6.1"
-
-istanbul-reports@^3.1.3:
- version "3.1.7"
- resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-3.1.7.tgz#daed12b9e1dca518e15c056e1e537e741280fa0b"
- integrity sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==
- dependencies:
- html-escaper "^2.0.0"
- istanbul-lib-report "^3.0.0"
-
-jest-changed-files@^29.7.0:
- version "29.7.0"
- resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-29.7.0.tgz#1c06d07e77c78e1585d020424dedc10d6e17ac3a"
- integrity sha512-fEArFiwf1BpQ+4bXSprcDc3/x4HSzL4al2tozwVpDFpsxALjLYdyiIK4e5Vz66GQJIbXJ82+35PtysofptNX2w==
- dependencies:
- execa "^5.0.0"
- jest-util "^29.7.0"
- p-limit "^3.1.0"
-
-jest-circus@^29.7.0:
- version "29.7.0"
- resolved "https://registry.yarnpkg.com/jest-circus/-/jest-circus-29.7.0.tgz#b6817a45fcc835d8b16d5962d0c026473ee3668a"
- integrity sha512-3E1nCMgipcTkCocFwM90XXQab9bS+GMsjdpmPrlelaxwD93Ad8iVEjX/vvHPdLPnFf+L40u+5+iutRdA1N9myw==
- dependencies:
- "@jest/environment" "^29.7.0"
- "@jest/expect" "^29.7.0"
- "@jest/test-result" "^29.7.0"
- "@jest/types" "^29.6.3"
- "@types/node" "*"
- chalk "^4.0.0"
- co "^4.6.0"
- dedent "^1.0.0"
- is-generator-fn "^2.0.0"
- jest-each "^29.7.0"
- jest-matcher-utils "^29.7.0"
- jest-message-util "^29.7.0"
- jest-runtime "^29.7.0"
- jest-snapshot "^29.7.0"
- jest-util "^29.7.0"
- p-limit "^3.1.0"
- pretty-format "^29.7.0"
- pure-rand "^6.0.0"
- slash "^3.0.0"
- stack-utils "^2.0.3"
-
-jest-cli@^29.7.0:
- version "29.7.0"
- resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-29.7.0.tgz#5592c940798e0cae677eec169264f2d839a37995"
- integrity sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg==
- dependencies:
- "@jest/core" "^29.7.0"
- "@jest/test-result" "^29.7.0"
- "@jest/types" "^29.6.3"
- chalk "^4.0.0"
- create-jest "^29.7.0"
- exit "^0.1.2"
- import-local "^3.0.2"
- jest-config "^29.7.0"
- jest-util "^29.7.0"
- jest-validate "^29.7.0"
- yargs "^17.3.1"
-
-jest-config@^29.7.0:
- version "29.7.0"
- resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-29.7.0.tgz#bcbda8806dbcc01b1e316a46bb74085a84b0245f"
- integrity sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ==
- dependencies:
- "@babel/core" "^7.11.6"
- "@jest/test-sequencer" "^29.7.0"
- "@jest/types" "^29.6.3"
- babel-jest "^29.7.0"
- chalk "^4.0.0"
- ci-info "^3.2.0"
- deepmerge "^4.2.2"
- glob "^7.1.3"
- graceful-fs "^4.2.9"
- jest-circus "^29.7.0"
- jest-environment-node "^29.7.0"
- jest-get-type "^29.6.3"
- jest-regex-util "^29.6.3"
- jest-resolve "^29.7.0"
- jest-runner "^29.7.0"
- jest-util "^29.7.0"
- jest-validate "^29.7.0"
- micromatch "^4.0.4"
- parse-json "^5.2.0"
- pretty-format "^29.7.0"
- slash "^3.0.0"
- strip-json-comments "^3.1.1"
-
-jest-diff@^29.7.0:
- version "29.7.0"
- resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-29.7.0.tgz#017934a66ebb7ecf6f205e84699be10afd70458a"
- integrity sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==
- dependencies:
- chalk "^4.0.0"
- diff-sequences "^29.6.3"
- jest-get-type "^29.6.3"
- pretty-format "^29.7.0"
-
-jest-docblock@^29.7.0:
- version "29.7.0"
- resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-29.7.0.tgz#8fddb6adc3cdc955c93e2a87f61cfd350d5d119a"
- integrity sha512-q617Auw3A612guyaFgsbFeYpNP5t2aoUNLwBUbc/0kD1R4t9ixDbyFTHd1nok4epoVFpr7PmeWHrhvuV3XaJ4g==
- dependencies:
- detect-newline "^3.0.0"
-
-jest-each@^29.7.0:
- version "29.7.0"
- resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-29.7.0.tgz#162a9b3f2328bdd991beaabffbb74745e56577d1"
- integrity sha512-gns+Er14+ZrEoC5fhOfYCY1LOHHr0TI+rQUHZS8Ttw2l7gl+80eHc/gFf2Ktkw0+SIACDTeWvpFcv3B04VembQ==
- dependencies:
- "@jest/types" "^29.6.3"
- chalk "^4.0.0"
- jest-get-type "^29.6.3"
- jest-util "^29.7.0"
- pretty-format "^29.7.0"
-
-jest-environment-node@^29.7.0:
- version "29.7.0"
- resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-29.7.0.tgz#0b93e111dda8ec120bc8300e6d1fb9576e164376"
- integrity sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw==
- dependencies:
- "@jest/environment" "^29.7.0"
- "@jest/fake-timers" "^29.7.0"
- "@jest/types" "^29.6.3"
- "@types/node" "*"
- jest-mock "^29.7.0"
- jest-util "^29.7.0"
-
-jest-get-type@^29.6.3:
- version "29.6.3"
- resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-29.6.3.tgz#36f499fdcea197c1045a127319c0481723908fd1"
- integrity sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==
-
-jest-haste-map@^29.7.0:
- version "29.7.0"
- resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-29.7.0.tgz#3c2396524482f5a0506376e6c858c3bbcc17b104"
- integrity sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==
- dependencies:
- "@jest/types" "^29.6.3"
- "@types/graceful-fs" "^4.1.3"
- "@types/node" "*"
- anymatch "^3.0.3"
- fb-watchman "^2.0.0"
- graceful-fs "^4.2.9"
- jest-regex-util "^29.6.3"
- jest-util "^29.7.0"
- jest-worker "^29.7.0"
- micromatch "^4.0.4"
- walker "^1.0.8"
- optionalDependencies:
- fsevents "^2.3.2"
-
-jest-leak-detector@^29.7.0:
- version "29.7.0"
- resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-29.7.0.tgz#5b7ec0dadfdfec0ca383dc9aa016d36b5ea4c728"
- integrity sha512-kYA8IJcSYtST2BY9I+SMC32nDpBT3J2NvWJx8+JCuCdl/CR1I4EKUJROiP8XtCcxqgTTBGJNdbB1A8XRKbTetw==
- dependencies:
- jest-get-type "^29.6.3"
- pretty-format "^29.7.0"
-
-jest-matcher-utils@^29.7.0:
- version "29.7.0"
- resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-29.7.0.tgz#ae8fec79ff249fd592ce80e3ee474e83a6c44f12"
- integrity sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g==
- dependencies:
- chalk "^4.0.0"
- jest-diff "^29.7.0"
- jest-get-type "^29.6.3"
- pretty-format "^29.7.0"
-
-jest-message-util@^29.7.0:
- version "29.7.0"
- resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-29.7.0.tgz#8bc392e204e95dfe7564abbe72a404e28e51f7f3"
- integrity sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==
- dependencies:
- "@babel/code-frame" "^7.12.13"
- "@jest/types" "^29.6.3"
- "@types/stack-utils" "^2.0.0"
- chalk "^4.0.0"
- graceful-fs "^4.2.9"
- micromatch "^4.0.4"
- pretty-format "^29.7.0"
- slash "^3.0.0"
- stack-utils "^2.0.3"
-
-jest-mock@^29.7.0:
- version "29.7.0"
- resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-29.7.0.tgz#4e836cf60e99c6fcfabe9f99d017f3fdd50a6347"
- integrity sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw==
- dependencies:
- "@jest/types" "^29.6.3"
- "@types/node" "*"
- jest-util "^29.7.0"
-
-jest-pnp-resolver@^1.2.2:
- version "1.2.3"
- resolved "https://registry.yarnpkg.com/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz#930b1546164d4ad5937d5540e711d4d38d4cad2e"
- integrity sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==
-
-jest-regex-util@^29.6.3:
- version "29.6.3"
- resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-29.6.3.tgz#4a556d9c776af68e1c5f48194f4d0327d24e8a52"
- integrity sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==
-
-jest-resolve-dependencies@^29.7.0:
- version "29.7.0"
- resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-29.7.0.tgz#1b04f2c095f37fc776ff40803dc92921b1e88428"
- integrity sha512-un0zD/6qxJ+S0et7WxeI3H5XSe9lTBBR7bOHCHXkKR6luG5mwDDlIzVQ0V5cZCuoTgEdcdwzTghYkTWfubi+nA==
- dependencies:
- jest-regex-util "^29.6.3"
- jest-snapshot "^29.7.0"
-
-jest-resolve@^29.7.0:
- version "29.7.0"
- resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-29.7.0.tgz#64d6a8992dd26f635ab0c01e5eef4399c6bcbc30"
- integrity sha512-IOVhZSrg+UvVAshDSDtHyFCCBUl/Q3AAJv8iZ6ZjnZ74xzvwuzLXid9IIIPgTnY62SJjfuupMKZsZQRsCvxEgA==
- dependencies:
- chalk "^4.0.0"
- graceful-fs "^4.2.9"
- jest-haste-map "^29.7.0"
- jest-pnp-resolver "^1.2.2"
- jest-util "^29.7.0"
- jest-validate "^29.7.0"
- resolve "^1.20.0"
- resolve.exports "^2.0.0"
- slash "^3.0.0"
-
-jest-runner@^29.7.0:
- version "29.7.0"
- resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-29.7.0.tgz#809af072d408a53dcfd2e849a4c976d3132f718e"
- integrity sha512-fsc4N6cPCAahybGBfTRcq5wFR6fpLznMg47sY5aDpsoejOcVYFb07AHuSnR0liMcPTgBsA3ZJL6kFOjPdoNipQ==
- dependencies:
- "@jest/console" "^29.7.0"
- "@jest/environment" "^29.7.0"
- "@jest/test-result" "^29.7.0"
- "@jest/transform" "^29.7.0"
- "@jest/types" "^29.6.3"
- "@types/node" "*"
- chalk "^4.0.0"
- emittery "^0.13.1"
- graceful-fs "^4.2.9"
- jest-docblock "^29.7.0"
- jest-environment-node "^29.7.0"
- jest-haste-map "^29.7.0"
- jest-leak-detector "^29.7.0"
- jest-message-util "^29.7.0"
- jest-resolve "^29.7.0"
- jest-runtime "^29.7.0"
- jest-util "^29.7.0"
- jest-watcher "^29.7.0"
- jest-worker "^29.7.0"
- p-limit "^3.1.0"
- source-map-support "0.5.13"
-
-jest-runtime@^29.7.0:
- version "29.7.0"
- resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-29.7.0.tgz#efecb3141cf7d3767a3a0cc8f7c9990587d3d817"
- integrity sha512-gUnLjgwdGqW7B4LvOIkbKs9WGbn+QLqRQQ9juC6HndeDiezIwhDP+mhMwHWCEcfQ5RUXa6OPnFF8BJh5xegwwQ==
- dependencies:
- "@jest/environment" "^29.7.0"
- "@jest/fake-timers" "^29.7.0"
- "@jest/globals" "^29.7.0"
- "@jest/source-map" "^29.6.3"
- "@jest/test-result" "^29.7.0"
- "@jest/transform" "^29.7.0"
- "@jest/types" "^29.6.3"
- "@types/node" "*"
- chalk "^4.0.0"
- cjs-module-lexer "^1.0.0"
- collect-v8-coverage "^1.0.0"
- glob "^7.1.3"
- graceful-fs "^4.2.9"
- jest-haste-map "^29.7.0"
- jest-message-util "^29.7.0"
- jest-mock "^29.7.0"
- jest-regex-util "^29.6.3"
- jest-resolve "^29.7.0"
- jest-snapshot "^29.7.0"
- jest-util "^29.7.0"
- slash "^3.0.0"
- strip-bom "^4.0.0"
-
-jest-snapshot@^29.7.0:
- version "29.7.0"
- resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-29.7.0.tgz#c2c574c3f51865da1bb329036778a69bf88a6be5"
- integrity sha512-Rm0BMWtxBcioHr1/OX5YCP8Uov4riHvKPknOGs804Zg9JGZgmIBkbtlxJC/7Z4msKYVbIJtfU+tKb8xlYNfdkw==
- dependencies:
- "@babel/core" "^7.11.6"
- "@babel/generator" "^7.7.2"
- "@babel/plugin-syntax-jsx" "^7.7.2"
- "@babel/plugin-syntax-typescript" "^7.7.2"
- "@babel/types" "^7.3.3"
- "@jest/expect-utils" "^29.7.0"
- "@jest/transform" "^29.7.0"
- "@jest/types" "^29.6.3"
- babel-preset-current-node-syntax "^1.0.0"
- chalk "^4.0.0"
- expect "^29.7.0"
- graceful-fs "^4.2.9"
- jest-diff "^29.7.0"
- jest-get-type "^29.6.3"
- jest-matcher-utils "^29.7.0"
- jest-message-util "^29.7.0"
- jest-util "^29.7.0"
- natural-compare "^1.4.0"
- pretty-format "^29.7.0"
- semver "^7.5.3"
-
-jest-util@^29.7.0:
- version "29.7.0"
- resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-29.7.0.tgz#23c2b62bfb22be82b44de98055802ff3710fc0bc"
- integrity sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==
- dependencies:
- "@jest/types" "^29.6.3"
- "@types/node" "*"
- chalk "^4.0.0"
- ci-info "^3.2.0"
- graceful-fs "^4.2.9"
- picomatch "^2.2.3"
-
-jest-validate@^29.7.0:
- version "29.7.0"
- resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-29.7.0.tgz#7bf705511c64da591d46b15fce41400d52147d9c"
- integrity sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw==
- dependencies:
- "@jest/types" "^29.6.3"
- camelcase "^6.2.0"
- chalk "^4.0.0"
- jest-get-type "^29.6.3"
- leven "^3.1.0"
- pretty-format "^29.7.0"
-
-jest-watcher@^29.7.0:
- version "29.7.0"
- resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-29.7.0.tgz#7810d30d619c3a62093223ce6bb359ca1b28a2f2"
- integrity sha512-49Fg7WXkU3Vl2h6LbLtMQ/HyB6rXSIX7SqvBLQmssRBGN9I0PNvPmAmCWSOY6SOvrjhI/F7/bGAv9RtnsPA03g==
- dependencies:
- "@jest/test-result" "^29.7.0"
- "@jest/types" "^29.6.3"
- "@types/node" "*"
- ansi-escapes "^4.2.1"
- chalk "^4.0.0"
- emittery "^0.13.1"
- jest-util "^29.7.0"
- string-length "^4.0.1"
-
-jest-worker@^29.7.0:
- version "29.7.0"
- resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-29.7.0.tgz#acad073acbbaeb7262bd5389e1bcf43e10058d4a"
- integrity sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==
- dependencies:
- "@types/node" "*"
- jest-util "^29.7.0"
- merge-stream "^2.0.0"
- supports-color "^8.0.0"
-
-jest@^29.7.0:
- version "29.7.0"
- resolved "https://registry.yarnpkg.com/jest/-/jest-29.7.0.tgz#994676fc24177f088f1c5e3737f5697204ff2613"
- integrity sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==
- dependencies:
- "@jest/core" "^29.7.0"
- "@jest/types" "^29.6.3"
- import-local "^3.0.2"
- jest-cli "^29.7.0"
-
-js-tokens@^4.0.0:
- version "4.0.0"
- resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499"
- integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==
-
-js-yaml@^3.13.1:
- version "3.14.1"
- resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.1.tgz#dae812fdb3825fa306609a8717383c50c36a0537"
- integrity sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==
- dependencies:
- argparse "^1.0.7"
- esprima "^4.0.0"
-
-js-yaml@^4.1.0:
- version "4.1.0"
- resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602"
- integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==
- dependencies:
- argparse "^2.0.1"
-
-jsdoc-type-pratt-parser@^4.0.0:
- version "4.1.0"
- resolved "https://registry.yarnpkg.com/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-4.1.0.tgz#ff6b4a3f339c34a6c188cbf50a16087858d22113"
- integrity sha512-Hicd6JK5Njt2QB6XYFS7ok9e37O8AYk3jTcppG4YVQnYjOemymvTcmc7OWsmq/Qqj5TdRFO5/x/tIPmBeRtGHg==
-
-jsdoc-type-pratt-parser@~4.0.0:
- version "4.0.0"
- resolved "https://registry.yarnpkg.com/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-4.0.0.tgz#136f0571a99c184d84ec84662c45c29ceff71114"
- integrity sha512-YtOli5Cmzy3q4dP26GraSOeAhqecewG04hoO8DY56CH4KJ9Fvv5qKWUCCo3HZob7esJQHCv6/+bnTy72xZZaVQ==
-
-jsesc@^3.0.2:
- version "3.0.2"
- resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-3.0.2.tgz#bb8b09a6597ba426425f2e4a07245c3d00b9343e"
- integrity sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==
-
-json-buffer@3.0.1:
- version "3.0.1"
- resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.1.tgz#9338802a30d3b6605fbe0613e094008ca8c05a13"
- integrity sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==
-
-json-parse-even-better-errors@^2.3.0:
- version "2.3.1"
- resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d"
- integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==
-
-json-schema-traverse@^0.4.1:
- version "0.4.1"
- resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660"
- integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==
-
-json-schema-traverse@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2"
- integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==
-
-json-stable-stringify-without-jsonify@^1.0.1:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651"
- integrity sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==
-
-json5@^1.0.2:
- version "1.0.2"
- resolved "https://registry.yarnpkg.com/json5/-/json5-1.0.2.tgz#63d98d60f21b313b77c4d6da18bfa69d80e1d593"
- integrity sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==
- dependencies:
- minimist "^1.2.0"
-
-json5@^2.2.3:
- version "2.2.3"
- resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283"
- integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==
-
-keyv@^4.5.3:
- version "4.5.4"
- resolved "https://registry.yarnpkg.com/keyv/-/keyv-4.5.4.tgz#a879a99e29452f942439f2a405e3af8b31d4de93"
- integrity sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==
- dependencies:
- json-buffer "3.0.1"
-
-kleur@^3.0.3:
- version "3.0.3"
- resolved "https://registry.yarnpkg.com/kleur/-/kleur-3.0.3.tgz#a79c9ecc86ee1ce3fa6206d1216c501f147fc07e"
- integrity sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==
-
-leven@^3.1.0:
- version "3.1.0"
- resolved "https://registry.yarnpkg.com/leven/-/leven-3.1.0.tgz#77891de834064cccba82ae7842bb6b14a13ed7f2"
- integrity sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==
-
-levn@^0.4.1:
- version "0.4.1"
- resolved "https://registry.yarnpkg.com/levn/-/levn-0.4.1.tgz#ae4562c007473b932a6200d403268dd2fffc6ade"
- integrity sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==
- dependencies:
- prelude-ls "^1.2.1"
- type-check "~0.4.0"
-
-lilconfig@^2.0.3, lilconfig@^2.0.5:
- version "2.1.0"
- resolved "https://registry.yarnpkg.com/lilconfig/-/lilconfig-2.1.0.tgz#78e23ac89ebb7e1bfbf25b18043de756548e7f52"
- integrity sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==
-
-lines-and-columns@^1.1.6:
- version "1.2.4"
- resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632"
- integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==
-
-loader-utils@^3.2.0:
- version "3.3.1"
- resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-3.3.1.tgz#735b9a19fd63648ca7adbd31c2327dfe281304e5"
- integrity sha512-FMJTLMXfCLMLfJxcX9PFqX5qD88Z5MRGaZCVzfuqeZSPsyiBzs+pahDQjbIWz2QIzPZz0NX9Zy4FX3lmK6YHIg==
-
-locate-path@^5.0.0:
- version "5.0.0"
- resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0"
- integrity sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==
- dependencies:
- p-locate "^4.1.0"
-
-locate-path@^6.0.0:
- version "6.0.0"
- resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286"
- integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==
- dependencies:
- p-locate "^5.0.0"
-
-lodash.camelcase@^4.3.0:
- version "4.3.0"
- resolved "https://registry.yarnpkg.com/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz#b28aa6288a2b9fc651035c7711f65ab6190331a6"
- integrity sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==
-
-lodash.memoize@^4.1.2:
- version "4.1.2"
- resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe"
- integrity sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==
-
-lodash.merge@^4.6.2:
- version "4.6.2"
- resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a"
- integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==
-
-lodash.uniq@^4.5.0:
- version "4.5.0"
- resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773"
- integrity sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==
-
-lodash@^4.17.21:
- version "4.17.21"
- resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
- integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
-
-lru-cache@^5.1.1:
- version "5.1.1"
- resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920"
- integrity sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==
- dependencies:
- yallist "^3.0.2"
-
-magic-string@^0.30.3:
- version "0.30.12"
- resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.30.12.tgz#9eb11c9d072b9bcb4940a5b2c2e1a217e4ee1a60"
- integrity sha512-Ea8I3sQMVXr8JhN4z+H/d8zwo+tYDgHE9+5G4Wnrwhs0gaK9fXTKx0Tw5Xwsd/bCPTTZNRAdpyzvoeORe9LYpw==
- dependencies:
- "@jridgewell/sourcemap-codec" "^1.5.0"
-
-make-dir@^4.0.0:
- version "4.0.0"
- resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-4.0.0.tgz#c3c2307a771277cd9638305f915c29ae741b614e"
- integrity sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==
- dependencies:
- semver "^7.5.3"
-
-makeerror@1.0.12:
- version "1.0.12"
- resolved "https://registry.yarnpkg.com/makeerror/-/makeerror-1.0.12.tgz#3e5dd2079a82e812e983cc6610c4a2cb0eaa801a"
- integrity sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==
- dependencies:
- tmpl "1.0.5"
-
-mdn-data@2.0.14:
- version "2.0.14"
- resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.14.tgz#7113fc4281917d63ce29b43446f701e68c25ba50"
- integrity sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==
-
-merge-stream@^2.0.0:
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60"
- integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==
-
-merge2@^1.3.0, merge2@^1.4.1:
- version "1.4.1"
- resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae"
- integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==
-
-micromatch@^4.0.4, micromatch@^4.0.5:
- version "4.0.8"
- resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.8.tgz#d66fa18f3a47076789320b9b1af32bd86d9fa202"
- integrity sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==
- dependencies:
- braces "^3.0.3"
- picomatch "^2.3.1"
-
-mime-db@1.52.0:
- version "1.52.0"
- resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70"
- integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==
-
-"mime-db@>= 1.43.0 < 2":
- version "1.53.0"
- resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.53.0.tgz#3cb63cd820fc29896d9d4e8c32ab4fcd74ccb447"
- integrity sha512-oHlN/w+3MQ3rba9rqFr6V/ypF10LSkdwUysQL7GkXoTgIWeV+tcXGA852TBxH+gsh8UWoyhR1hKcoMJTuWflpg==
-
-mime-db@~1.33.0:
- version "1.33.0"
- resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.33.0.tgz#a3492050a5cb9b63450541e39d9788d2272783db"
- integrity sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ==
-
-mime-types@2.1.18:
- version "2.1.18"
- resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.18.tgz#6f323f60a83d11146f831ff11fd66e2fe5503bb8"
- integrity sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==
- dependencies:
- mime-db "~1.33.0"
-
-mime-types@~2.1.34:
- version "2.1.35"
- resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a"
- integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==
- dependencies:
- mime-db "1.52.0"
-
-mimic-fn@^2.1.0:
- version "2.1.0"
- resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b"
- integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==
-
-mini-svg-data-uri@^1.4.4:
- version "1.4.4"
- resolved "https://registry.yarnpkg.com/mini-svg-data-uri/-/mini-svg-data-uri-1.4.4.tgz#8ab0aabcdf8c29ad5693ca595af19dd2ead09939"
- integrity sha512-r9deDe9p5FJUPZAk3A59wGH7Ii9YrjjWw0jmw/liSbHl2CHiyXj6FcDXDu2K3TjVAXqiJdaw3xxwlZZr9E6nHg==
-
-minimatch@3.1.2, minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2:
- version "3.1.2"
- resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b"
- integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==
- dependencies:
- brace-expansion "^1.1.7"
-
-minimatch@^9.0.4:
- version "9.0.5"
- resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.5.tgz#d74f9dd6b57d83d8e98cfb82133b03978bc929e5"
- integrity sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==
- dependencies:
- brace-expansion "^2.0.1"
-
-minimist@^1.2.0, minimist@^1.2.6:
- version "1.2.8"
- resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c"
- integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==
-
-ms@2.0.0:
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8"
- integrity sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==
-
-ms@^2.1.1, ms@^2.1.3:
- version "2.1.3"
- resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2"
- integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==
-
-nanoid@^3.3.7:
- version "3.3.7"
- resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.7.tgz#d0c301a691bc8d54efa0a2226ccf3fe2fd656bd8"
- integrity sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==
-
-natural-compare@^1.4.0:
- version "1.4.0"
- resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7"
- integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==
-
-negotiator@0.6.3:
- version "0.6.3"
- resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd"
- integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==
-
-node-addon-api@^7.0.0:
- version "7.1.1"
- resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-7.1.1.tgz#1aba6693b0f255258a049d621329329322aad558"
- integrity sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==
-
-node-int64@^0.4.0:
- version "0.4.0"
- resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b"
- integrity sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==
-
-node-releases@^2.0.18:
- version "2.0.18"
- resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.18.tgz#f010e8d35e2fe8d6b2944f03f70213ecedc4ca3f"
- integrity sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==
-
-normalize-path@^3.0.0:
- version "3.0.0"
- resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65"
- integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==
-
-normalize-range@^0.1.2:
- version "0.1.2"
- resolved "https://registry.yarnpkg.com/normalize-range/-/normalize-range-0.1.2.tgz#2d10c06bdfd312ea9777695a4d28439456b75942"
- integrity sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==
-
-normalize-url@^6.0.1:
- version "6.1.0"
- resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-6.1.0.tgz#40d0885b535deffe3f3147bec877d05fe4c5668a"
- integrity sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==
-
-npm-run-path@^4.0.1:
- version "4.0.1"
- resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea"
- integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==
- dependencies:
- path-key "^3.0.0"
-
-nth-check@^2.0.1:
- version "2.1.1"
- resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-2.1.1.tgz#c9eab428effce36cd6b92c924bdb000ef1f1ed1d"
- integrity sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==
- dependencies:
- boolbase "^1.0.0"
-
-object-assign@^4:
- version "4.1.1"
- resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
- integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==
-
-object-inspect@^1.13.1:
- version "1.13.2"
- resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.13.2.tgz#dea0088467fb991e67af4058147a24824a3043ff"
- integrity sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==
-
-object-keys@^1.1.1:
- version "1.1.1"
- resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e"
- integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==
-
-object.assign@^4.1.5:
- version "4.1.5"
- resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.5.tgz#3a833f9ab7fdb80fc9e8d2300c803d216d8fdbb0"
- integrity sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==
- dependencies:
- call-bind "^1.0.5"
- define-properties "^1.2.1"
- has-symbols "^1.0.3"
- object-keys "^1.1.1"
-
-object.fromentries@^2.0.8:
- version "2.0.8"
- resolved "https://registry.yarnpkg.com/object.fromentries/-/object.fromentries-2.0.8.tgz#f7195d8a9b97bd95cbc1999ea939ecd1a2b00c65"
- integrity sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==
- dependencies:
- call-bind "^1.0.7"
- define-properties "^1.2.1"
- es-abstract "^1.23.2"
- es-object-atoms "^1.0.0"
-
-object.groupby@^1.0.3:
- version "1.0.3"
- resolved "https://registry.yarnpkg.com/object.groupby/-/object.groupby-1.0.3.tgz#9b125c36238129f6f7b61954a1e7176148d5002e"
- integrity sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==
- dependencies:
- call-bind "^1.0.7"
- define-properties "^1.2.1"
- es-abstract "^1.23.2"
-
-object.values@^1.2.0:
- version "1.2.0"
- resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.2.0.tgz#65405a9d92cee68ac2d303002e0b8470a4d9ab1b"
- integrity sha512-yBYjY9QX2hnRmZHAjG/f13MzmBzxzYgQhFrke06TTyKY5zSTEqkOeukBzIdVA3j3ulu8Qa3MbVFShV7T2RmGtQ==
- dependencies:
- call-bind "^1.0.7"
- define-properties "^1.2.1"
- es-object-atoms "^1.0.0"
-
-on-headers@~1.0.2:
- version "1.0.2"
- resolved "https://registry.yarnpkg.com/on-headers/-/on-headers-1.0.2.tgz#772b0ae6aaa525c399e489adfad90c403eb3c28f"
- integrity sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==
-
-once@^1.3.0:
- version "1.4.0"
- resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1"
- integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==
- dependencies:
- wrappy "1"
-
-onetime@^5.1.2:
- version "5.1.2"
- resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e"
- integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==
- dependencies:
- mimic-fn "^2.1.0"
-
-open@^8.4.0:
- version "8.4.2"
- resolved "https://registry.yarnpkg.com/open/-/open-8.4.2.tgz#5b5ffe2a8f793dcd2aad73e550cb87b59cb084f9"
- integrity sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==
- dependencies:
- define-lazy-prop "^2.0.0"
- is-docker "^2.1.1"
- is-wsl "^2.2.0"
-
-optionator@^0.9.3:
- version "0.9.4"
- resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.4.tgz#7ea1c1a5d91d764fb282139c88fe11e182a3a734"
- integrity sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==
- dependencies:
- deep-is "^0.1.3"
- fast-levenshtein "^2.0.6"
- levn "^0.4.1"
- prelude-ls "^1.2.1"
- type-check "^0.4.0"
- word-wrap "^1.2.5"
-
-p-finally@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae"
- integrity sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==
-
-p-limit@^2.2.0:
- version "2.3.0"
- resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1"
- integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==
- dependencies:
- p-try "^2.0.0"
-
-p-limit@^3.0.2, p-limit@^3.1.0:
- version "3.1.0"
- resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b"
- integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==
- dependencies:
- yocto-queue "^0.1.0"
-
-p-locate@^4.1.0:
- version "4.1.0"
- resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-4.1.0.tgz#a3428bb7088b3a60292f66919278b7c297ad4f07"
- integrity sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==
- dependencies:
- p-limit "^2.2.0"
-
-p-locate@^5.0.0:
- version "5.0.0"
- resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834"
- integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==
- dependencies:
- p-limit "^3.0.2"
-
-p-queue@^6.6.2:
- version "6.6.2"
- resolved "https://registry.yarnpkg.com/p-queue/-/p-queue-6.6.2.tgz#2068a9dcf8e67dd0ec3e7a2bcb76810faa85e426"
- integrity sha512-RwFpb72c/BhQLEXIZ5K2e+AhgNVmIejGlTgiB9MzZ0e93GRvqZ7uSi0dvRF7/XIXDeNkra2fNHBxTyPDGySpjQ==
- dependencies:
- eventemitter3 "^4.0.4"
- p-timeout "^3.2.0"
-
-p-timeout@^3.2.0:
- version "3.2.0"
- resolved "https://registry.yarnpkg.com/p-timeout/-/p-timeout-3.2.0.tgz#c7e17abc971d2a7962ef83626b35d635acf23dfe"
- integrity sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg==
- dependencies:
- p-finally "^1.0.0"
-
-p-try@^2.0.0:
- version "2.2.0"
- resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6"
- integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==
-
-parent-module@^1.0.0:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2"
- integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==
- dependencies:
- callsites "^3.0.0"
-
-parse-json@^5.2.0:
- version "5.2.0"
- resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.2.0.tgz#c76fc66dee54231c962b22bcc8a72cf2f99753cd"
- integrity sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==
- dependencies:
- "@babel/code-frame" "^7.0.0"
- error-ex "^1.3.1"
- json-parse-even-better-errors "^2.3.0"
- lines-and-columns "^1.1.6"
-
-path-exists@^4.0.0:
- version "4.0.0"
- resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3"
- integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==
-
-path-is-absolute@^1.0.0:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f"
- integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==
-
-path-is-inside@1.0.2:
- version "1.0.2"
- resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53"
- integrity sha512-DUWJr3+ULp4zXmol/SZkFf3JGsS9/SIv+Y3Rt93/UjPpDpklB5f1er4O3POIbUuUJ3FXgqte2Q7SrU6zAqwk8w==
-
-path-key@^3.0.0, path-key@^3.1.0:
- version "3.1.1"
- resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375"
- integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==
-
-path-parse@^1.0.7:
- version "1.0.7"
- resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735"
- integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==
-
-path-to-regexp@3.3.0:
- version "3.3.0"
- resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-3.3.0.tgz#f7f31d32e8518c2660862b644414b6d5c63a611b"
- integrity sha512-qyCH421YQPS2WFDxDjftfc1ZR5WKQzVzqsp4n9M2kQhVOo/ByahFoUNJfl58kOcEGfQ//7weFTDhm+ss8Ecxgw==
-
-path-type@^4.0.0:
- version "4.0.0"
- resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b"
- integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==
-
-picocolors@^1.0.0, picocolors@^1.0.1, picocolors@^1.1.0:
- version "1.1.1"
- resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.1.1.tgz#3d321af3eab939b083c8f929a1d12cda81c26b6b"
- integrity sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==
-
-picomatch@^2.0.4, picomatch@^2.2.3, picomatch@^2.3.1:
- version "2.3.1"
- resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42"
- integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==
-
-pify@^5.0.0:
- version "5.0.0"
- resolved "https://registry.yarnpkg.com/pify/-/pify-5.0.0.tgz#1f5eca3f5e87ebec28cc6d54a0e4aaf00acc127f"
- integrity sha512-eW/gHNMlxdSP6dmG6uJip6FXN0EQBwm2clYYd8Wul42Cwu/DK8HEftzsapcNdYe2MfLiIwZqsDk2RDEsTE79hA==
-
-pirates@^4.0.4:
- version "4.0.6"
- resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.6.tgz#3018ae32ecfcff6c29ba2267cbf21166ac1f36b9"
- integrity sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==
-
-pkg-dir@^4.2.0:
- version "4.2.0"
- resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3"
- integrity sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==
- dependencies:
- find-up "^4.0.0"
-
-playcanvas@^1.74.0:
- version "1.74.0"
- resolved "https://registry.yarnpkg.com/playcanvas/-/playcanvas-1.74.0.tgz#5f871db5430f1c0eed8b8570e8fb08afd3f53c14"
- integrity sha512-0vIvUXj0Ml+CkOjsvXU9v+oMCtBqJzFLFhC8mwbRuaw+7J3v5XD1009tLoHtsmnj9ul3nHATtwrNPydqEQwylg==
- dependencies:
- "@types/webxr" "^0.5.16"
- "@webgpu/types" "^0.1.40"
-
-possible-typed-array-names@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz#89bb63c6fada2c3e90adc4a647beeeb39cc7bf8f"
- integrity sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==
-
-postcss-calc@^8.2.3:
- version "8.2.4"
- resolved "https://registry.yarnpkg.com/postcss-calc/-/postcss-calc-8.2.4.tgz#77b9c29bfcbe8a07ff6693dc87050828889739a5"
- integrity sha512-SmWMSJmB8MRnnULldx0lQIyhSNvuDl9HfrZkaqqE/WHAhToYsAvDq+yAsA/kIyINDszOp3Rh0GFoNuH5Ypsm3Q==
- dependencies:
- postcss-selector-parser "^6.0.9"
- postcss-value-parser "^4.2.0"
-
-postcss-colormin@^5.3.1:
- version "5.3.1"
- resolved "https://registry.yarnpkg.com/postcss-colormin/-/postcss-colormin-5.3.1.tgz#86c27c26ed6ba00d96c79e08f3ffb418d1d1988f"
- integrity sha512-UsWQG0AqTFQmpBegeLLc1+c3jIqBNB0zlDGRWR+dQ3pRKJL1oeMzyqmH3o2PIfn9MBdNrVPWhDbT769LxCTLJQ==
- dependencies:
- browserslist "^4.21.4"
- caniuse-api "^3.0.0"
- colord "^2.9.1"
- postcss-value-parser "^4.2.0"
-
-postcss-convert-values@^5.1.3:
- version "5.1.3"
- resolved "https://registry.yarnpkg.com/postcss-convert-values/-/postcss-convert-values-5.1.3.tgz#04998bb9ba6b65aa31035d669a6af342c5f9d393"
- integrity sha512-82pC1xkJZtcJEfiLw6UXnXVXScgtBrjlO5CBmuDQc+dlb88ZYheFsjTn40+zBVi3DkfF7iezO0nJUPLcJK3pvA==
- dependencies:
- browserslist "^4.21.4"
- postcss-value-parser "^4.2.0"
-
-postcss-discard-comments@^5.1.2:
- version "5.1.2"
- resolved "https://registry.yarnpkg.com/postcss-discard-comments/-/postcss-discard-comments-5.1.2.tgz#8df5e81d2925af2780075840c1526f0660e53696"
- integrity sha512-+L8208OVbHVF2UQf1iDmRcbdjJkuBF6IS29yBDSiWUIzpYaAhtNl6JYnYm12FnkeCwQqF5LeklOu6rAqgfBZqQ==
-
-postcss-discard-duplicates@^5.1.0:
- version "5.1.0"
- resolved "https://registry.yarnpkg.com/postcss-discard-duplicates/-/postcss-discard-duplicates-5.1.0.tgz#9eb4fe8456706a4eebd6d3b7b777d07bad03e848"
- integrity sha512-zmX3IoSI2aoenxHV6C7plngHWWhUOV3sP1T8y2ifzxzbtnuhk1EdPwm0S1bIUNaJ2eNbWeGLEwzw8huPD67aQw==
-
-postcss-discard-empty@^5.1.1:
- version "5.1.1"
- resolved "https://registry.yarnpkg.com/postcss-discard-empty/-/postcss-discard-empty-5.1.1.tgz#e57762343ff7f503fe53fca553d18d7f0c369c6c"
- integrity sha512-zPz4WljiSuLWsI0ir4Mcnr4qQQ5e1Ukc3i7UfE2XcrwKK2LIPIqE5jxMRxO6GbI3cv//ztXDsXwEWT3BHOGh3A==
-
-postcss-discard-overridden@^5.1.0:
- version "5.1.0"
- resolved "https://registry.yarnpkg.com/postcss-discard-overridden/-/postcss-discard-overridden-5.1.0.tgz#7e8c5b53325747e9d90131bb88635282fb4a276e"
- integrity sha512-21nOL7RqWR1kasIVdKs8HNqQJhFxLsyRfAnUDm4Fe4t4mCWL9OJiHvlHPjcd8zc5Myu89b/7wZDnOSjFgeWRtw==
-
-postcss-load-config@^3.0.0:
- version "3.1.4"
- resolved "https://registry.yarnpkg.com/postcss-load-config/-/postcss-load-config-3.1.4.tgz#1ab2571faf84bb078877e1d07905eabe9ebda855"
- integrity sha512-6DiM4E7v4coTE4uzA8U//WhtPwyhiim3eyjEMFCnUpzbrkK9wJHgKDT2mR+HbtSrd/NubVaYTOpSpjUl8NQeRg==
- dependencies:
- lilconfig "^2.0.5"
- yaml "^1.10.2"
-
-postcss-merge-longhand@^5.1.7:
- version "5.1.7"
- resolved "https://registry.yarnpkg.com/postcss-merge-longhand/-/postcss-merge-longhand-5.1.7.tgz#24a1bdf402d9ef0e70f568f39bdc0344d568fb16"
- integrity sha512-YCI9gZB+PLNskrK0BB3/2OzPnGhPkBEwmwhfYk1ilBHYVAZB7/tkTHFBAnCrvBBOmeYyMYw3DMjT55SyxMBzjQ==
- dependencies:
- postcss-value-parser "^4.2.0"
- stylehacks "^5.1.1"
-
-postcss-merge-rules@^5.1.4:
- version "5.1.4"
- resolved "https://registry.yarnpkg.com/postcss-merge-rules/-/postcss-merge-rules-5.1.4.tgz#2f26fa5cacb75b1402e213789f6766ae5e40313c"
- integrity sha512-0R2IuYpgU93y9lhVbO/OylTtKMVcHb67zjWIfCiKR9rWL3GUk1677LAqD/BcHizukdZEjT8Ru3oHRoAYoJy44g==
- dependencies:
- browserslist "^4.21.4"
- caniuse-api "^3.0.0"
- cssnano-utils "^3.1.0"
- postcss-selector-parser "^6.0.5"
-
-postcss-minify-font-values@^5.1.0:
- version "5.1.0"
- resolved "https://registry.yarnpkg.com/postcss-minify-font-values/-/postcss-minify-font-values-5.1.0.tgz#f1df0014a726083d260d3bd85d7385fb89d1f01b"
- integrity sha512-el3mYTgx13ZAPPirSVsHqFzl+BBBDrXvbySvPGFnQcTI4iNslrPaFq4muTkLZmKlGk4gyFAYUBMH30+HurREyA==
- dependencies:
- postcss-value-parser "^4.2.0"
-
-postcss-minify-gradients@^5.1.1:
- version "5.1.1"
- resolved "https://registry.yarnpkg.com/postcss-minify-gradients/-/postcss-minify-gradients-5.1.1.tgz#f1fe1b4f498134a5068240c2f25d46fcd236ba2c"
- integrity sha512-VGvXMTpCEo4qHTNSa9A0a3D+dxGFZCYwR6Jokk+/3oB6flu2/PnPXAh2x7x52EkY5xlIHLm+Le8tJxe/7TNhzw==
- dependencies:
- colord "^2.9.1"
- cssnano-utils "^3.1.0"
- postcss-value-parser "^4.2.0"
-
-postcss-minify-params@^5.1.4:
- version "5.1.4"
- resolved "https://registry.yarnpkg.com/postcss-minify-params/-/postcss-minify-params-5.1.4.tgz#c06a6c787128b3208b38c9364cfc40c8aa5d7352"
- integrity sha512-+mePA3MgdmVmv6g+30rn57USjOGSAyuxUmkfiWpzalZ8aiBkdPYjXWtHuwJGm1v5Ojy0Z0LaSYhHaLJQB0P8Jw==
- dependencies:
- browserslist "^4.21.4"
- cssnano-utils "^3.1.0"
- postcss-value-parser "^4.2.0"
-
-postcss-minify-selectors@^5.2.1:
- version "5.2.1"
- resolved "https://registry.yarnpkg.com/postcss-minify-selectors/-/postcss-minify-selectors-5.2.1.tgz#d4e7e6b46147b8117ea9325a915a801d5fe656c6"
- integrity sha512-nPJu7OjZJTsVUmPdm2TcaiohIwxP+v8ha9NehQ2ye9szv4orirRU3SDdtUmKH+10nzn0bAyOXZ0UEr7OpvLehg==
- dependencies:
- postcss-selector-parser "^6.0.5"
-
-postcss-modules-extract-imports@^3.0.0:
- version "3.1.0"
- resolved "https://registry.yarnpkg.com/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.1.0.tgz#b4497cb85a9c0c4b5aabeb759bb25e8d89f15002"
- integrity sha512-k3kNe0aNFQDAZGbin48pL2VNidTF0w4/eASDsxlyspobzU3wZQLOGj7L9gfRe0Jo9/4uud09DsjFNH7winGv8Q==
-
-postcss-modules-local-by-default@^4.0.0:
- version "4.0.5"
- resolved "https://registry.yarnpkg.com/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.5.tgz#f1b9bd757a8edf4d8556e8d0f4f894260e3df78f"
- integrity sha512-6MieY7sIfTK0hYfafw1OMEG+2bg8Q1ocHCpoWLqOKj3JXlKu4G7btkmM/B7lFubYkYWmRSPLZi5chid63ZaZYw==
- dependencies:
- icss-utils "^5.0.0"
- postcss-selector-parser "^6.0.2"
- postcss-value-parser "^4.1.0"
-
-postcss-modules-scope@^3.0.0:
- version "3.2.0"
- resolved "https://registry.yarnpkg.com/postcss-modules-scope/-/postcss-modules-scope-3.2.0.tgz#a43d28289a169ce2c15c00c4e64c0858e43457d5"
- integrity sha512-oq+g1ssrsZOsx9M96c5w8laRmvEu9C3adDSjI8oTcbfkrTE8hx/zfyobUoWIxaKPO8bt6S62kxpw5GqypEw1QQ==
- dependencies:
- postcss-selector-parser "^6.0.4"
-
-postcss-modules-values@^4.0.0:
- version "4.0.0"
- resolved "https://registry.yarnpkg.com/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz#d7c5e7e68c3bb3c9b27cbf48ca0bb3ffb4602c9c"
- integrity sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==
- dependencies:
- icss-utils "^5.0.0"
-
-postcss-modules@^4.0.0:
- version "4.3.1"
- resolved "https://registry.yarnpkg.com/postcss-modules/-/postcss-modules-4.3.1.tgz#517c06c09eab07d133ae0effca2c510abba18048"
- integrity sha512-ItUhSUxBBdNamkT3KzIZwYNNRFKmkJrofvC2nWab3CPKhYBQ1f27XXh1PAPE27Psx58jeelPsxWB/+og+KEH0Q==
- dependencies:
- generic-names "^4.0.0"
- icss-replace-symbols "^1.1.0"
- lodash.camelcase "^4.3.0"
- postcss-modules-extract-imports "^3.0.0"
- postcss-modules-local-by-default "^4.0.0"
- postcss-modules-scope "^3.0.0"
- postcss-modules-values "^4.0.0"
- string-hash "^1.1.1"
-
-postcss-normalize-charset@^5.1.0:
- version "5.1.0"
- resolved "https://registry.yarnpkg.com/postcss-normalize-charset/-/postcss-normalize-charset-5.1.0.tgz#9302de0b29094b52c259e9b2cf8dc0879879f0ed"
- integrity sha512-mSgUJ+pd/ldRGVx26p2wz9dNZ7ji6Pn8VWBajMXFf8jk7vUoSrZ2lt/wZR7DtlZYKesmZI680qjr2CeFF2fbUg==
-
-postcss-normalize-display-values@^5.1.0:
- version "5.1.0"
- resolved "https://registry.yarnpkg.com/postcss-normalize-display-values/-/postcss-normalize-display-values-5.1.0.tgz#72abbae58081960e9edd7200fcf21ab8325c3da8"
- integrity sha512-WP4KIM4o2dazQXWmFaqMmcvsKmhdINFblgSeRgn8BJ6vxaMyaJkwAzpPpuvSIoG/rmX3M+IrRZEz2H0glrQNEA==
- dependencies:
- postcss-value-parser "^4.2.0"
-
-postcss-normalize-positions@^5.1.1:
- version "5.1.1"
- resolved "https://registry.yarnpkg.com/postcss-normalize-positions/-/postcss-normalize-positions-5.1.1.tgz#ef97279d894087b59325b45c47f1e863daefbb92"
- integrity sha512-6UpCb0G4eofTCQLFVuI3EVNZzBNPiIKcA1AKVka+31fTVySphr3VUgAIULBhxZkKgwLImhzMR2Bw1ORK+37INg==
- dependencies:
- postcss-value-parser "^4.2.0"
-
-postcss-normalize-repeat-style@^5.1.1:
- version "5.1.1"
- resolved "https://registry.yarnpkg.com/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-5.1.1.tgz#e9eb96805204f4766df66fd09ed2e13545420fb2"
- integrity sha512-mFpLspGWkQtBcWIRFLmewo8aC3ImN2i/J3v8YCFUwDnPu3Xz4rLohDO26lGjwNsQxB3YF0KKRwspGzE2JEuS0g==
- dependencies:
- postcss-value-parser "^4.2.0"
-
-postcss-normalize-string@^5.1.0:
- version "5.1.0"
- resolved "https://registry.yarnpkg.com/postcss-normalize-string/-/postcss-normalize-string-5.1.0.tgz#411961169e07308c82c1f8c55f3e8a337757e228"
- integrity sha512-oYiIJOf4T9T1N4i+abeIc7Vgm/xPCGih4bZz5Nm0/ARVJ7K6xrDlLwvwqOydvyL3RHNf8qZk6vo3aatiw/go3w==
- dependencies:
- postcss-value-parser "^4.2.0"
-
-postcss-normalize-timing-functions@^5.1.0:
- version "5.1.0"
- resolved "https://registry.yarnpkg.com/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-5.1.0.tgz#d5614410f8f0b2388e9f240aa6011ba6f52dafbb"
- integrity sha512-DOEkzJ4SAXv5xkHl0Wa9cZLF3WCBhF3o1SKVxKQAa+0pYKlueTpCgvkFAHfk+Y64ezX9+nITGrDZeVGgITJXjg==
- dependencies:
- postcss-value-parser "^4.2.0"
-
-postcss-normalize-unicode@^5.1.1:
- version "5.1.1"
- resolved "https://registry.yarnpkg.com/postcss-normalize-unicode/-/postcss-normalize-unicode-5.1.1.tgz#f67297fca3fea7f17e0d2caa40769afc487aa030"
- integrity sha512-qnCL5jzkNUmKVhZoENp1mJiGNPcsJCs1aaRmURmeJGES23Z/ajaln+EPTD+rBeNkSryI+2WTdW+lwcVdOikrpA==
- dependencies:
- browserslist "^4.21.4"
- postcss-value-parser "^4.2.0"
-
-postcss-normalize-url@^5.1.0:
- version "5.1.0"
- resolved "https://registry.yarnpkg.com/postcss-normalize-url/-/postcss-normalize-url-5.1.0.tgz#ed9d88ca82e21abef99f743457d3729a042adcdc"
- integrity sha512-5upGeDO+PVthOxSmds43ZeMeZfKH+/DKgGRD7TElkkyS46JXAUhMzIKiCa7BabPeIy3AQcTkXwVVN7DbqsiCew==
- dependencies:
- normalize-url "^6.0.1"
- postcss-value-parser "^4.2.0"
-
-postcss-normalize-whitespace@^5.1.1:
- version "5.1.1"
- resolved "https://registry.yarnpkg.com/postcss-normalize-whitespace/-/postcss-normalize-whitespace-5.1.1.tgz#08a1a0d1ffa17a7cc6efe1e6c9da969cc4493cfa"
- integrity sha512-83ZJ4t3NUDETIHTa3uEg6asWjSBYL5EdkVB0sDncx9ERzOKBVJIUeDO9RyA9Zwtig8El1d79HBp0JEi8wvGQnA==
- dependencies:
- postcss-value-parser "^4.2.0"
-
-postcss-ordered-values@^5.1.3:
- version "5.1.3"
- resolved "https://registry.yarnpkg.com/postcss-ordered-values/-/postcss-ordered-values-5.1.3.tgz#b6fd2bd10f937b23d86bc829c69e7732ce76ea38"
- integrity sha512-9UO79VUhPwEkzbb3RNpqqghc6lcYej1aveQteWY+4POIwlqkYE21HKWaLDF6lWNuqCobEAyTovVhtI32Rbv2RQ==
- dependencies:
- cssnano-utils "^3.1.0"
- postcss-value-parser "^4.2.0"
-
-postcss-reduce-initial@^5.1.2:
- version "5.1.2"
- resolved "https://registry.yarnpkg.com/postcss-reduce-initial/-/postcss-reduce-initial-5.1.2.tgz#798cd77b3e033eae7105c18c9d371d989e1382d6"
- integrity sha512-dE/y2XRaqAi6OvjzD22pjTUQ8eOfc6m/natGHgKFBK9DxFmIm69YmaRVQrGgFlEfc1HePIurY0TmDeROK05rIg==
- dependencies:
- browserslist "^4.21.4"
- caniuse-api "^3.0.0"
-
-postcss-reduce-transforms@^5.1.0:
- version "5.1.0"
- resolved "https://registry.yarnpkg.com/postcss-reduce-transforms/-/postcss-reduce-transforms-5.1.0.tgz#333b70e7758b802f3dd0ddfe98bb1ccfef96b6e9"
- integrity sha512-2fbdbmgir5AvpW9RLtdONx1QoYG2/EtqpNQbFASDlixBbAYuTcJ0dECwlqNqH7VbaUnEnh8SrxOe2sRIn24XyQ==
- dependencies:
- postcss-value-parser "^4.2.0"
-
-postcss-selector-parser@^6.0.2, postcss-selector-parser@^6.0.4, postcss-selector-parser@^6.0.5, postcss-selector-parser@^6.0.9:
- version "6.1.2"
- resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz#27ecb41fb0e3b6ba7a1ec84fff347f734c7929de"
- integrity sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==
- dependencies:
- cssesc "^3.0.0"
- util-deprecate "^1.0.2"
-
-postcss-svgo@^5.1.0:
- version "5.1.0"
- resolved "https://registry.yarnpkg.com/postcss-svgo/-/postcss-svgo-5.1.0.tgz#0a317400ced789f233a28826e77523f15857d80d"
- integrity sha512-D75KsH1zm5ZrHyxPakAxJWtkyXew5qwS70v56exwvw542d9CRtTo78K0WeFxZB4G7JXKKMbEZtZayTGdIky/eA==
- dependencies:
- postcss-value-parser "^4.2.0"
- svgo "^2.7.0"
-
-postcss-unique-selectors@^5.1.1:
- version "5.1.1"
- resolved "https://registry.yarnpkg.com/postcss-unique-selectors/-/postcss-unique-selectors-5.1.1.tgz#a9f273d1eacd09e9aa6088f4b0507b18b1b541b6"
- integrity sha512-5JiODlELrz8L2HwxfPnhOWZYWDxVHWL83ufOv84NrcgipI7TaeRsatAhK4Tr2/ZiYldpK/wBvw5BD3qfaK96GA==
- dependencies:
- postcss-selector-parser "^6.0.5"
-
-postcss-value-parser@^4.1.0, postcss-value-parser@^4.2.0:
- version "4.2.0"
- resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz#723c09920836ba6d3e5af019f92bc0971c02e514"
- integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==
-
-postcss@^8.4.47:
- version "8.4.47"
- resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.47.tgz#5bf6c9a010f3e724c503bf03ef7947dcb0fea365"
- integrity sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ==
- dependencies:
- nanoid "^3.3.7"
- picocolors "^1.1.0"
- source-map-js "^1.2.1"
-
-prelude-ls@^1.2.1:
- version "1.2.1"
- resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396"
- integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==
-
-pretty-format@^29.7.0:
- version "29.7.0"
- resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-29.7.0.tgz#ca42c758310f365bfa71a0bda0a807160b776812"
- integrity sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==
- dependencies:
- "@jest/schemas" "^29.6.3"
- ansi-styles "^5.0.0"
- react-is "^18.0.0"
-
-promise.series@^0.2.0:
- version "0.2.0"
- resolved "https://registry.yarnpkg.com/promise.series/-/promise.series-0.2.0.tgz#2cc7ebe959fc3a6619c04ab4dbdc9e452d864bbd"
- integrity sha512-VWQJyU2bcDTgZw8kpfBpB/ejZASlCrzwz5f2hjb/zlujOEB4oeiAhHygAWq8ubsX2GVkD4kCU5V2dwOTaCY5EQ==
-
-prompts@^2.0.1:
- version "2.4.2"
- resolved "https://registry.yarnpkg.com/prompts/-/prompts-2.4.2.tgz#7b57e73b3a48029ad10ebd44f74b01722a4cb069"
- integrity sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==
- dependencies:
- kleur "^3.0.3"
- sisteransi "^1.0.5"
-
-punycode@^2.1.0:
- version "2.3.1"
- resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.1.tgz#027422e2faec0b25e1549c3e1bd8309b9133b6e5"
- integrity sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==
-
-pure-rand@^6.0.0:
- version "6.1.0"
- resolved "https://registry.yarnpkg.com/pure-rand/-/pure-rand-6.1.0.tgz#d173cf23258231976ccbdb05247c9787957604f2"
- integrity sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA==
-
-queue-microtask@^1.2.2:
- version "1.2.3"
- resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243"
- integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==
-
-randombytes@^2.1.0:
- version "2.1.0"
- resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a"
- integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==
- dependencies:
- safe-buffer "^5.1.0"
-
-range-parser@1.2.0:
- version "1.2.0"
- resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.0.tgz#f49be6b487894ddc40dcc94a322f611092e00d5e"
- integrity sha512-kA5WQoNVo4t9lNx2kQNFCxKeBl5IbbSNBl1M/tLkw9WCn+hxNBAW5Qh8gdhs63CJnhjJ2zQWFoqPJP2sK1AV5A==
-
-rc@^1.0.1, rc@^1.1.6:
- version "1.2.8"
- resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed"
- integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==
- dependencies:
- deep-extend "^0.6.0"
- ini "~1.3.0"
- minimist "^1.2.0"
- strip-json-comments "~2.0.1"
-
-react-is@^18.0.0:
- version "18.3.1"
- resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.3.1.tgz#e83557dc12eae63a99e003a46388b1dcbb44db7e"
- integrity sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==
-
-readdirp@^4.0.1:
- version "4.0.2"
- resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-4.0.2.tgz#388fccb8b75665da3abffe2d8f8ed59fe74c230a"
- integrity sha512-yDMz9g+VaZkqBYS/ozoBJwaBhTbZo3UNYQHNRw1D3UFQB8oHB4uS/tAODO+ZLjGWmUbKnIlOWO+aaIiAxrUWHA==
-
-refa@^0.12.0, refa@^0.12.1:
- version "0.12.1"
- resolved "https://registry.yarnpkg.com/refa/-/refa-0.12.1.tgz#dac13c4782dc22b6bae6cce81a2b863888ea39c6"
- integrity sha512-J8rn6v4DBb2nnFqkqwy6/NnTYMcgLA+sLr0iIO41qpv0n+ngb7ksag2tMRl0inb1bbO/esUwzW1vbJi7K0sI0g==
- dependencies:
- "@eslint-community/regexpp" "^4.8.0"
-
-regenerator-runtime@^0.14.0:
- version "0.14.1"
- resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz#356ade10263f685dda125100cd862c1db895327f"
- integrity sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==
-
-regexp-ast-analysis@^0.7.0, regexp-ast-analysis@^0.7.1:
- version "0.7.1"
- resolved "https://registry.yarnpkg.com/regexp-ast-analysis/-/regexp-ast-analysis-0.7.1.tgz#c0e24cb2a90f6eadd4cbaaba129317e29d29c482"
- integrity sha512-sZuz1dYW/ZsfG17WSAG7eS85r5a0dDsvg+7BiiYR5o6lKCAtUrEwdmRmaGF6rwVj3LcmAeYkOWKEPlbPzN3Y3A==
- dependencies:
- "@eslint-community/regexpp" "^4.8.0"
- refa "^0.12.1"
-
-regexp.prototype.flags@^1.5.2:
- version "1.5.3"
- resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.5.3.tgz#b3ae40b1d2499b8350ab2c3fe6ef3845d3a96f42"
- integrity sha512-vqlC04+RQoFalODCbCumG2xIOvapzVMHwsyIGM/SIE8fRhFFsXeH8/QQ+s0T0kDAhKc4k30s73/0ydkHQz6HlQ==
- dependencies:
- call-bind "^1.0.7"
- define-properties "^1.2.1"
- es-errors "^1.3.0"
- set-function-name "^2.0.2"
-
-registry-auth-token@3.3.2:
- version "3.3.2"
- resolved "https://registry.yarnpkg.com/registry-auth-token/-/registry-auth-token-3.3.2.tgz#851fd49038eecb586911115af845260eec983f20"
- integrity sha512-JL39c60XlzCVgNrO+qq68FoNb56w/m7JYvGR2jT5iR1xBrUA3Mfx5Twk5rqTThPmQKMWydGmq8oFtDlxfrmxnQ==
- dependencies:
- rc "^1.1.6"
- safe-buffer "^5.0.1"
-
-registry-url@3.1.0:
- version "3.1.0"
- resolved "https://registry.yarnpkg.com/registry-url/-/registry-url-3.1.0.tgz#3d4ef870f73dde1d77f0cf9a381432444e174942"
- integrity sha512-ZbgR5aZEdf4UKZVBPYIgaglBmSF2Hi94s2PcIHhRGFjKYu+chjJdYfHn4rt3hB6eCKLJ8giVIIfgMa1ehDfZKA==
- dependencies:
- rc "^1.0.1"
-
-require-directory@^2.1.1:
- version "2.1.1"
- resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42"
- integrity sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==
-
-require-from-string@^2.0.2:
- version "2.0.2"
- resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909"
- integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==
-
-resolve-cwd@^3.0.0:
- version "3.0.0"
- resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-3.0.0.tgz#0f0075f1bb2544766cf73ba6a6e2adfebcb13f2d"
- integrity sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==
- dependencies:
- resolve-from "^5.0.0"
-
-resolve-from@^4.0.0:
- version "4.0.0"
- resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6"
- integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==
-
-resolve-from@^5.0.0:
- version "5.0.0"
- resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69"
- integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==
-
-resolve.exports@^2.0.0:
- version "2.0.2"
- resolved "https://registry.yarnpkg.com/resolve.exports/-/resolve.exports-2.0.2.tgz#f8c934b8e6a13f539e38b7098e2e36134f01e800"
- integrity sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg==
-
-resolve@^1.19.0, resolve@^1.20.0, resolve@^1.22.1, resolve@^1.22.4:
- version "1.22.8"
- resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.8.tgz#b6c87a9f2aa06dfab52e3d70ac8cde321fa5a48d"
- integrity sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==
- dependencies:
- is-core-module "^2.13.0"
- path-parse "^1.0.7"
- supports-preserve-symlinks-flag "^1.0.0"
-
-reusify@^1.0.4:
- version "1.0.4"
- resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76"
- integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==
-
-rimraf@^3.0.2:
- version "3.0.2"
- resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a"
- integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==
- dependencies:
- glob "^7.1.3"
-
-rollup-plugin-postcss@^4.0.2:
- version "4.0.2"
- resolved "https://registry.yarnpkg.com/rollup-plugin-postcss/-/rollup-plugin-postcss-4.0.2.tgz#15e9462f39475059b368ce0e49c800fa4b1f7050"
- integrity sha512-05EaY6zvZdmvPUDi3uCcAQoESDcYnv8ogJJQRp6V5kZ6J6P7uAVJlrTZcaaA20wTH527YTnKfkAoPxWI/jPp4w==
- dependencies:
- chalk "^4.1.0"
- concat-with-sourcemaps "^1.1.0"
- cssnano "^5.0.1"
- import-cwd "^3.0.0"
- p-queue "^6.6.2"
- pify "^5.0.0"
- postcss-load-config "^3.0.0"
- postcss-modules "^4.0.0"
- promise.series "^0.2.0"
- resolve "^1.19.0"
- rollup-pluginutils "^2.8.2"
- safe-identifier "^0.4.2"
- style-inject "^0.3.0"
-
-rollup-plugin-visualizer@^5.12.0:
- version "5.12.0"
- resolved "https://registry.yarnpkg.com/rollup-plugin-visualizer/-/rollup-plugin-visualizer-5.12.0.tgz#661542191ce78ee4f378995297260d0c1efb1302"
- integrity sha512-8/NU9jXcHRs7Nnj07PF2o4gjxmm9lXIrZ8r175bT9dK8qoLlvKTwRMArRCMgpMGlq8CTLugRvEmyMeMXIU2pNQ==
- dependencies:
- open "^8.4.0"
- picomatch "^2.3.1"
- source-map "^0.7.4"
- yargs "^17.5.1"
-
-rollup-pluginutils@^2.8.2:
- version "2.8.2"
- resolved "https://registry.yarnpkg.com/rollup-pluginutils/-/rollup-pluginutils-2.8.2.tgz#72f2af0748b592364dbd3389e600e5a9444a351e"
- integrity sha512-EEp9NhnUkwY8aif6bxgovPHMoMoNr2FulJziTndpt5H9RdwC47GSGuII9XxpSdzVGM0GWrNPHV6ie1LTNJPaLQ==
- dependencies:
- estree-walker "^0.6.1"
-
-rollup@^4.23.0:
- version "4.24.0"
- resolved "https://registry.yarnpkg.com/rollup/-/rollup-4.24.0.tgz#c14a3576f20622ea6a5c9cad7caca5e6e9555d05"
- integrity sha512-DOmrlGSXNk1DM0ljiQA+i+o0rSLhtii1je5wgk60j49d1jHT5YYttBv1iWOnYSTG+fZZESUOSNiAl89SIet+Cg==
- dependencies:
- "@types/estree" "1.0.6"
- optionalDependencies:
- "@rollup/rollup-android-arm-eabi" "4.24.0"
- "@rollup/rollup-android-arm64" "4.24.0"
- "@rollup/rollup-darwin-arm64" "4.24.0"
- "@rollup/rollup-darwin-x64" "4.24.0"
- "@rollup/rollup-linux-arm-gnueabihf" "4.24.0"
- "@rollup/rollup-linux-arm-musleabihf" "4.24.0"
- "@rollup/rollup-linux-arm64-gnu" "4.24.0"
- "@rollup/rollup-linux-arm64-musl" "4.24.0"
- "@rollup/rollup-linux-powerpc64le-gnu" "4.24.0"
- "@rollup/rollup-linux-riscv64-gnu" "4.24.0"
- "@rollup/rollup-linux-s390x-gnu" "4.24.0"
- "@rollup/rollup-linux-x64-gnu" "4.24.0"
- "@rollup/rollup-linux-x64-musl" "4.24.0"
- "@rollup/rollup-win32-arm64-msvc" "4.24.0"
- "@rollup/rollup-win32-ia32-msvc" "4.24.0"
- "@rollup/rollup-win32-x64-msvc" "4.24.0"
- fsevents "~2.3.2"
-
-run-parallel@^1.1.9:
- version "1.2.0"
- resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee"
- integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==
- dependencies:
- queue-microtask "^1.2.2"
-
-rxjs@^7.8.1:
- version "7.8.1"
- resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-7.8.1.tgz#6f6f3d99ea8044291efd92e7c7fcf562c4057543"
- integrity sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==
- dependencies:
- tslib "^2.1.0"
-
-safe-array-concat@^1.1.2:
- version "1.1.2"
- resolved "https://registry.yarnpkg.com/safe-array-concat/-/safe-array-concat-1.1.2.tgz#81d77ee0c4e8b863635227c721278dd524c20edb"
- integrity sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==
- dependencies:
- call-bind "^1.0.7"
- get-intrinsic "^1.2.4"
- has-symbols "^1.0.3"
- isarray "^2.0.5"
-
-safe-buffer@5.1.2:
- version "5.1.2"
- resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d"
- integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==
-
-safe-buffer@^5.0.1, safe-buffer@^5.1.0:
- version "5.2.1"
- resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6"
- integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==
-
-safe-identifier@^0.4.2:
- version "0.4.2"
- resolved "https://registry.yarnpkg.com/safe-identifier/-/safe-identifier-0.4.2.tgz#cf6bfca31c2897c588092d1750d30ef501d59fcb"
- integrity sha512-6pNbSMW6OhAi9j+N8V+U715yBQsaWJ7eyEUaOrawX+isg5ZxhUlV1NipNtgaKHmFGiABwt+ZF04Ii+3Xjkg+8w==
-
-safe-regex-test@^1.0.3:
- version "1.0.3"
- resolved "https://registry.yarnpkg.com/safe-regex-test/-/safe-regex-test-1.0.3.tgz#a5b4c0f06e0ab50ea2c395c14d8371232924c377"
- integrity sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==
- dependencies:
- call-bind "^1.0.6"
- es-errors "^1.3.0"
- is-regex "^1.1.4"
-
-sass@^1.79.4:
- version "1.80.3"
- resolved "https://registry.yarnpkg.com/sass/-/sass-1.80.3.tgz#3f63dd527647d2b3de35f36acb971bda80517423"
- integrity sha512-ptDWyVmDMVielpz/oWy3YP3nfs7LpJTHIJZboMVs8GEC9eUmtZTZhMHlTW98wY4aEorDfjN38+Wr/XjskFWcfA==
- dependencies:
- "@parcel/watcher" "^2.4.1"
- chokidar "^4.0.0"
- immutable "^4.0.0"
- source-map-js ">=0.6.2 <2.0.0"
-
-scslre@^0.3.0:
- version "0.3.0"
- resolved "https://registry.yarnpkg.com/scslre/-/scslre-0.3.0.tgz#c3211e9bfc5547fc86b1eabaa34ed1a657060155"
- integrity sha512-3A6sD0WYP7+QrjbfNA2FN3FsOaGGFoekCVgTyypy53gPxhbkCIjtO6YWgdrfM+n/8sI8JeXZOIxsHjMTNxQ4nQ==
- dependencies:
- "@eslint-community/regexpp" "^4.8.0"
- refa "^0.12.0"
- regexp-ast-analysis "^0.7.0"
-
-semver@^6.3.0, semver@^6.3.1:
- version "6.3.1"
- resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4"
- integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==
-
-semver@^7.5.3, semver@^7.5.4, semver@^7.6.0:
- version "7.6.3"
- resolved "https://registry.yarnpkg.com/semver/-/semver-7.6.3.tgz#980f7b5550bc175fb4dc09403085627f9eb33143"
- integrity sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==
-
-serialize-javascript@^6.0.1:
- version "6.0.2"
- resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.2.tgz#defa1e055c83bf6d59ea805d8da862254eb6a6c2"
- integrity sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==
- dependencies:
- randombytes "^2.1.0"
-
-serve-handler@6.1.6:
- version "6.1.6"
- resolved "https://registry.yarnpkg.com/serve-handler/-/serve-handler-6.1.6.tgz#50803c1d3e947cd4a341d617f8209b22bd76cfa1"
- integrity sha512-x5RL9Y2p5+Sh3D38Fh9i/iQ5ZK+e4xuXRd/pGbM4D13tgo/MGwbttUk8emytcr1YYzBYs+apnUngBDFYfpjPuQ==
- dependencies:
- bytes "3.0.0"
- content-disposition "0.5.2"
- mime-types "2.1.18"
- minimatch "3.1.2"
- path-is-inside "1.0.2"
- path-to-regexp "3.3.0"
- range-parser "1.2.0"
-
-serve@^14.2.3:
- version "14.2.4"
- resolved "https://registry.yarnpkg.com/serve/-/serve-14.2.4.tgz#ba4c425c3c965f496703762e808f34b913f42fb0"
- integrity sha512-qy1S34PJ/fcY8gjVGszDB3EXiPSk5FKhUa7tQe0UPRddxRidc2V6cNHPNewbE1D7MAkgLuWEt3Vw56vYy73tzQ==
- dependencies:
- "@zeit/schemas" "2.36.0"
- ajv "8.12.0"
- arg "5.0.2"
- boxen "7.0.0"
- chalk "5.0.1"
- chalk-template "0.4.0"
- clipboardy "3.0.0"
- compression "1.7.4"
- is-port-reachable "4.0.0"
- serve-handler "6.1.6"
- update-check "1.5.4"
-
-set-function-length@^1.2.1:
- version "1.2.2"
- resolved "https://registry.yarnpkg.com/set-function-length/-/set-function-length-1.2.2.tgz#aac72314198eaed975cf77b2c3b6b880695e5449"
- integrity sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==
- dependencies:
- define-data-property "^1.1.4"
- es-errors "^1.3.0"
- function-bind "^1.1.2"
- get-intrinsic "^1.2.4"
- gopd "^1.0.1"
- has-property-descriptors "^1.0.2"
-
-set-function-name@^2.0.2:
- version "2.0.2"
- resolved "https://registry.yarnpkg.com/set-function-name/-/set-function-name-2.0.2.tgz#16a705c5a0dc2f5e638ca96d8a8cd4e1c2b90985"
- integrity sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==
- dependencies:
- define-data-property "^1.1.4"
- es-errors "^1.3.0"
- functions-have-names "^1.2.3"
- has-property-descriptors "^1.0.2"
-
-shebang-command@^2.0.0:
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea"
- integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==
- dependencies:
- shebang-regex "^3.0.0"
-
-shebang-regex@^3.0.0:
- version "3.0.0"
- resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172"
- integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==
-
-shell-quote@^1.8.1:
- version "1.8.1"
- resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.8.1.tgz#6dbf4db75515ad5bac63b4f1894c3a154c766680"
- integrity sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==
-
-side-channel@^1.0.4:
- version "1.0.6"
- resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.6.tgz#abd25fb7cd24baf45466406b1096b7831c9215f2"
- integrity sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==
- dependencies:
- call-bind "^1.0.7"
- es-errors "^1.3.0"
- get-intrinsic "^1.2.4"
- object-inspect "^1.13.1"
-
-signal-exit@^3.0.3, signal-exit@^3.0.7:
- version "3.0.7"
- resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9"
- integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==
-
-sisteransi@^1.0.5:
- version "1.0.5"
- resolved "https://registry.yarnpkg.com/sisteransi/-/sisteransi-1.0.5.tgz#134d681297756437cc05ca01370d3a7a571075ed"
- integrity sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==
-
-slash@^3.0.0:
- version "3.0.0"
- resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634"
- integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==
-
-smob@^1.0.0:
- version "1.5.0"
- resolved "https://registry.yarnpkg.com/smob/-/smob-1.5.0.tgz#85d79a1403abf128d24d3ebc1cdc5e1a9548d3ab"
- integrity sha512-g6T+p7QO8npa+/hNx9ohv1E5pVCmWrVCUzUXJyLdMmftX6ER0oiWY/w9knEonLpnOp6b6FenKnMfR8gqwWdwig==
-
-"source-map-js@>=0.6.2 <2.0.0", source-map-js@^1.2.1:
- version "1.2.1"
- resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.2.1.tgz#1ce5650fddd87abc099eda37dcff024c2667ae46"
- integrity sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==
-
-source-map-support@0.5.13:
- version "0.5.13"
- resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.13.tgz#31b24a9c2e73c2de85066c0feb7d44767ed52932"
- integrity sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==
- dependencies:
- buffer-from "^1.0.0"
- source-map "^0.6.0"
-
-source-map-support@~0.5.20:
- version "0.5.21"
- resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f"
- integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==
- dependencies:
- buffer-from "^1.0.0"
- source-map "^0.6.0"
-
-source-map@^0.6.0, source-map@^0.6.1:
- version "0.6.1"
- resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263"
- integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==
-
-source-map@^0.7.4:
- version "0.7.4"
- resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.4.tgz#a9bbe705c9d8846f4e08ff6765acf0f1b0898656"
- integrity sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==
-
-spdx-exceptions@^2.1.0:
- version "2.5.0"
- resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz#5d607d27fc806f66d7b64a766650fa890f04ed66"
- integrity sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==
-
-spdx-expression-parse@^4.0.0:
- version "4.0.0"
- resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-4.0.0.tgz#a23af9f3132115465dac215c099303e4ceac5794"
- integrity sha512-Clya5JIij/7C6bRR22+tnGXbc4VKlibKSVj2iHvVeX5iMW7s1SIQlqu699JkODJJIhh/pUu8L0/VLh8xflD+LQ==
- dependencies:
- spdx-exceptions "^2.1.0"
- spdx-license-ids "^3.0.0"
-
-spdx-license-ids@^3.0.0:
- version "3.0.20"
- resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.20.tgz#e44ed19ed318dd1e5888f93325cee800f0f51b89"
- integrity sha512-jg25NiDV/1fLtSgEgyvVyDunvaNHbuwF9lfNV17gSmPFAlYzdfNBlLtLzXTevwkPj7DhGbmN9VnmJIgLnhvaBw==
-
-sprintf-js@~1.0.2:
- version "1.0.3"
- resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c"
- integrity sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==
-
-stable@^0.1.8:
- version "0.1.8"
- resolved "https://registry.yarnpkg.com/stable/-/stable-0.1.8.tgz#836eb3c8382fe2936feaf544631017ce7d47a3cf"
- integrity sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==
-
-stack-utils@^2.0.3:
- version "2.0.6"
- resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-2.0.6.tgz#aaf0748169c02fc33c8232abccf933f54a1cc34f"
- integrity sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==
- dependencies:
- escape-string-regexp "^2.0.0"
-
-string-hash@^1.1.1:
- version "1.1.3"
- resolved "https://registry.yarnpkg.com/string-hash/-/string-hash-1.1.3.tgz#e8aafc0ac1855b4666929ed7dd1275df5d6c811b"
- integrity sha512-kJUvRUFK49aub+a7T1nNE66EJbZBMnBgoC1UbCZ5n6bsZKBRga4KgBRTMn/pFkeCZSYtNeSyMxPDM0AXWELk2A==
-
-string-length@^4.0.1:
- version "4.0.2"
- resolved "https://registry.yarnpkg.com/string-length/-/string-length-4.0.2.tgz#a8a8dc7bd5c1a82b9b3c8b87e125f66871b6e57a"
- integrity sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==
- dependencies:
- char-regex "^1.0.2"
- strip-ansi "^6.0.0"
-
-string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3:
- version "4.2.3"
- resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
- integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
- dependencies:
- emoji-regex "^8.0.0"
- is-fullwidth-code-point "^3.0.0"
- strip-ansi "^6.0.1"
-
-string-width@^5.0.1, string-width@^5.1.2:
- version "5.1.2"
- resolved "https://registry.yarnpkg.com/string-width/-/string-width-5.1.2.tgz#14f8daec6d81e7221d2a357e668cab73bdbca794"
- integrity sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==
- dependencies:
- eastasianwidth "^0.2.0"
- emoji-regex "^9.2.2"
- strip-ansi "^7.0.1"
-
-string.prototype.trim@^1.2.9:
- version "1.2.9"
- resolved "https://registry.yarnpkg.com/string.prototype.trim/-/string.prototype.trim-1.2.9.tgz#b6fa326d72d2c78b6df02f7759c73f8f6274faa4"
- integrity sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==
- dependencies:
- call-bind "^1.0.7"
- define-properties "^1.2.1"
- es-abstract "^1.23.0"
- es-object-atoms "^1.0.0"
-
-string.prototype.trimend@^1.0.8:
- version "1.0.8"
- resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.8.tgz#3651b8513719e8a9f48de7f2f77640b26652b229"
- integrity sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ==
- dependencies:
- call-bind "^1.0.7"
- define-properties "^1.2.1"
- es-object-atoms "^1.0.0"
-
-string.prototype.trimstart@^1.0.8:
- version "1.0.8"
- resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz#7ee834dda8c7c17eff3118472bb35bfedaa34dde"
- integrity sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==
- dependencies:
- call-bind "^1.0.7"
- define-properties "^1.2.1"
- es-object-atoms "^1.0.0"
-
-strip-ansi@^6.0.0, strip-ansi@^6.0.1:
- version "6.0.1"
- resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
- integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
- dependencies:
- ansi-regex "^5.0.1"
-
-strip-ansi@^7.0.1:
- version "7.1.0"
- resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.1.0.tgz#d5b6568ca689d8561370b0707685d22434faff45"
- integrity sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==
- dependencies:
- ansi-regex "^6.0.1"
-
-strip-bom@^3.0.0:
- version "3.0.0"
- resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3"
- integrity sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==
-
-strip-bom@^4.0.0:
- version "4.0.0"
- resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-4.0.0.tgz#9c3505c1db45bcedca3d9cf7a16f5c5aa3901878"
- integrity sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==
-
-strip-final-newline@^2.0.0:
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad"
- integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==
-
-strip-json-comments@^3.1.1:
- version "3.1.1"
- resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006"
- integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==
-
-strip-json-comments@~2.0.1:
- version "2.0.1"
- resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a"
- integrity sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==
-
-style-inject@^0.3.0:
- version "0.3.0"
- resolved "https://registry.yarnpkg.com/style-inject/-/style-inject-0.3.0.tgz#d21c477affec91811cc82355832a700d22bf8dd3"
- integrity sha512-IezA2qp+vcdlhJaVm5SOdPPTUu0FCEqfNSli2vRuSIBbu5Nq5UvygTk/VzeCqfLz2Atj3dVII5QBKGZRZ0edzw==
-
-stylehacks@^5.1.1:
- version "5.1.1"
- resolved "https://registry.yarnpkg.com/stylehacks/-/stylehacks-5.1.1.tgz#7934a34eb59d7152149fa69d6e9e56f2fc34bcc9"
- integrity sha512-sBpcd5Hx7G6seo7b1LkpttvTz7ikD0LlH5RmdcBNb6fFR0Fl7LQwHDFr300q4cwUqi+IYrFGmsIHieMBfnN/Bw==
- dependencies:
- browserslist "^4.21.4"
- postcss-selector-parser "^6.0.4"
-
-supports-color@^5.3.0:
- version "5.5.0"
- resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f"
- integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==
- dependencies:
- has-flag "^3.0.0"
-
-supports-color@^7.1.0:
- version "7.2.0"
- resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da"
- integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==
- dependencies:
- has-flag "^4.0.0"
-
-supports-color@^8.0.0, supports-color@^8.1.1:
- version "8.1.1"
- resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c"
- integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==
- dependencies:
- has-flag "^4.0.0"
-
-supports-preserve-symlinks-flag@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09"
- integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==
-
-svgo@^2.7.0:
- version "2.8.0"
- resolved "https://registry.yarnpkg.com/svgo/-/svgo-2.8.0.tgz#4ff80cce6710dc2795f0c7c74101e6764cfccd24"
- integrity sha512-+N/Q9kV1+F+UeWYoSiULYo4xYSDQlTgb+ayMobAXPwMnLvop7oxKMo9OzIrX5x3eS4L4f2UHhc9axXwY8DpChg==
- dependencies:
- "@trysound/sax" "0.2.0"
- commander "^7.2.0"
- css-select "^4.1.3"
- css-tree "^1.1.3"
- csso "^4.2.0"
- picocolors "^1.0.0"
- stable "^0.1.8"
-
-terser@^5.17.4:
- version "5.36.0"
- resolved "https://registry.yarnpkg.com/terser/-/terser-5.36.0.tgz#8b0dbed459ac40ff7b4c9fd5a3a2029de105180e"
- integrity sha512-IYV9eNMuFAV4THUspIRXkLakHnV6XO7FEdtKjf/mDyrnqUg9LnlOn6/RwRvM9SZjR4GUq8Nk8zj67FzVARr74w==
- dependencies:
- "@jridgewell/source-map" "^0.3.3"
- acorn "^8.8.2"
- commander "^2.20.0"
- source-map-support "~0.5.20"
-
-test-exclude@^6.0.0:
- version "6.0.0"
- resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-6.0.0.tgz#04a8698661d805ea6fa293b6cb9e63ac044ef15e"
- integrity sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==
- dependencies:
- "@istanbuljs/schema" "^0.1.2"
- glob "^7.1.4"
- minimatch "^3.0.4"
-
-text-table@^0.2.0:
- version "0.2.0"
- resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4"
- integrity sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==
-
-tmpl@1.0.5:
- version "1.0.5"
- resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.5.tgz#8683e0b902bb9c20c4f726e3c0b69f36518c07cc"
- integrity sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==
-
-to-fast-properties@^2.0.0:
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e"
- integrity sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==
-
-to-regex-range@^5.0.1:
- version "5.0.1"
- resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4"
- integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==
- dependencies:
- is-number "^7.0.0"
-
-tree-kill@^1.2.2:
- version "1.2.2"
- resolved "https://registry.yarnpkg.com/tree-kill/-/tree-kill-1.2.2.tgz#4ca09a9092c88b73a7cdc5e8a01b507b0790a0cc"
- integrity sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==
-
-ts-api-utils@^1.3.0:
- version "1.3.0"
- resolved "https://registry.yarnpkg.com/ts-api-utils/-/ts-api-utils-1.3.0.tgz#4b490e27129f1e8e686b45cc4ab63714dc60eea1"
- integrity sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==
-
-tsconfig-paths@^3.15.0:
- version "3.15.0"
- resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz#5299ec605e55b1abb23ec939ef15edaf483070d4"
- integrity sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==
- dependencies:
- "@types/json5" "^0.0.29"
- json5 "^1.0.2"
- minimist "^1.2.6"
- strip-bom "^3.0.0"
-
-tslib@^2.1.0, tslib@^2.7.0:
- version "2.8.0"
- resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.8.0.tgz#d124c86c3c05a40a91e6fdea4021bd31d377971b"
- integrity sha512-jWVzBLplnCmoaTr13V9dYbiQ99wvZRd0vNWaDRg+aVYRcjDF3nDksxFDE/+fkXnKhpnUUkmx5pK/v8mCtLVqZA==
-
-type-check@^0.4.0, type-check@~0.4.0:
- version "0.4.0"
- resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1"
- integrity sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==
- dependencies:
- prelude-ls "^1.2.1"
-
-type-detect@4.0.8:
- version "4.0.8"
- resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c"
- integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==
-
-type-fest@^0.20.2:
- version "0.20.2"
- resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4"
- integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==
-
-type-fest@^0.21.3:
- version "0.21.3"
- resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.21.3.tgz#d260a24b0198436e133fa26a524a6d65fa3b2e37"
- integrity sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==
-
-type-fest@^2.13.0:
- version "2.19.0"
- resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-2.19.0.tgz#88068015bb33036a598b952e55e9311a60fd3a9b"
- integrity sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==
-
-typed-array-buffer@^1.0.2:
- version "1.0.2"
- resolved "https://registry.yarnpkg.com/typed-array-buffer/-/typed-array-buffer-1.0.2.tgz#1867c5d83b20fcb5ccf32649e5e2fc7424474ff3"
- integrity sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==
- dependencies:
- call-bind "^1.0.7"
- es-errors "^1.3.0"
- is-typed-array "^1.1.13"
-
-typed-array-byte-length@^1.0.1:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/typed-array-byte-length/-/typed-array-byte-length-1.0.1.tgz#d92972d3cff99a3fa2e765a28fcdc0f1d89dec67"
- integrity sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==
- dependencies:
- call-bind "^1.0.7"
- for-each "^0.3.3"
- gopd "^1.0.1"
- has-proto "^1.0.3"
- is-typed-array "^1.1.13"
-
-typed-array-byte-offset@^1.0.2:
- version "1.0.2"
- resolved "https://registry.yarnpkg.com/typed-array-byte-offset/-/typed-array-byte-offset-1.0.2.tgz#f9ec1acb9259f395093e4567eb3c28a580d02063"
- integrity sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==
- dependencies:
- available-typed-arrays "^1.0.7"
- call-bind "^1.0.7"
- for-each "^0.3.3"
- gopd "^1.0.1"
- has-proto "^1.0.3"
- is-typed-array "^1.1.13"
-
-typed-array-length@^1.0.6:
- version "1.0.6"
- resolved "https://registry.yarnpkg.com/typed-array-length/-/typed-array-length-1.0.6.tgz#57155207c76e64a3457482dfdc1c9d1d3c4c73a3"
- integrity sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g==
- dependencies:
- call-bind "^1.0.7"
- for-each "^0.3.3"
- gopd "^1.0.1"
- has-proto "^1.0.3"
- is-typed-array "^1.1.13"
- possible-typed-array-names "^1.0.0"
-
-unbox-primitive@^1.0.2:
- version "1.0.2"
- resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.2.tgz#29032021057d5e6cdbd08c5129c226dff8ed6f9e"
- integrity sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==
- dependencies:
- call-bind "^1.0.2"
- has-bigints "^1.0.2"
- has-symbols "^1.0.3"
- which-boxed-primitive "^1.0.2"
-
-undici-types@~6.19.2:
- version "6.19.8"
- resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-6.19.8.tgz#35111c9d1437ab83a7cdc0abae2f26d88eda0a02"
- integrity sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==
-
-update-browserslist-db@^1.1.0:
- version "1.1.1"
- resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.1.1.tgz#80846fba1d79e82547fb661f8d141e0945755fe5"
- integrity sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==
- dependencies:
- escalade "^3.2.0"
- picocolors "^1.1.0"
-
-update-check@1.5.4:
- version "1.5.4"
- resolved "https://registry.yarnpkg.com/update-check/-/update-check-1.5.4.tgz#5b508e259558f1ad7dbc8b4b0457d4c9d28c8743"
- integrity sha512-5YHsflzHP4t1G+8WGPlvKbJEbAJGCgw+Em+dGR1KmBUbr1J36SJBqlHLjR7oob7sco5hWHGQVcr9B2poIVDDTQ==
- dependencies:
- registry-auth-token "3.3.2"
- registry-url "3.1.0"
-
-uri-js@^4.2.2:
- version "4.4.1"
- resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e"
- integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==
- dependencies:
- punycode "^2.1.0"
-
-util-deprecate@^1.0.2:
- version "1.0.2"
- resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"
- integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==
-
-v8-to-istanbul@^9.0.1:
- version "9.3.0"
- resolved "https://registry.yarnpkg.com/v8-to-istanbul/-/v8-to-istanbul-9.3.0.tgz#b9572abfa62bd556c16d75fdebc1a411d5ff3175"
- integrity sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA==
- dependencies:
- "@jridgewell/trace-mapping" "^0.3.12"
- "@types/istanbul-lib-coverage" "^2.0.1"
- convert-source-map "^2.0.0"
-
-vary@^1, vary@~1.1.2:
- version "1.1.2"
- resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc"
- integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==
-
-walker@^1.0.8:
- version "1.0.8"
- resolved "https://registry.yarnpkg.com/walker/-/walker-1.0.8.tgz#bd498db477afe573dc04185f011d3ab8a8d7653f"
- integrity sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==
- dependencies:
- makeerror "1.0.12"
-
-which-boxed-primitive@^1.0.2:
- version "1.0.2"
- resolved "https://registry.yarnpkg.com/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz#13757bc89b209b049fe5d86430e21cf40a89a8e6"
- integrity sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==
- dependencies:
- is-bigint "^1.0.1"
- is-boolean-object "^1.1.0"
- is-number-object "^1.0.4"
- is-string "^1.0.5"
- is-symbol "^1.0.3"
-
-which-typed-array@^1.1.14, which-typed-array@^1.1.15:
- version "1.1.15"
- resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.15.tgz#264859e9b11a649b388bfaaf4f767df1f779b38d"
- integrity sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==
- dependencies:
- available-typed-arrays "^1.0.7"
- call-bind "^1.0.7"
- for-each "^0.3.3"
- gopd "^1.0.1"
- has-tostringtag "^1.0.2"
-
-which@^2.0.1:
- version "2.0.2"
- resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1"
- integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==
- dependencies:
- isexe "^2.0.0"
-
-widest-line@^4.0.1:
- version "4.0.1"
- resolved "https://registry.yarnpkg.com/widest-line/-/widest-line-4.0.1.tgz#a0fc673aaba1ea6f0a0d35b3c2795c9a9cc2ebf2"
- integrity sha512-o0cyEG0e8GPzT4iGHphIOh0cJOV8fivsXxddQasHPHfoZf1ZexrfeA21w2NaEN1RHE+fXlfISmOE8R9N3u3Qig==
- dependencies:
- string-width "^5.0.1"
-
-word-wrap@^1.2.5:
- version "1.2.5"
- resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.5.tgz#d2c45c6dd4fbce621a66f136cbe328afd0410b34"
- integrity sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==
-
-wrap-ansi@^7.0.0:
- version "7.0.0"
- resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43"
- integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==
- dependencies:
- ansi-styles "^4.0.0"
- string-width "^4.1.0"
- strip-ansi "^6.0.0"
-
-wrap-ansi@^8.0.1:
- version "8.1.0"
- resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214"
- integrity sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==
- dependencies:
- ansi-styles "^6.1.0"
- string-width "^5.0.1"
- strip-ansi "^7.0.1"
-
-wrappy@1:
- version "1.0.2"
- resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
- integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==
-
-write-file-atomic@^4.0.2:
- version "4.0.2"
- resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-4.0.2.tgz#a9df01ae5b77858a027fd2e80768ee433555fcfd"
- integrity sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==
- dependencies:
- imurmurhash "^0.1.4"
- signal-exit "^3.0.7"
-
-y18n@^5.0.5:
- version "5.0.8"
- resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55"
- integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==
-
-yallist@^3.0.2:
- version "3.1.1"
- resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd"
- integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==
-
-yaml@^1.10.2:
- version "1.10.2"
- resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b"
- integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==
-
-yargs-parser@^21.1.1:
- version "21.1.1"
- resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-21.1.1.tgz#9096bceebf990d21bb31fa9516e0ede294a77d35"
- integrity sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==
-
-yargs@^17.3.1, yargs@^17.5.1, yargs@^17.7.2:
- version "17.7.2"
- resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.7.2.tgz#991df39aca675a192b816e1e0363f9d75d2aa269"
- integrity sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==
- dependencies:
- cliui "^8.0.1"
- escalade "^3.1.1"
- get-caller-file "^2.0.5"
- require-directory "^2.1.1"
- string-width "^4.2.3"
- y18n "^5.0.5"
- yargs-parser "^21.1.1"
-
-yocto-queue@^0.1.0:
- version "0.1.0"
- resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b"
- integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==