diff --git a/.gitattributes b/.gitattributes index 0c47cbb0b..0c7fac37b 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,3 +1,4 @@ # We'll let Git's auto-detection algorithm infer if a file is text. If it is, # enforce LF line endings regardless of OS or git configurations. -* text=auto eol=lf \ No newline at end of file +* text=auto eol=lf +e2e/fixtures/** filter=lfs diff=lfs merge=lfs -text diff --git a/.github/HOW_TO_CONTRIBUTE.md b/.github/HOW_TO_CONTRIBUTE.md index caf62f133..ce8bba1e8 100644 --- a/.github/HOW_TO_CONTRIBUTE.md +++ b/.github/HOW_TO_CONTRIBUTE.md @@ -48,6 +48,8 @@ The following is a set of guidelines for contributing to Galacean. Please spend - Clone the Galacean playground repository and write a demo for your change. - Write an uint test in the Galacean repository and run `npm run test` to execute the uint test. +- [Write an e2e test](https://github.com/galacean/runtime/wiki/How-to-write-an-e2e-Test-for-runtime) in the Galacean repository and run `npm run e2e` to execute the e2e test. + ### Submitting a Pull Request @@ -142,4 +144,4 @@ git pull --ff upstream master ## Credits
Thank you to all the people who have already contributed to Galacean!
-
// WIP: Contributors \ No newline at end of file +
// WIP: Contributors diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f4c81bf4e..4579bc32a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -73,3 +73,53 @@ jobs: - name: Upload coverage to Codecov run: ./node_modules/.bin/codecov - run: curl -s https://codecov.io/bash + + e2e: + + runs-on: ubuntu-latest + + strategy: + matrix: + node-version: [16.x] + + steps: + - uses: actions/checkout@v3 + with: + lfs: true + - name: Install pnpm + uses: pnpm/action-setup@v2 + - name: Use Node.js ${{ matrix.node-version }} + uses: actions/setup-node@v3 + with: + node-version: ${{ matrix.node-version }} + cache: pnpm + - name: Install dependencies + run: pnpm i + - name: Build + run: npm run build + + - name: Run Cypress Tests + uses: cypress-io/github-action@v5 + with: + start: npm run e2e:case + wait-on: 'http://localhost:5175' + wait-on-timeout: 120 + browser: chrome + - name: Upload Diff + if: failure() + uses: actions/upload-artifact@v3 + with: + name: cypress-diff + path: e2e/diff/ + - name: Upload Origin + if: failure() + uses: actions/upload-artifact@v3 + with: + name: cypress-origin + path: e2e/fixtures/originImage + - name: Upload Screenshots + if: failure() + uses: actions/upload-artifact@v3 + with: + name: cypress-screenshots + path: e2e/screenshots/ diff --git a/.gitignore b/.gitignore index a1680d039..554dfe661 100644 --- a/.gitignore +++ b/.gitignore @@ -7,6 +7,7 @@ tmp /packages/*/types /packages/*/doc /tests/node_modules +/e2e/node_modules /playground/node_modules types /packages/*/test/fixtures/**/node_modules @@ -25,3 +26,11 @@ stats.html tsconfig.tsbuildinfo api yarn.lock +e2e/videos/* +e2e/screenshots/* +e2e/diff/* +e2e/.dev/mpa +.husky/post-checkout +.husky/post-commit +.husky/pre-push +.husky/post-merge diff --git a/README.md b/README.md index 37718e199..9abf11b5f 100644 --- a/README.md +++ b/README.md @@ -75,6 +75,16 @@ Everyone is welcome to join us! Whether you find a bug, have a great feature req Make sure to read the [Contributing Guide](.github/HOW_TO_CONTRIBUTE.md) / [贡献指南](https://github.com/galacean/engine/wiki/%E5%A6%82%E4%BD%95%E4%B8%8E%E6%88%91%E4%BB%AC%E5%85%B1%E5%BB%BA-Oasis-%E5%BC%80%E6%BA%90%E4%BA%92%E5%8A%A8%E5%BC%95%E6%93%8E) before submitting changes. +## Clone +Prerequisites: +- [git-lfs](https://git-lfs.com/) (Install by official website) + +Clone this repository: + +```sh +git clone git@github.com:galacean/runtime.git +``` + ## Build Prerequisites: diff --git a/cypress.config.ts b/cypress.config.ts new file mode 100644 index 000000000..a7cf3d132 --- /dev/null +++ b/cypress.config.ts @@ -0,0 +1,71 @@ +import { defineConfig } from "cypress"; +import { compare } from "odiff-bin"; + +const path = require("path"); +const fs = require("fs-extra"); + +const downloadDirectory = path.join(__dirname, "e2e/downloads"); +let isRunningInCommandLine = false; +export default defineConfig({ + e2e: { + viewportWidth: 1200, + viewportHeight: 800, + baseUrl: "http://localhost:5175", + defaultCommandTimeout: 60000, + fileServerFolder: "e2e", + supportFile: "e2e/support/e2e.ts", + fixturesFolder: "e2e/fixtures", + screenshotsFolder: "e2e/screenshots", + videosFolder: "e2e/videos", + specPattern: "e2e/tests/*.cy.ts", + setupNodeEvents(on, config) { + // implement node event listeners here + on("before:browser:launch", (browser, launchOptions) => { + console.log("launching browser %s is headless? %s", browser.name, browser.isHeadless); + // supply the absolute path to an unpacked extension's folder + // NOTE: extensions cannot be loaded in headless Chrome + if (fs.existsSync("e2e/diff")) { + fs.rmdirSync("e2e/diff", { recursive: true }); + } + if (browser.name === "chrome") { + launchOptions.preferences.default["download"] = { + default_directory: downloadDirectory + }; + } + if (browser.isHeadless) { + isRunningInCommandLine = true; + } + launchOptions.args.push("--force-device-scale-factor=1"); + return launchOptions; + }), + on("task", { + async compare({ fileName, options }) { + fileName += ".png"; + const baseFolder = "e2e/fixtures/originImage/"; + const newFolder = path.join("e2e/screenshots", isRunningInCommandLine ? options.specFolder : ""); + const diffFolder = path.join("e2e/diff", options.specFolder); + if (!fs.existsSync(diffFolder)) { + fs.mkdirSync(diffFolder, { recursive: true }); + } + const baseImage = path.join(baseFolder, fileName); + const newImage = path.join(newFolder, fileName); + const diffImage = path.join(diffFolder, fileName); + console.log("comparing base image %s to the new image %s", baseImage, newImage); + if (options) { + console.log("odiff options %o", options); + } + const started = +new Date(); + + const result = await compare(baseImage, newImage, diffImage, options); + const finished = +new Date(); + const elapsed = finished - started; + console.log("odiff took %dms", elapsed); + + console.log(result); + return result; + } + }); + } + }, + chromeWebSecurity: false +}); diff --git a/e2e/.dev/AlibabaSans.ttf b/e2e/.dev/AlibabaSans.ttf new file mode 100644 index 000000000..124487150 Binary files /dev/null and b/e2e/.dev/AlibabaSans.ttf differ diff --git a/e2e/.dev/index.html b/e2e/.dev/index.html new file mode 100644 index 000000000..3bc6adb5c --- /dev/null +++ b/e2e/.dev/index.html @@ -0,0 +1,39 @@ + + + + + + Galacean Case + + + +
+
+ +
+ + + + +
+ + + + diff --git a/e2e/.dev/index.js b/e2e/.dev/index.js new file mode 100644 index 000000000..fb32d79bc --- /dev/null +++ b/e2e/.dev/index.js @@ -0,0 +1,76 @@ +import './index.sass'; +import demoList from './mpa/.demoList.json'; +const itemListDOM = document.getElementById('itemList'); +const searchBarDOM = document.getElementById('searchBar'); +const iframe = document.getElementById('iframe'); +const items = []; // itemDOM,label + +Object.keys(demoList).forEach((group) => { + const demos = demoList[group]; + const groupDOM = document.createElement('div'); + const demosDOM = document.createElement('ul'); + itemListDOM.appendChild(groupDOM); + groupDOM.appendChild(demosDOM); + + demos.forEach((item) => { + const { label, src } = item; + const itemDOM = document.createElement('a'); + + itemDOM.innerHTML = src; + itemDOM.title = `${src}`; + itemDOM.onclick = function () { + clickItem(itemDOM); + }; + demosDOM.appendChild(itemDOM); + + items.push({ + itemDOM, + label, + src, + }); + }); +}); + +searchBarDOM.oninput = () => { + updateFilter(searchBar.value); +}; + +function updateFilter(value) { + const reg = new RegExp(value, 'i'); + + items.forEach(({ itemDOM, label, src }) => { + reg.lastIndex = 0; + if (reg.test(label) || reg.test(src)) { + itemDOM.classList.remove('hide'); + } else { + itemDOM.classList.add('hide'); + } + }); +} + +function clickItem(itemDOM) { + window.location.hash = `#mpa/${itemDOM.title}`; +} + +function onHashChange() { + const hashPath = window.location.hash.split('#')[1]; + if (!hashPath) { + clickItem(items[0].itemDOM); + return; + } + iframe.src = hashPath + '.html'; + + items.forEach(({ itemDOM }) => { + const itemPath = `mpa/${itemDOM.title}`; + if (itemPath === hashPath) { + itemDOM.classList.add('active'); + } else { + itemDOM.classList.remove('active'); + } + }); +} + +window.onhashchange = onHashChange; + +// init +onHashChange(); diff --git a/e2e/.dev/index.sass b/e2e/.dev/index.sass new file mode 100644 index 000000000..618af3908 --- /dev/null +++ b/e2e/.dev/index.sass @@ -0,0 +1,97 @@ +$header-height: 3.5rem +$header-padding: 1rem +$container-gap: 2rem +$transition-duration: 0.5s + +* + box-sizing: border-box + +html, body + margin: 0 + width: 100% + height: 100% + overflow: hidden + +body + font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen, Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif + font-size: 16px + +a + text-decoration: none + color: inherit + display: inline-block + +.container + display: flex + height: 100% + user-select: none + .header + position: absolute + top: 0 + left: 0 + height: $header-height + padding: $header-padding $container-gap + .logo + height: $header-height - 2 * $header-padding + display: flex + align-items: center + img + height: 100% + span + font-weight: bold + padding-left: 10px + font-size: 1.2em + .search-bar + position: absolute + top: $header-height + left: 1rem + padding: $header-padding $container-gap + background: #fff url("//gw-office.alipayobjects.com/basement_prod/225a73b9-1281-4388-9555-1e671899bc25.svg") .6rem .55rem no-repeat + cursor: text + width: 10rem + height: 2rem + color: #666 + display: inline-block + border: 1px solid #ccc + border-radius: 2rem + font-size: .9rem + line-height: 2rem + outline: none + .nav-left + display: flex + flex-direction: column + overflow: auto + padding: 1rem $container-gap + margin-top: $header-height + 2rem + + .item-list + .hide + height: 0 + ul + padding-left: 20px + margin: 0 + .title + font-weight: bold + cursor: default + font-size: 1.2em + a + height: 2rem + line-height: 2rem + cursor: pointer + transition-property: color,height + transition-duration: $transition-duration + overflow: hidden + display: block + &.active + text-decoration: underline + color: #096dd9 + &:hover + color: #096dd9 + + .nav-right + flex: 1 + box-shadow: rgb(125 121 121) -2px 0px 8px + + iframe + width: 100% + height: 100% diff --git a/e2e/.dev/template/iframe.ejs b/e2e/.dev/template/iframe.ejs new file mode 100644 index 000000000..6c6a9a755 --- /dev/null +++ b/e2e/.dev/template/iframe.ejs @@ -0,0 +1,55 @@ + + + + + + <%= title %> + + + + + + + + + + diff --git a/e2e/.dev/vite.config.js b/e2e/.dev/vite.config.js new file mode 100644 index 000000000..459bd71db --- /dev/null +++ b/e2e/.dev/vite.config.js @@ -0,0 +1,76 @@ +const path = require("path"); +const fs = require("fs-extra"); +const OUT_PATH = "mpa"; +const templateStr = fs.readFileSync(path.join(__dirname, "template/iframe.ejs"), "utf8"); + +// 替换 ejs 模版格式的字符串,如 <%= title %>: templateStr.replaceEJS("title","replaced title"); +String.prototype.replaceEJS = function (regStr, replaceStr) { + return this.replace(new RegExp(`<%=\\s*${regStr}\\s*%>`, "g"), replaceStr); +}; + +// clear mpa +fs.emptyDirSync(path.resolve(__dirname, OUT_PATH)); + +// create mpa +const demoList = fs + .readdirSync(path.join(__dirname, "../case")) + .filter((name) => /.ts$/.test(name) && name.indexOf(".") !== 0) + .map((name) => { + return { + file: name.split(".ts")[0] + }; + }); + +demoList.forEach(({ file }) => { + const ejs = templateStr.replaceEJS("url", `./${file}.ts`); + + fs.outputFileSync(path.resolve(__dirname, OUT_PATH, file + ".ts"), `import "../../case/${file}"`); + fs.outputFileSync(path.resolve(__dirname, OUT_PATH, file + ".html"), ejs); +}); + +// output demolist +const demoSorted = {}; +demoList.forEach(({ file }) => { + if (!demoSorted[file]) { + demoSorted[file] = []; + } + demoSorted[file].push({ + src: file + }); +}); + +fs.outputJSONSync(path.join(__dirname, OUT_PATH, ".demoList.json"), demoSorted); + +module.exports = { + server: { + open: true, + host: "0.0.0.0", + port: 5175 + }, + resolve: { + dedupe: ["@galacean/engine"] + }, + optimizeDeps: { + exclude: [ + "@galacean/engine", + "@galacean/engine-draco", + "@galacean/engine-lottie", + "@galacean/engine-spine", + "@galacean/tools-baker", + "@galacean/engine-toolkit", + "@galacean/engine-toolkit-auxiliary-lines", + "@galacean/engine-toolkit-controls", + "@galacean/engine-toolkit-framebuffer-picker", + "@galacean/engine-toolkit-gizmo", + "@galacean/engine-toolkit-lines", + "@galacean/engine-toolkit-outline", + "@galacean/engine-toolkit-planar-shadow-material", + "@galacean/engine-toolkit-skeleton-viewer", + "@galacean/engine-toolkit-grid-material", + "@galacean/engine-toolkit-navigation-gizmo", + "@galacean/engine-toolkit-geometry-sketch", + "@galacean/engine-toolkit-stats", + "@galacean/engine-toolkit-input-logger" + ] + } +}; diff --git a/e2e/case/.mockForE2E.ts b/e2e/case/.mockForE2E.ts new file mode 100644 index 000000000..d7e01472e --- /dev/null +++ b/e2e/case/.mockForE2E.ts @@ -0,0 +1,20 @@ +export const updateForE2E = (engine, deltaTime = 100) => { + engine._vSyncCount = Infinity; + engine._time._lastSystemTime = 0; + let times = 0; + performance.now = function () { + times++; + return times * deltaTime; + }; + for (let i = 0; i < 10; ++i) { + engine.update(); + } +}; + +export const e2eReady = () => { + setTimeout(() => { + const text = document.createElement("div"); + text.className = "cypressReady"; + document.body.appendChild(text); + }, 1000); +} diff --git a/e2e/case/animator-additive.ts b/e2e/case/animator-additive.ts new file mode 100644 index 000000000..cbfa0fa89 --- /dev/null +++ b/e2e/case/animator-additive.ts @@ -0,0 +1,68 @@ +/** + * @title Animation Additive + * @category Animation + */ +import { + Animator, + AnimatorControllerLayer, + AnimatorLayerBlendingMode, + AnimatorStateMachine, + Camera, + DirectLight, + GLTFResource, + Logger, + SystemInfo, + Vector3, + WebGLEngine +} from "@galacean/engine"; +import { OrbitControl } from "@galacean/engine-toolkit"; +import { e2eReady, updateForE2E } from "./.mockForE2E"; + +Logger.enable(); + +WebGLEngine.create({ canvas: "canvas" }).then((engine) => { + engine.canvas.resizeByClientSize(2); + const scene = engine.sceneManager.activeScene; + const rootEntity = scene.createRootEntity(); + + // camera + const cameraEntity = rootEntity.createChild("camera_node"); + cameraEntity.transform.position = new Vector3(0, 1, 5); + cameraEntity.addComponent(Camera); + cameraEntity.addComponent(OrbitControl).target = new Vector3(0, 1, 0); + + const lightNode = rootEntity.createChild("light_node"); + lightNode.addComponent(DirectLight).intensity = 0.6; + lightNode.transform.lookAt(new Vector3(0, 0, 1)); + lightNode.transform.rotate(new Vector3(0, 90, 0)); + + engine.resourceManager + .load("https://gw.alipayobjects.com/os/bmw-prod/5e3c1e4e-496e-45f8-8e05-f89f2bd5e4a4.glb") + .then((gltfResource) => { + const { animations = [], defaultSceneRoot } = gltfResource; + const animator = defaultSceneRoot.getComponent(Animator); + const { animatorController } = animator; + + const animatorStateMachine = new AnimatorStateMachine(); + const additiveLayer = new AnimatorControllerLayer("additiveLayer"); + additiveLayer.stateMachine = animatorStateMachine; + additiveLayer.blendingMode = AnimatorLayerBlendingMode.Additive; + animatorController.addLayer(additiveLayer); + + const additivePoseNames = animations.filter((clip) => clip.name.includes("pose")).map((clip) => clip.name); + + additivePoseNames.forEach((name) => { + const clip = animator.findAnimatorState(name).clip; + const newState = animatorStateMachine.addState(name); + newState.clipStartTime = 1; + newState.clip = clip; + }); + + rootEntity.addChild(defaultSceneRoot); + + animator.play("walk", 0); + animator.play("sad_pose", 1); + updateForE2E(engine); + e2eReady(); + }); +}); diff --git a/e2e/case/animator-blendShape.ts b/e2e/case/animator-blendShape.ts new file mode 100644 index 000000000..10c492fd7 --- /dev/null +++ b/e2e/case/animator-blendShape.ts @@ -0,0 +1,49 @@ +/** + * @title Animation BlendShape + * @category Animation + */ +import { OrbitControl } from "@galacean/engine-toolkit"; +import { + Animator, + Camera, + DirectLight, + Logger, + SkinnedMeshRenderer, + SystemInfo, + Vector3, + WebGLEngine, + GLTFResource +} from "@galacean/engine"; +import { e2eReady, updateForE2E } from "./.mockForE2E"; + +Logger.enable(); +WebGLEngine.create({ canvas: "canvas" }).then((engine) => { + engine.canvas.resizeByClientSize(2); + const scene = engine.sceneManager.activeScene; + const rootEntity = scene.createRootEntity(); + + // camera + const cameraEntity = rootEntity.createChild("camera_node"); + cameraEntity.transform.position = new Vector3(0, 1, 5); + cameraEntity.addComponent(Camera); + cameraEntity.addComponent(OrbitControl).target = new Vector3(0, 1, 0); + + const lightNode = rootEntity.createChild("light_node"); + lightNode.addComponent(DirectLight).intensity = 1.0; + lightNode.transform.lookAt(new Vector3(0, 0, 1)); + lightNode.transform.rotate(new Vector3(-45, -135, 0)); + + engine.resourceManager + .load("https://gw.alipayobjects.com/os/bmw-prod/746da3e3-fdc9-4155-8fee-0e2a97de4e72.glb") + .then((asset) => { + const { defaultSceneRoot } = asset; + rootEntity.addChild(defaultSceneRoot); + const animator = defaultSceneRoot.getComponent(Animator); + const skinMeshRenderer = defaultSceneRoot.getComponent(SkinnedMeshRenderer); + + skinMeshRenderer.blendShapeWeights[0] = 1.0; + animator.play("TheWave"); + updateForE2E(engine); + e2eReady(); + }); +}); diff --git a/e2e/case/animator-crossfade.ts b/e2e/case/animator-crossfade.ts new file mode 100644 index 000000000..8d7b0955d --- /dev/null +++ b/e2e/case/animator-crossfade.ts @@ -0,0 +1,47 @@ +/** + * @title Animation Play + * @category Animation + */ +import { OrbitControl } from "@galacean/engine-toolkit"; +import { + Animator, + Camera, + DirectLight, + Logger, + SystemInfo, + Vector3, + WebGLEngine, + GLTFResource +} from "@galacean/engine"; +import { e2eReady, updateForE2E } from "./.mockForE2E"; + +Logger.enable(); +WebGLEngine.create({ canvas: "canvas" }).then((engine) => { + engine.canvas.resizeByClientSize(2); + const scene = engine.sceneManager.activeScene; + const rootEntity = scene.createRootEntity(); + + // camera + const cameraEntity = rootEntity.createChild("camera_node"); + cameraEntity.transform.position = new Vector3(0, 1, 5); + cameraEntity.addComponent(Camera); + cameraEntity.addComponent(OrbitControl).target = new Vector3(0, 1, 0); + + const lightNode = rootEntity.createChild("light_node"); + lightNode.addComponent(DirectLight).intensity = 0.6; + lightNode.transform.lookAt(new Vector3(0, 0, 1)); + lightNode.transform.rotate(new Vector3(0, 90, 0)); + + engine.resourceManager + .load("https://gw.alipayobjects.com/os/bmw-prod/5e3c1e4e-496e-45f8-8e05-f89f2bd5e4a4.glb") + .then((gltfResource) => { + const { animations = [], defaultSceneRoot } = gltfResource; + rootEntity.addChild(defaultSceneRoot); + const animator = defaultSceneRoot.getComponent(Animator); + animator.play("agree"); + updateForE2E(engine, 30); + animator.crossFade("walk", 0.5, 0, 0); + updateForE2E(engine, 30); + e2eReady(); + }); +}); diff --git a/e2e/case/animator-customAnimationClip.ts b/e2e/case/animator-customAnimationClip.ts new file mode 100644 index 000000000..b54ea7e14 --- /dev/null +++ b/e2e/case/animator-customAnimationClip.ts @@ -0,0 +1,188 @@ +/** + * @title Animation CustomAnimationClip + * @category Animation + */ +import { + AnimationClip, + AnimationColorCurve, + AnimationFloatCurve, + AnimationVector3Curve, + Animator, + AnimatorController, + AnimatorControllerLayer, + AnimatorStateMachine, + Camera, + Color, + DirectLight, + GLTFResource, + Keyframe, + Logger, + SpotLight, + SystemInfo, + Transform, + Vector3, + WebGLEngine +} from "@galacean/engine"; +import { e2eReady, updateForE2E } from "./.mockForE2E"; + +Logger.enable(); +WebGLEngine.create({ canvas: "canvas" }).then((engine) => { + engine.canvas.resizeByClientSize(2); + const scene = engine.sceneManager.activeScene; + const rootEntity = scene.createRootEntity(); + + // camera + const cameraWrap = rootEntity.createChild("camera_wrap"); + const cameraEntity = cameraWrap.createChild("camera"); + cameraEntity.transform.position = new Vector3(0, 3, 8); + cameraEntity.transform.rotation = new Vector3(-2, 0, 0); + cameraEntity.addComponent(Camera); + + const lightWrap = rootEntity.createChild("light_wrap"); + + const directLightEntity = lightWrap.createChild("light_node"); + const directLight = directLightEntity.addComponent(DirectLight); + directLight.intensity = 0.6; + directLightEntity.transform.lookAt(new Vector3(0, 0, 1)); + directLightEntity.transform.rotate(new Vector3(0, 90, 0)); + + const spotLightEntity = lightWrap.createChild("spotLight1"); + const spotLightEntity2 = spotLightEntity.clone(); + spotLightEntity2.name = "spotLight2"; + spotLightEntity2.transform.setRotation(-120, 0, 0); + lightWrap.addChild(spotLightEntity2); + + const spotLight = spotLightEntity.addComponent(SpotLight); + spotLight.angle = Math.PI / 60; + spotLightEntity.transform.setPosition(0, 8, 0); + spotLightEntity.transform.setRotation(-60, 0, 0); + const spotLight2 = spotLightEntity2.addComponent(SpotLight); + spotLight2.angle = Math.PI / 60; + spotLightEntity2.transform.setPosition(0, 8, 0); + spotLightEntity2.transform.setRotation(-60, 0, 0); + + engine.resourceManager + .load("https://gw.alipayobjects.com/os/OasisHub/244228a7-361c-4c63-a790-dd9e19d12e78/data.gltf") + .then((gltfResource) => { + const { defaultSceneRoot, animations = [] } = gltfResource; + rootEntity.addChild(defaultSceneRoot); + const animator = defaultSceneRoot.getComponent(Animator); + + const sceneAnimator = rootEntity.addComponent(Animator); + sceneAnimator.animatorController = new AnimatorController(); + const layer = new AnimatorControllerLayer("base"); + sceneAnimator.animatorController.addLayer(layer); + const stateMachine = (layer.stateMachine = new AnimatorStateMachine()); + const sceneState = stateMachine.addState("sceneAnim"); + const sceneClip = (sceneState.clip = new AnimationClip("sceneAnim")); + + //custom rotate curve + const rotateCurve = new AnimationVector3Curve(); + const key1 = new Keyframe(); + key1.time = 0; + key1.value = new Vector3(0, 0, 0); + const key2 = new Keyframe(); + key2.time = 15; + key2.value = new Vector3(0, 360, 0); + rotateCurve.addKey(key1); + rotateCurve.addKey(key2); + + //custom color curve + const colorCurve = new AnimationColorCurve(); + const key3 = new Keyframe(); + key3.time = 0; + key3.value = new Color(1, 0, 0, 1); + const key4 = new Keyframe(); + key4.time = 5; + key4.value = new Color(0, 1, 0, 1); + const key5 = new Keyframe(); + key5.time = 10; + key5.value = new Color(0, 0, 1, 1); + const key6 = new Keyframe(); + key6.time = 15; + key6.value = new Color(1, 0, 0, 1); + colorCurve.addKey(key3); + colorCurve.addKey(key4); + colorCurve.addKey(key5); + colorCurve.addKey(key6); + + const color2Curve = new AnimationColorCurve(); + const key16 = new Keyframe(); + key16.time = 0; + key16.value = new Color(0, 0, 1, 1); + const key17 = new Keyframe(); + key17.time = 5; + key17.value = new Color(0, 1, 0, 1); + const key18 = new Keyframe(); + key18.time = 10; + key18.value = new Color(1, 0, 0, 1); + const key19 = new Keyframe(); + key19.time = 15; + key19.value = new Color(0, 0, 1, 1); + color2Curve.addKey(key16); + color2Curve.addKey(key17); + color2Curve.addKey(key18); + color2Curve.addKey(key19); + + //custom fov curve + const fovCurve = new AnimationFloatCurve(); + const key7 = new Keyframe(); + key7.time = 0; + key7.value = 45; + const key8 = new Keyframe(); + key8.time = 8; + key8.value = 80; + const key9 = new Keyframe(); + key9.time = 15; + key9.value = 45; + + fovCurve.addKey(key7); + fovCurve.addKey(key8); + fovCurve.addKey(key9); + + //custom spotLight1 rotate curve + const spotLight1RotateCurve = new AnimationVector3Curve(); + const key10 = new Keyframe(); + key10.time = 0; + key10.value = new Vector3(-60, 0, 0); + const key11 = new Keyframe(); + key11.time = 10; + key11.value = new Vector3(-120, 0, 0); + const key12 = new Keyframe(); + key12.time = 15; + key12.value = new Vector3(-60, 0, 0); + spotLight1RotateCurve.addKey(key10); + spotLight1RotateCurve.addKey(key11); + spotLight1RotateCurve.addKey(key12); + + //custom spotLight2 rotate curve + const spotLight2RotateCurve = new AnimationVector3Curve(); + const key13 = new Keyframe(); + key13.time = 0; + key13.value = new Vector3(-120, 0, 0); + const key14 = new Keyframe(); + key14.time = 10; + key14.value = new Vector3(-60, 0, 0); + const key15 = new Keyframe(); + key15.time = 15; + key15.value = new Vector3(-120, 0, 0); + spotLight2RotateCurve.addKey(key13); + spotLight2RotateCurve.addKey(key14); + spotLight2RotateCurve.addKey(key15); + + sceneClip.addCurveBinding("/light_wrap/spotLight1", SpotLight, "color", colorCurve); + sceneClip.addCurveBinding("/light_wrap/spotLight1", Transform, "rotation", spotLight1RotateCurve); + sceneClip.addCurveBinding("/light_wrap/spotLight2", Transform, "rotation", spotLight2RotateCurve); + sceneClip.addCurveBinding("/light_wrap/spotLight2", SpotLight, "color", color2Curve); + sceneClip.addCurveBinding("/light_wrap", Transform, "rotation", rotateCurve); + // curve can be reused + sceneClip.addCurveBinding("/camera_wrap", Transform, "rotation", rotateCurve); + sceneClip.addCurveBinding("/camera_wrap/camera", Camera, "fieldOfView", fovCurve); + + sceneAnimator.play("sceneAnim", 0); + animator.play(animations[0].name, 0); + + updateForE2E(engine, 500); + e2eReady(); + }); +}); diff --git a/e2e/case/animator-customBlendShape.ts b/e2e/case/animator-customBlendShape.ts new file mode 100644 index 000000000..2cb054f58 --- /dev/null +++ b/e2e/case/animator-customBlendShape.ts @@ -0,0 +1,98 @@ +/** + * @title Animation CustomBlendShape + * @category Animation + */ +import { OrbitControl } from "@galacean/engine-toolkit"; +import { + AnimationClip, + AnimationFloatArrayCurve, + Animator, + AnimatorController, + AnimatorControllerLayer, + AnimatorStateMachine, + BlendShape, + Camera, + Keyframe, + Logger, + ModelMesh, + SkinnedMeshRenderer, + SystemInfo, + UnlitMaterial, + Vector3, + WebGLEngine +} from "@galacean/engine"; +import { e2eReady, updateForE2E } from "./.mockForE2E"; + +Logger.enable(); +WebGLEngine.create({ canvas: "canvas" }).then((engine) => { + engine.canvas.resizeByClientSize(2); + const scene = engine.sceneManager.activeScene; + const rootEntity = scene.createRootEntity(); + + // camera + const cameraEntity = rootEntity.createChild("cameraNode"); + cameraEntity.transform.position = new Vector3(0, 0, 5); + cameraEntity.addComponent(Camera); + cameraEntity.addComponent(OrbitControl); + + const meshEntity = rootEntity.createChild("meshEntity"); + const skinnedMeshRenderer = meshEntity.addComponent(SkinnedMeshRenderer); + const modelMesh = new ModelMesh(engine); + + // Set vertices data. + const positions = [ + new Vector3(-1.0, -1.0, 1.0), + new Vector3(1.0, -1.0, 1.0), + new Vector3(1.0, 1.0, 1.0), + new Vector3(1.0, 1.0, 1.0), + new Vector3(-1.0, 1.0, 1.0), + new Vector3(-1.0, -1.0, 1.0) + ]; + modelMesh.setPositions(positions); + + // Add SubMesh. + modelMesh.addSubMesh(0, 6); + + // Add BlendShape. + const deltaPositions = [ + new Vector3(0.0, 0.0, 0.0), + new Vector3(0.0, 0.0, 0.0), + new Vector3(-1.0, 0.0, 0.0), + new Vector3(-1.0, 0.0, 0.0), + new Vector3(1.0, 0.0, 0.0), + new Vector3(0.0, 0.0, 0.0) + ]; + const blendShape = new BlendShape("BlendShapeA"); + blendShape.addFrame(1.0, deltaPositions); + modelMesh.addBlendShape(blendShape); + + skinnedMeshRenderer.mesh = modelMesh; + skinnedMeshRenderer.setMaterial(new UnlitMaterial(engine)); + + // Upload data. + modelMesh.uploadData(false); + + const animator = meshEntity.addComponent(Animator); + animator.animatorController = new AnimatorController(); + const layer = new AnimatorControllerLayer("base"); + animator.animatorController.addLayer(layer); + const stateMachine = (layer.stateMachine = new AnimatorStateMachine()); + const state = stateMachine.addState("blendShape"); + const clip = (state.clip = new AnimationClip("blendShape")); + + //custom blendShape curve + const blendShapeCurve = new AnimationFloatArrayCurve(); + const key1 = new Keyframe(); + key1.time = 0; + key1.value = new Float32Array([0]); + const key2 = new Keyframe(); + key2.time = 5; + key2.value = new Float32Array([1]); + blendShapeCurve.addKey(key1); + blendShapeCurve.addKey(key2); + + clip.addCurveBinding("", SkinnedMeshRenderer, "blendShapeWeights", blendShapeCurve); + animator.play("blendShape"); + updateForE2E(engine, 1000); + e2eReady(); +}); diff --git a/e2e/case/animator-event.ts b/e2e/case/animator-event.ts new file mode 100644 index 000000000..5674fc7fd --- /dev/null +++ b/e2e/case/animator-event.ts @@ -0,0 +1,83 @@ +/** + * @title Animation Event + * @category Animation + */ +import { OrbitControl } from "@galacean/engine-toolkit"; +import * as dat from "dat.gui"; +import { + AnimationEvent, + Animator, + Camera, + DirectLight, + Font, + FontStyle, + GLTFResource, + Script, + SystemInfo, + TextRenderer, + Vector3, + WebGLEngine +} from "@galacean/engine"; +import { e2eReady, updateForE2E } from "./.mockForE2E"; + +const engine = await WebGLEngine.create({ canvas: "canvas" }); +engine.canvas.resizeByClientSize(2); +const scene = engine.sceneManager.activeScene; +const rootEntity = scene.createRootEntity(); +console.log(99, SystemInfo.devicePixelRatio); +// camera +const cameraEntity = rootEntity.createChild("camera_node"); +cameraEntity.transform.position = new Vector3(0, 1, 5); +cameraEntity.addComponent(Camera); +cameraEntity.addComponent(OrbitControl).target = new Vector3(0, 1, 0); + +const lightNode = rootEntity.createChild("light_node"); +lightNode.addComponent(DirectLight).intensity = 0.6; +lightNode.transform.lookAt(new Vector3(0, 0, 1)); +lightNode.transform.rotate(new Vector3(0, 90, 0)); + +// initText +const textEntity = rootEntity.createChild("text"); +const textRenderer = textEntity.addComponent(TextRenderer); +textEntity.transform.setPosition(0, 2, 0); +textRenderer.fontSize = 12; +textRenderer.font = Font.createFromOS(engine, "AlibabaSans"); +textRenderer.text = ""; + +engine.resourceManager + .load("https://gw.alipayobjects.com/os/bmw-prod/5e3c1e4e-496e-45f8-8e05-f89f2bd5e4a4.glb") + .then((gltfResource) => { + const { defaultSceneRoot, animations } = gltfResource; + rootEntity.addChild(defaultSceneRoot); + const animator = defaultSceneRoot.getComponent(Animator); + + const state = animator.findAnimatorState("walk"); + const clip = state.clip; + + const event0 = new AnimationEvent(); + event0.functionName = "event0"; + event0.time = 0.5; + clip.addEvent(event0); + + const event1 = new AnimationEvent(); + event1.functionName = "event1"; + event1.time = clip.length; + clip.addEvent(event1); + + defaultSceneRoot.addComponent( + class extends Script { + event0(): void { + textRenderer.text = "0"; + } + + event1(): void { + textRenderer.text = "1"; + } + } + ); + + animator.play("walk", 0); + + updateForE2E(engine, 500); + e2eReady(); + }); diff --git a/e2e/case/animator-play.ts b/e2e/case/animator-play.ts new file mode 100644 index 000000000..80aac51ea --- /dev/null +++ b/e2e/case/animator-play.ts @@ -0,0 +1,46 @@ +/** + * @title Animation Play + * @category Animation + */ +import { + Animator, + Camera, + DirectLight, + GLTFResource, + Logger, + SystemInfo, + Vector3, + WebGLEngine +} from "@galacean/engine"; +import { OrbitControl } from "@galacean/engine-toolkit"; +import { updateForE2E, e2eReady } from "./.mockForE2E"; + +Logger.enable(); +WebGLEngine.create({ canvas: "canvas" }).then((engine) => { + engine.canvas.resizeByClientSize(2); + const scene = engine.sceneManager.activeScene; + const rootEntity = scene.createRootEntity(); + + // camera + const cameraEntity = rootEntity.createChild("camera_node"); + cameraEntity.transform.position = new Vector3(0, 1, 5); + cameraEntity.addComponent(Camera); + cameraEntity.addComponent(OrbitControl).target = new Vector3(0, 1, 0); + + const lightNode = rootEntity.createChild("light_node"); + lightNode.addComponent(DirectLight).intensity = 0.6; + lightNode.transform.lookAt(new Vector3(0, 0, 1)); + lightNode.transform.rotate(new Vector3(0, 90, 0)); + + engine.resourceManager + .load("https://gw.alipayobjects.com/os/bmw-prod/5e3c1e4e-496e-45f8-8e05-f89f2bd5e4a4.glb") + .then((gltfResource) => { + const { defaultSceneRoot } = gltfResource; + rootEntity.addChild(defaultSceneRoot); + const animator = defaultSceneRoot.getComponent(Animator); + animator.play("agree"); + + updateForE2E(engine); + e2eReady(); + }); +}); diff --git a/e2e/case/animator-reuse.ts b/e2e/case/animator-reuse.ts new file mode 100644 index 000000000..256a0a26c --- /dev/null +++ b/e2e/case/animator-reuse.ts @@ -0,0 +1,69 @@ +/** + * @title Animation Reuse + * @category Animation + */ +import { + Animator, + AssetPromise, + Camera, + DirectLight, + GLTFResource, + Logger, + SystemInfo, + Vector3, + WebGLEngine +} from "@galacean/engine"; +import { OrbitControl } from "@galacean/engine-toolkit"; +import { e2eReady, updateForE2E } from "./.mockForE2E"; + +Logger.enable(); +WebGLEngine.create({ canvas: "canvas" }).then((engine) => { + engine.canvas.resizeByClientSize(2); + const scene = engine.sceneManager.activeScene; + const rootEntity = scene.createRootEntity(); + + // camera + const cameraEntity = rootEntity.createChild("camera_node"); + cameraEntity.transform.position = new Vector3(0, 1, 5); + cameraEntity.addComponent(Camera); + cameraEntity.addComponent(OrbitControl).target = new Vector3(0, 1, 0); + + const lightNode = rootEntity.createChild("light_node"); + lightNode.addComponent(DirectLight).intensity = 0.6; + lightNode.transform.lookAt(new Vector3(0, 0, 1)); + lightNode.transform.rotate(new Vector3(0, 90, 0)); + + const promises: AssetPromise[] = []; + // origin model + promises.push( + engine.resourceManager.load( + "https://gw.alipayobjects.com/os/OasisHub/6f5b1918-1380-4641-a57a-7507503a524c/data.gltf" + ) + ); + // animation + promises.push( + engine.resourceManager.load( + "https://gw.alipayobjects.com/os/OasisHub/9ef53086-67d4-4be6-bff8-449a8074a5bd/data.gltf" + ) + ); + + Promise.all(promises).then((resArr) => { + const modelGLTF = resArr[0]; + const animationGLTF = resArr[1]; + const { animations: originAnimations = [] } = modelGLTF; + const { animations = [] } = animationGLTF; + const { defaultSceneRoot } = modelGLTF; + rootEntity.addChild(defaultSceneRoot); + const animator = defaultSceneRoot.getComponent(Animator); + + const danceState = animator.animatorController.layers[0].stateMachine.addState("dance"); + danceState.clip = animations[0]; + + animator.play("dance"); + + const animationNames = originAnimations.map((clip) => clip.name); + animationNames.push("dance"); + updateForE2E(engine); + e2eReady(); + }); +}); diff --git a/e2e/case/animator-stateMachineScript.ts b/e2e/case/animator-stateMachineScript.ts new file mode 100644 index 000000000..41d0cf450 --- /dev/null +++ b/e2e/case/animator-stateMachineScript.ts @@ -0,0 +1,82 @@ +/** + * @title AnimatorStateScript + * @category Animation + */ +import { OrbitControl } from "@galacean/engine-toolkit"; +import { + Animator, + AnimatorState, + Camera, + DirectLight, + Font, + FontStyle, + GLTFResource, + Logger, + StateMachineScript, + SystemInfo, + TextRenderer, + Vector3, + WebGLEngine +} from "@galacean/engine"; +import { e2eReady, updateForE2E } from "./.mockForE2E"; + +Logger.enable(); +WebGLEngine.create({ canvas: "canvas" }).then((engine) => { + engine.canvas.resizeByClientSize(2); + const scene = engine.sceneManager.activeScene; + const rootEntity = scene.createRootEntity(); + + // camera + const cameraEntity = rootEntity.createChild("camera_node"); + cameraEntity.transform.position = new Vector3(0, 1, 5); + cameraEntity.addComponent(Camera); + cameraEntity.addComponent(OrbitControl).target = new Vector3(0, 1, 0); + + const lightNode = rootEntity.createChild("light_node"); + lightNode.addComponent(DirectLight).intensity = 0.6; + lightNode.transform.lookAt(new Vector3(0, 0, 1)); + lightNode.transform.rotate(new Vector3(0, 90, 0)); + + // initText + const textEntity = rootEntity.createChild("text"); + const textRenderer = textEntity.addComponent(TextRenderer); + textEntity.transform.setPosition(0, 2, 0); + textRenderer.fontSize = 12; + textRenderer.font = Font.createFromOS(engine, "AlibabaSans"); + textRenderer.text = ""; + + engine.resourceManager + .load("https://gw.alipayobjects.com/os/bmw-prod/5e3c1e4e-496e-45f8-8e05-f89f2bd5e4a4.glb") + .then((gltfResource) => { + const { animations = [], defaultSceneRoot } = gltfResource; + rootEntity.addChild(defaultSceneRoot); + + const animator = defaultSceneRoot.getComponent(Animator); + const state = animator.findAnimatorState("walk"); + + state.addStateMachineScript( + class extends StateMachineScript { + onStateEnter(animator: Animator, animatorState: AnimatorState, layerIndex: number): void { + textRenderer.text = "0"; + console.log("onStateEnter: ", animatorState); + } + + onStateUpdate(animator: Animator, animatorState: AnimatorState, layerIndex: number): void { + console.log("onStateUpdate: ", animatorState); + } + + onStateExit(animator: Animator, animatorState: AnimatorState, layerIndex: number): void { + textRenderer.text = "1"; + console.log("onStateExit: ", animatorState); + } + } + ); + + animator.play("walk"); + + updateForE2E(engine, 30); + animator.crossFade("run", 0.5, 0, 0); + updateForE2E(engine, 100); + e2eReady(); + }); +}); diff --git a/e2e/fixtures/originImage/Animator_animator-additive.png b/e2e/fixtures/originImage/Animator_animator-additive.png new file mode 100644 index 000000000..1748689cd --- /dev/null +++ b/e2e/fixtures/originImage/Animator_animator-additive.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c9f55ccf7d9ba3eeae64d80dec8a0f1d07a28708b6864200402611c5d70fe2f3 +size 31060 diff --git a/e2e/fixtures/originImage/Animator_animator-blendShape.png b/e2e/fixtures/originImage/Animator_animator-blendShape.png new file mode 100644 index 000000000..749e14aad --- /dev/null +++ b/e2e/fixtures/originImage/Animator_animator-blendShape.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6247265cc5a322be8c5870243db59fb945651e56f046a390991130aa20171a8e +size 72841 diff --git a/e2e/fixtures/originImage/Animator_animator-crossfade.png b/e2e/fixtures/originImage/Animator_animator-crossfade.png new file mode 100644 index 000000000..4280f552d --- /dev/null +++ b/e2e/fixtures/originImage/Animator_animator-crossfade.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c053b0cc1ac48e4e764d5c16b0ca2d46b5f72e4d07b74ff3b779974af22f40a0 +size 30566 diff --git a/e2e/fixtures/originImage/Animator_animator-customAnimationClip.png b/e2e/fixtures/originImage/Animator_animator-customAnimationClip.png new file mode 100644 index 000000000..9206ffdaf --- /dev/null +++ b/e2e/fixtures/originImage/Animator_animator-customAnimationClip.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2b2f8c4351d39e95152af5604858512e94157b58e74800ec5be8cc9c0344cabe +size 14836 diff --git a/e2e/fixtures/originImage/Animator_animator-customBlendShape.png b/e2e/fixtures/originImage/Animator_animator-customBlendShape.png new file mode 100644 index 000000000..a7e5304bf --- /dev/null +++ b/e2e/fixtures/originImage/Animator_animator-customBlendShape.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f816564ea3b61a8f6ec6bb6ab55c4526278f15c3167493bd6e7ae7a8d96b9538 +size 9894 diff --git a/e2e/fixtures/originImage/Animator_animator-event.png b/e2e/fixtures/originImage/Animator_animator-event.png new file mode 100644 index 000000000..27a0a79e1 --- /dev/null +++ b/e2e/fixtures/originImage/Animator_animator-event.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:46d72de6ff304523602e6d651bd19de111d8a92c9ecac5854fcd8ae3686262f8 +size 30210 diff --git a/e2e/fixtures/originImage/Animator_animator-play.png b/e2e/fixtures/originImage/Animator_animator-play.png new file mode 100644 index 000000000..fb2385910 --- /dev/null +++ b/e2e/fixtures/originImage/Animator_animator-play.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d2ae9948fa4082b03e9a2b6e847b2e301497045a1e8a51aed55238dc67fcbb31 +size 31219 diff --git a/e2e/fixtures/originImage/Animator_animator-reuse.png b/e2e/fixtures/originImage/Animator_animator-reuse.png new file mode 100644 index 000000000..f77e7459f --- /dev/null +++ b/e2e/fixtures/originImage/Animator_animator-reuse.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9a7e5ed546549e84343f7a590eb7d01eed5a8716833b25e305d8356ab174aee6 +size 28309 diff --git a/e2e/fixtures/originImage/Animator_animator-stateMachineScript.png b/e2e/fixtures/originImage/Animator_animator-stateMachineScript.png new file mode 100644 index 000000000..563f72b53 --- /dev/null +++ b/e2e/fixtures/originImage/Animator_animator-stateMachineScript.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:92beef2371cf9b1cb897902ef47c58646b30133d8ebd418c39820931d226a8f0 +size 28203 diff --git a/e2e/package.json b/e2e/package.json new file mode 100644 index 000000000..b23220505 --- /dev/null +++ b/e2e/package.json @@ -0,0 +1,25 @@ +{ + "name": "@galacean/engine-e2e", + "private": true, + "version": "1.0.0-alpha.6", + "license": "MIT", + "scripts": { + "case": "vite serve .dev --config .dev/vite.config.js", + "b:types": "echo hi" + }, + "files": [ + ], + "dependencies": { + "@galacean/engine-toolkit": "^1.0.0-beta.1", + "@galacean/engine": "workspace:*", + "@galacean/engine-core": "workspace:*", + "@galacean/engine-loader": "workspace:*", + "@galacean/engine-design": "workspace:*", + "@galacean/engine-math": "workspace:*", + "@galacean/engine-rhi-webgl": "workspace:*", + "@galacean/engine-physics-lite": "workspace:*", + "dat.gui": "^0.7.9", + "vite": "^3.1.6", + "sass": "^1.55.0" + } +} diff --git a/e2e/support/commands.ts b/e2e/support/commands.ts new file mode 100644 index 000000000..bc0436c05 --- /dev/null +++ b/e2e/support/commands.ts @@ -0,0 +1,67 @@ +import { recurse } from "cypress-recurse"; +/// +// *********************************************** +// This example commands.ts shows you how to +// create various custom commands and overwrite +// existing commands. +// +// For more comprehensive examples of custom +// commands please read more here: +// https://on.cypress.io/custom-commands +// *********************************************** +// +// +// -- This is a parent command -- +// Cypress.Commands.add('login', (email, password) => { ... }) +// +// +// -- This is a child command -- +// Cypress.Commands.add('drag', { prevSubject: 'element'}, (subject, options) => { ... }) +// +// +// -- This is a dual command -- +// Cypress.Commands.add('dismiss', { prevSubject: 'optional'}, (subject, options) => { ... }) +// +// +// -- This will overwrite an existing command -- +// Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... }) +// +declare global { + namespace Cypress { + interface Chainable { + screenshotWithThreshold(category: string, name: string, threshold?: number): Chainable; + } + } +} + +Cypress.Commands.add("screenshotWithThreshold", (category, name, threshold = 0) => { + cy.visit(`/mpa/${name}.html`); + + cy.get(".cypressReady").then(() => { + return new Promise((resolve) => { + const imageName = `${category}_${name}`; + resolve( + recurse( + () => { + return cy + .get("#canvas") + .screenshot(imageName, { overwrite: true, capture: "viewport" }) + .then(() => { + return cy.task("compare", { + fileName: imageName, + options: { + specFolder: Cypress.spec.name, + threshold + } + }); + }); + }, + ({ match }) => match, + { + limit: 3 + } + ) + ); + }); + }); +}); diff --git a/e2e/support/e2e.ts b/e2e/support/e2e.ts new file mode 100644 index 000000000..6a173d6fc --- /dev/null +++ b/e2e/support/e2e.ts @@ -0,0 +1,20 @@ +// *********************************************************** +// This example support/e2e.ts is processed and +// loaded automatically before your test files. +// +// This is a great place to put global configuration and +// behavior that modifies Cypress. +// +// You can change the location of this file or turn off +// automatically serving support files with the +// 'supportFile' configuration option. +// +// You can read more here: +// https://on.cypress.io/configuration +// *********************************************************** + +// Import commands.js using ES2015 syntax: +import "./commands"; + +// Alternatively you can use CommonJS syntax: +// require('./commands') diff --git a/e2e/tests/animator.cy.ts b/e2e/tests/animator.cy.ts new file mode 100644 index 000000000..98b09b17c --- /dev/null +++ b/e2e/tests/animator.cy.ts @@ -0,0 +1,37 @@ +describe("Animator", () => { + it("Animator Play", () => { + cy.screenshotWithThreshold("Animator", "animator-play", 0.3); + }); + + it("Animator Crossfade", () => { + cy.screenshotWithThreshold("Animator", "animator-crossfade", 0.3); + }); + + it("Animation Additive", () => { + cy.screenshotWithThreshold("Animator", "animator-additive", 0.3); + }); + + it("Animator Reuse", () => { + cy.screenshotWithThreshold("Animator", "animator-reuse", 0.3); + }); + + it("Animation BlendShape", () => { + cy.screenshotWithThreshold("Animator", "animator-blendShape", 0.3); + }); + + it("Animator CustomBlendShape", () => { + cy.screenshotWithThreshold("Animator", "animator-customBlendShape", 0.3); + }); + + it("Animator stateMachineScript", () => { + cy.screenshotWithThreshold("Animator", "animator-stateMachineScript", 0.38); + }); + + it("Animator event", () => { + cy.screenshotWithThreshold("Animator", "animator-event", 0.38); + }); + + it("Animator CustomAnimationClip", () => { + cy.screenshotWithThreshold("Animator", "animator-customAnimationClip", 0.3); + }); +}); diff --git a/e2e/tsconfig.json b/e2e/tsconfig.json new file mode 100644 index 000000000..18edb199a --- /dev/null +++ b/e2e/tsconfig.json @@ -0,0 +1,8 @@ +{ + "compilerOptions": { + "target": "es5", + "lib": ["es5", "dom"], + "types": ["cypress", "node"] + }, + "include": ["**/*.ts"] +} diff --git a/package.json b/package.json index 58c669edb..fa0857d17 100644 --- a/package.json +++ b/package.json @@ -18,6 +18,9 @@ "b:miniprogram": "cross-env BUILD_TYPE=MINI rollup -c", "b:all": "npm run b:types && cross-env BUILD_TYPE=ALL rollup -c", "clean": "pnpm -r exec rm -rf dist && pnpm -r exec rm -rf types", + "e2e:case": "pnpm -C ./e2e run case", + "e2e": "cypress run --browser chrome --headless", + "e2e:debug": "cypress open", "prepare": "husky install" }, "devDependencies": { @@ -54,7 +57,11 @@ "ts-node": "^10", "typescript": "^5.1.6", "@types/webxr": "latest", - "husky": "^8.0.0" + "husky": "^8.0.0", + "fs-extra": "^10.1.0", + "cypress": "^12.17.1", + "cypress-recurse": "^1.23.0", + "odiff-bin": "^2.5.0" }, "lint-staged": { "*.{ts}": [ diff --git a/packages/core/src/2d/text/TextUtils.ts b/packages/core/src/2d/text/TextUtils.ts index e22fa890e..1c01b7800 100644 --- a/packages/core/src/2d/text/TextUtils.ts +++ b/packages/core/src/2d/text/TextUtils.ts @@ -215,8 +215,8 @@ export class TextUtils { } else { word += char; wordWidth += charInfo.xAdvance; - wordMaxAscent = lineMaxAscent = Math.max(wordMaxAscent, ascent); - wordMaxDescent = lineMaxDescent = Math.max(wordMaxDescent, descent); + wordMaxAscent = Math.max(wordMaxAscent, ascent); + wordMaxDescent = Math.max(wordMaxDescent, descent); } } } diff --git a/packages/core/src/Component.ts b/packages/core/src/Component.ts index e29a11faf..061580515 100644 --- a/packages/core/src/Component.ts +++ b/packages/core/src/Component.ts @@ -36,20 +36,28 @@ export class Component extends EngineObject { this._enabled = value; if (this._entity._isActiveInScene) { if (value) { - this._phasedActiveInScene = true; - this._onEnableInScene(); + if (!this._phasedActiveInScene) { + this._phasedActiveInScene = true; + this._onEnableInScene(); + } } else { - this._phasedActiveInScene = false; - this._onDisableInScene(); + if (this._phasedActiveInScene) { + this._phasedActiveInScene = false; + this._onDisableInScene(); + } } } if (this._entity.isActiveInHierarchy) { if (value) { - this._phasedActive = true; - this._onEnable(); + if (!this._phasedActive) { + this._phasedActive = true; + this._onEnable(); + } } else { - this._phasedActive = false; - this._onDisable(); + if (this._phasedActive) { + this._phasedActive = false; + this._onDisable(); + } } } } diff --git a/packages/core/src/RenderPipeline/RenderQueue.ts b/packages/core/src/RenderPipeline/RenderQueue.ts index 1cb10380f..bff83c357 100644 --- a/packages/core/src/RenderPipeline/RenderQueue.ts +++ b/packages/core/src/RenderPipeline/RenderQueue.ts @@ -18,6 +18,7 @@ export class RenderQueue { static _compareFromNearToFar(a: RenderElement, b: RenderElement): number { return ( a.data.component.priority - b.data.component.priority || + a.data.material._priority - b.data.material._priority || a.data.component._distanceForSort - b.data.component._distanceForSort ); } @@ -28,6 +29,7 @@ export class RenderQueue { static _compareFromFarToNear(a: RenderElement, b: RenderElement): number { return ( a.data.component.priority - b.data.component.priority || + a.data.material._priority - b.data.material._priority || b.data.component._distanceForSort - a.data.component._distanceForSort ); } diff --git a/packages/core/src/animation/AnimationClip.ts b/packages/core/src/animation/AnimationClip.ts index 4327c1a2f..79982db52 100644 --- a/packages/core/src/animation/AnimationClip.ts +++ b/packages/core/src/animation/AnimationClip.ts @@ -1,6 +1,7 @@ import { EngineObject } from "../base/EngineObject"; import { Component } from "../Component"; import { Entity } from "../Entity"; +import { UpdateFlagManager } from "../UpdateFlagManager"; import { AnimationClipCurveBinding } from "./AnimationClipCurveBinding"; import { AnimationCurve } from "./animationCurve/AnimationCurve"; import { AnimationEvent } from "./AnimationEvent"; @@ -14,6 +15,9 @@ export class AnimationClip extends EngineObject { /** @internal */ _curveBindings: AnimationClipCurveBinding[] = []; + /** @internal */ + _updateFlagManager: UpdateFlagManager = new UpdateFlagManager(); + private _length: number = 0; private _events: AnimationEvent[] = []; @@ -81,6 +85,8 @@ export class AnimationClip extends EngineObject { while (--index >= 0 && eventTime < events[index].time); events.splice(index + 1, 0, newEvent); } + + this._updateFlagManager.dispatch(); } /** @@ -88,6 +94,7 @@ export class AnimationClip extends EngineObject { */ clearEvents(): void { this._events.length = 0; + this._updateFlagManager.dispatch(); } /** diff --git a/packages/core/src/animation/Animator.ts b/packages/core/src/animation/Animator.ts index 52020ff68..201ef362c 100644 --- a/packages/core/src/animation/Animator.ts +++ b/packages/core/src/animation/Animator.ts @@ -312,7 +312,6 @@ export class Animator extends Component { const { property } = curve; const { instanceId } = targetEntity; - // Get owner const propertyOwners = (curveOwnerPool[instanceId] ||= Object.create(null)); const owner = (propertyOwners[property] ||= curve._createCurveOwner(targetEntity, component)); @@ -336,26 +335,30 @@ export class Animator extends Component { private _saveAnimatorEventHandlers(state: AnimatorState, animatorStateData: AnimatorStateData): void { const eventHandlerPool = this._animationEventHandlerPool; const scripts = []; - this._entity.getComponents(Script, scripts); - const scriptCount = scripts.length; const { eventHandlers } = animatorStateData; - const { events } = state.clip; - eventHandlers.length = 0; - for (let i = 0, n = events.length; i < n; i++) { - const event = events[i]; - const eventHandler = eventHandlerPool.getFromPool(); - const funcName = event.functionName; - const { handlers } = eventHandler; + const clipChangedListener = () => { + this._entity.getComponents(Script, scripts); + const scriptCount = scripts.length; + const { events } = state.clip; + eventHandlers.length = 0; + for (let i = 0, n = events.length; i < n; i++) { + const event = events[i]; + const eventHandler = eventHandlerPool.getFromPool(); + const funcName = event.functionName; + const { handlers } = eventHandler; - eventHandler.event = event; - handlers.length = 0; - for (let j = scriptCount - 1; j >= 0; j--) { - const handler = scripts[j][funcName]; - handler && handlers.push(handler); + eventHandler.event = event; + handlers.length = 0; + for (let j = scriptCount - 1; j >= 0; j--) { + const handler = scripts[j][funcName]; + handler && handlers.push(handler); + } + eventHandlers.push(eventHandler); } - eventHandlers.push(eventHandler); - } + }; + clipChangedListener(); + state._updateFlagManager.addListener(clipChangedListener); } private _clearCrossData(animatorLayerData: AnimatorLayerData): void { diff --git a/packages/core/src/animation/AnimatorState.ts b/packages/core/src/animation/AnimatorState.ts index 1a805292f..d45b8ab52 100644 --- a/packages/core/src/animation/AnimatorState.ts +++ b/packages/core/src/animation/AnimatorState.ts @@ -1,3 +1,4 @@ +import { UpdateFlagManager } from "../UpdateFlagManager"; import { AnimationClip } from "./AnimationClip"; import { AnimatorStateTransition } from "./AnimatorTransition"; import { WrapMode } from "./enums/WrapMode"; @@ -18,6 +19,8 @@ export class AnimatorState { _onStateUpdateScripts: StateMachineScript[] = []; /** @internal */ _onStateExitScripts: StateMachineScript[] = []; + /** @internal */ + _updateFlagManager: UpdateFlagManager = new UpdateFlagManager(); private _clipStartTime: number = 0; private _clipEndTime: number = 1; @@ -39,8 +42,21 @@ export class AnimatorState { } set clip(clip: AnimationClip) { + const lastClip = this._clip; + if (lastClip === clip) { + return; + } + + if (lastClip) { + lastClip._updateFlagManager.removeListener(this._onClipChanged); + } + this._clip = clip; this._clipEndTime = Math.min(this._clipEndTime, 1); + + this._onClipChanged(); + + clip._updateFlagManager.addListener(this._onClipChanged); } /** @@ -68,7 +84,9 @@ export class AnimatorState { /** * @param name - The state's name */ - constructor(public readonly name: string) {} + constructor(public readonly name: string) { + this._onClipChanged = this._onClipChanged.bind(this); + } /** * Add an outgoing transition to the destination state. @@ -154,4 +172,11 @@ export class AnimatorState { index !== -1 && this._onStateExitScripts.splice(index, 1); } } + + /** + * @internal + */ + _onClipChanged(): void { + this._updateFlagManager.dispatch(); + } } diff --git a/packages/core/src/material/Material.ts b/packages/core/src/material/Material.ts index ff2a3cfb1..c6c6e3156 100644 --- a/packages/core/src/material/Material.ts +++ b/packages/core/src/material/Material.ts @@ -18,6 +18,8 @@ export class Material extends ReferResource implements IClone { _shader: Shader; /** @internal */ _renderStates: RenderState[] = []; // todo: later will as a part of shaderData when shader effect frame is OK, that is more powerful and flexible. + /** @internal */ + _priority: number = 0; // todo: temporary resolution of submesh rendering order issue. private _shaderData: ShaderData = new ShaderData(ShaderDataGroup.Material); diff --git a/packages/loader/src/resource-deserialize/resources/parser/ReflectionParser.ts b/packages/loader/src/resource-deserialize/resources/parser/ReflectionParser.ts index b8527e43b..e6ca2240b 100644 --- a/packages/loader/src/resource-deserialize/resources/parser/ReflectionParser.ts +++ b/packages/loader/src/resource-deserialize/resources/parser/ReflectionParser.ts @@ -18,6 +18,7 @@ export class ReflectionParser { if (position) entity.transform.position.copyFrom(position); if (rotation) entity.transform.rotation.copyFrom(rotation); if (scale) entity.transform.scale.copyFrom(scale); + entity.layer = entityConfig.layer ?? entity.layer; return entity; }); } diff --git a/packages/loader/src/resource-deserialize/resources/schema/BasicSchema.ts b/packages/loader/src/resource-deserialize/resources/schema/BasicSchema.ts index 174eb7f58..945d9c1eb 100644 --- a/packages/loader/src/resource-deserialize/resources/schema/BasicSchema.ts +++ b/packages/loader/src/resource-deserialize/resources/schema/BasicSchema.ts @@ -1,3 +1,5 @@ +import { Layer } from "@galacean/engine-core"; + export interface IVector3 { x: number; y: number; @@ -38,6 +40,7 @@ export interface IBasicEntity { scale?: IVector3; children?: Array; parent?: string; + layer?: Layer; } export type IEntity = IBasicEntity | IRefEntity; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index df47f72ad..cfb1bf140 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -46,7 +46,7 @@ importers: version: 18.17.0 '@types/webxr': specifier: latest - version: 0.5.1 + version: 0.5.2 '@typescript-eslint/eslint-plugin': specifier: ^6.1.0 version: 6.2.0(@typescript-eslint/parser@6.2.0)(eslint@8.46.0)(typescript@5.1.6) @@ -62,6 +62,12 @@ importers: cross-env: specifier: ^5.2.0 version: 5.2.1 + cypress: + specifier: ^12.17.1 + version: 12.17.1 + cypress-recurse: + specifier: ^1.23.0 + version: 1.23.0 electron: specifier: ^13 version: 13.6.9 @@ -77,6 +83,9 @@ importers: floss: specifier: ^5.0.1 version: 5.0.1(electron@13.6.9)(nyc@15.1.0) + fs-extra: + specifier: ^10.1.0 + version: 10.1.0 husky: specifier: ^8.0.0 version: 8.0.3 @@ -86,6 +95,9 @@ importers: nyc: specifier: ^15.1.0 version: 15.1.0 + odiff-bin: + specifier: ^2.5.0 + version: 2.5.0 prettier: specifier: ^3.0.0 version: 3.0.0 @@ -111,6 +123,42 @@ importers: specifier: ^5.1.6 version: 5.1.6 + e2e: + dependencies: + '@galacean/engine': + specifier: workspace:* + version: link:../packages/galacean + '@galacean/engine-core': + specifier: workspace:* + version: link:../packages/core + '@galacean/engine-design': + specifier: workspace:* + version: link:../packages/design + '@galacean/engine-loader': + specifier: workspace:* + version: link:../packages/loader + '@galacean/engine-math': + specifier: workspace:* + version: link:../packages/math + '@galacean/engine-physics-lite': + specifier: workspace:* + version: link:../packages/physics-lite + '@galacean/engine-rhi-webgl': + specifier: workspace:* + version: link:../packages/rhi-webgl + '@galacean/engine-toolkit': + specifier: ^1.0.0-beta.1 + version: 1.0.0-beta.1(@galacean/engine@packages+galacean) + dat.gui: + specifier: ^0.7.9 + version: 0.7.9 + sass: + specifier: ^1.55.0 + version: 1.55.0 + vite: + specifier: ^3.1.6 + version: 3.1.6(sass@1.55.0) + packages/core: dependencies: '@galacean/engine-math': @@ -300,7 +348,7 @@ packages: '@babel/traverse': 7.22.8 '@babel/types': 7.22.5 convert-source-map: 1.9.0 - debug: 4.3.4 + debug: 4.3.4(supports-color@8.1.1) gensync: 1.0.0-beta.2 json5: 2.2.3 semver: 6.3.1 @@ -458,7 +506,7 @@ packages: '@babel/helper-split-export-declaration': 7.22.6 '@babel/parser': 7.22.7 '@babel/types': 7.22.5 - debug: 4.3.4 + debug: 4.3.4(supports-color@8.1.1) globals: 11.12.0 transitivePeerDependencies: - supports-color @@ -503,6 +551,13 @@ packages: commander: 2.20.3 dev: true + /@colors/colors@1.5.0: + resolution: {integrity: sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==} + engines: {node: '>=0.1.90'} + requiresBuild: true + dev: true + optional: true + /@commitlint/cli@11.0.0: resolution: {integrity: sha512-YWZWg1DuqqO5Zjh7vUOeSX76vm0FFyz4y0cpGMFhrhvUi5unc4IVfCXZ6337R9zxuBtmveiRuuhQqnRRer+13g==} engines: {node: '>=v10.22.0'} @@ -647,11 +702,44 @@ packages: '@jridgewell/trace-mapping': 0.3.9 dev: true + /@cypress/request@2.88.12: + resolution: {integrity: sha512-tOn+0mDZxASFM+cuAP9szGUGPI1HwWVSvdzm7V4cCsPdFTx6qMj29CwaQmRAMIEhORIUBFBsYROYJcveK4uOjA==} + engines: {node: '>= 6'} + dependencies: + aws-sign2: 0.7.0 + aws4: 1.12.0 + caseless: 0.12.0 + combined-stream: 1.0.8 + extend: 3.0.2 + forever-agent: 0.6.1 + form-data: 2.3.3 + http-signature: 1.3.6 + is-typedarray: 1.0.0 + isstream: 0.1.2 + json-stringify-safe: 5.0.1 + mime-types: 2.1.35 + performance-now: 2.1.0 + qs: 6.10.4 + safe-buffer: 5.2.1 + tough-cookie: 4.1.3 + tunnel-agent: 0.6.0 + uuid: 8.3.2 + dev: true + + /@cypress/xvfb@1.2.4(supports-color@8.1.1): + resolution: {integrity: sha512-skbBzPggOVYCbnGgV+0dmBdW/s77ZkAOXIC1knS8NagwDjBrNC1LuXtQJeiN6l+m7lzmHtaoUw/ctJKdqkG57Q==} + dependencies: + debug: 3.2.7(supports-color@8.1.1) + lodash.once: 4.1.1 + transitivePeerDependencies: + - supports-color + dev: true + /@electron/get@1.14.1: resolution: {integrity: sha512-BrZYyL/6m0ZXz/lDxy/nlVhQz+WF+iPS6qXolEU8atw7h6v1aYkjwJZ63m+bJMBTxDE66X+r2tPS4a/8C82sZw==} engines: {node: '>=8.6'} dependencies: - debug: 4.3.4 + debug: 4.3.4(supports-color@8.1.1) env-paths: 2.2.1 fs-extra: 8.1.0 got: 9.6.0 @@ -665,6 +753,24 @@ packages: - supports-color dev: true + /@esbuild/android-arm@0.15.18: + resolution: {integrity: sha512-5GT+kcs2WVGjVs7+boataCkO5Fg0y4kCjzkB5bAip7H4jfnOS3dA6KPiww9W1OEKTKeAcUVhdZGvgI65OXmUnw==} + engines: {node: '>=12'} + cpu: [arm] + os: [android] + requiresBuild: true + dev: false + optional: true + + /@esbuild/linux-loong64@0.15.18: + resolution: {integrity: sha512-L4jVKS82XVhw2nvzLg/19ClLWg0y27ulRwuP7lcyL6AbUWB5aPglXY3M21mauDQMDfRLs8cQmeT03r/+X3cZYQ==} + engines: {node: '>=12'} + cpu: [loong64] + os: [linux] + requiresBuild: true + dev: false + optional: true + /@eslint-community/eslint-utils@4.4.0(eslint@8.46.0): resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -685,7 +791,7 @@ packages: engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dependencies: ajv: 6.12.6 - debug: 4.3.4 + debug: 4.3.4(supports-color@8.1.1) espree: 9.6.1 globals: 13.20.0 ignore: 5.2.4 @@ -706,12 +812,123 @@ packages: resolution: {integrity: sha512-J8TOSBq3SoZbDhM9+R/u77hP93gz/rajSA+K2kGyijPpORPWUXHUpTaleoj+92As0S9uPRP7Oi8IqMf0u+ro6A==} dev: true + /@galacean/engine-toolkit-auxiliary-lines@1.0.0-beta.1(@galacean/engine@packages+galacean): + resolution: {integrity: sha512-EvRBQc0gOhPeJUteyCyxOOqVB/Ls/lcp1CDbicH7Pxfv1Eyww+NFMNVN8RbvxPwcjMuZtzSvaaKgMx8KZK6WnQ==} + peerDependencies: + '@galacean/engine': ^1.0.0-alpha + dependencies: + '@galacean/engine': link:packages/galacean + '@galacean/engine-toolkit-custom-material': 1.0.0-beta.1(@galacean/engine@packages+galacean) + dev: false + + /@galacean/engine-toolkit-controls@1.0.0-beta.1(@galacean/engine@packages+galacean): + resolution: {integrity: sha512-q5yqPYfJlvGBXWUVt88dQUsEGDzg1VwUmp2mxOoJCcSDFBLE3ZdWUwnNOneIkkSTX/kNujOdBOPFbLMRDbMzNg==} + peerDependencies: + '@galacean/engine': ^1.0.0-alpha + dependencies: + '@galacean/engine': link:packages/galacean + dev: false + + /@galacean/engine-toolkit-custom-material@1.0.0-beta.1(@galacean/engine@packages+galacean): + resolution: {integrity: sha512-FqEacCNVUHo55CSKON+4LfMJgjRYmsBe4/ywFSNXQ9t+x0po8p4ztCyJwCSph1YdGzrk1hIbMGpFmlU6tCosrA==} + peerDependencies: + '@galacean/engine': ^1.0.0-alpha + dependencies: + '@galacean/engine': link:packages/galacean + dev: false + + /@galacean/engine-toolkit-framebuffer-picker@1.0.0-beta.1(@galacean/engine@packages+galacean): + resolution: {integrity: sha512-e/ZLiaIGJeuHcZUFPPLjdxxBF1WfScF1XJBwt3iMW6lRONYVlJbaq8up0Pcu74N6i4aytaEVTeAonf778SQyrg==} + peerDependencies: + '@galacean/engine': ^1.0.0-alpha + dependencies: + '@galacean/engine': link:packages/galacean + dev: false + + /@galacean/engine-toolkit-geometry-sketch@1.0.0-beta.1(@galacean/engine@packages+galacean): + resolution: {integrity: sha512-FyPkAOn/s/sLwrxKb1xQbE+DEmoT9jnCxYnPGRAawhEoypVDnvqQZoopELjsmQGecSmhCqvXuEO0yNQSdiW4lQ==} + peerDependencies: + '@galacean/engine': ^1.0.0-alpha + dependencies: + '@galacean/engine': link:packages/galacean + dev: false + + /@galacean/engine-toolkit-gizmo@1.0.0-beta.1(@galacean/engine@packages+galacean): + resolution: {integrity: sha512-9F5PXr5dYSjRXpq8FgZUmE4ziYOR0hJGmBY7y1nlrK/Zug8IMyza4epHyIIlbJAO3qIWI9A7PccrNZamg+79cw==} + peerDependencies: + '@galacean/engine': ^1.0.0-alpha + dependencies: + '@galacean/engine': link:packages/galacean + '@galacean/engine-toolkit-custom-material': 1.0.0-beta.1(@galacean/engine@packages+galacean) + '@galacean/engine-toolkit-framebuffer-picker': 1.0.0-beta.1(@galacean/engine@packages+galacean) + dev: false + + /@galacean/engine-toolkit-lines@1.0.0-beta.1(@galacean/engine@packages+galacean): + resolution: {integrity: sha512-Y9Pa5kXgQFFnI81a6hYGXhMvupUw2uMFMpcyUKKG9KJjEyJKwlh/rOAsMIVb23djlK1jD6n3SwEm4febiZhu1A==} + peerDependencies: + '@galacean/engine': ^1.0.0-alpha + dependencies: + '@galacean/engine': link:packages/galacean + dev: false + + /@galacean/engine-toolkit-navigation-gizmo@1.0.0-beta.1(@galacean/engine@packages+galacean): + resolution: {integrity: sha512-5/1k7uayO+5Wh51Pkvs5ipxT0WfCcZR5Iavzz8tHyPUMbbQrQcZZIwsOuTj57m9rUs5oDIyXKPl4t3QWTPXI3g==} + peerDependencies: + '@galacean/engine': ^1.0.0-alpha + dependencies: + '@galacean/engine': link:packages/galacean + '@galacean/engine-toolkit-controls': 1.0.0-beta.1(@galacean/engine@packages+galacean) + '@galacean/engine-toolkit-custom-material': 1.0.0-beta.1(@galacean/engine@packages+galacean) + dev: false + + /@galacean/engine-toolkit-outline@1.0.0-beta.1(@galacean/engine@packages+galacean): + resolution: {integrity: sha512-0mAHxMBYAWKo3OSHwCrl1w3GEYzfm1mYoG11Q/70feTSNNS+YkePJY2wvvvStflGmnqffDU3q+3sK6w6hxUH5w==} + peerDependencies: + '@galacean/engine': ^1.0.0-alpha + dependencies: + '@galacean/engine': link:packages/galacean + dev: false + + /@galacean/engine-toolkit-skeleton-viewer@1.0.0-beta.1(@galacean/engine@packages+galacean): + resolution: {integrity: sha512-Ni6nQ0GijPUYtMnWR5UUjIx9WitY48vB+FfO+QqEw17Yp+KfvuW9On2NKTxICKG/NTC/lg30L0xCYVgb+r7fNw==} + peerDependencies: + '@galacean/engine': ^1.0.0-alpha + dependencies: + '@galacean/engine': link:packages/galacean + dev: false + + /@galacean/engine-toolkit-stats@1.0.0-beta.1(@galacean/engine@packages+galacean): + resolution: {integrity: sha512-28RskztCxAfR7qHQU5c8zJzuok39pLC/5/0YgNXyIcCZtdBCOb2d+3fo3p17OMcT1JSquKipO3Ze7JoqI/EgfA==} + peerDependencies: + '@galacean/engine': ^1.0.0-alpha + dependencies: + '@galacean/engine': link:packages/galacean + dev: false + + /@galacean/engine-toolkit@1.0.0-beta.1(@galacean/engine@packages+galacean): + resolution: {integrity: sha512-TRB6NS5hXDNiAgsiEsymxGFzTHW70c6FNoESw/87G/BpMgZ1cGcA0yAIlSzeuAPkXO2w30/4CZSZTRpYsRpzpA==} + dependencies: + '@galacean/engine-toolkit-auxiliary-lines': 1.0.0-beta.1(@galacean/engine@packages+galacean) + '@galacean/engine-toolkit-controls': 1.0.0-beta.1(@galacean/engine@packages+galacean) + '@galacean/engine-toolkit-custom-material': 1.0.0-beta.1(@galacean/engine@packages+galacean) + '@galacean/engine-toolkit-framebuffer-picker': 1.0.0-beta.1(@galacean/engine@packages+galacean) + '@galacean/engine-toolkit-geometry-sketch': 1.0.0-beta.1(@galacean/engine@packages+galacean) + '@galacean/engine-toolkit-gizmo': 1.0.0-beta.1(@galacean/engine@packages+galacean) + '@galacean/engine-toolkit-lines': 1.0.0-beta.1(@galacean/engine@packages+galacean) + '@galacean/engine-toolkit-navigation-gizmo': 1.0.0-beta.1(@galacean/engine@packages+galacean) + '@galacean/engine-toolkit-outline': 1.0.0-beta.1(@galacean/engine@packages+galacean) + '@galacean/engine-toolkit-skeleton-viewer': 1.0.0-beta.1(@galacean/engine@packages+galacean) + '@galacean/engine-toolkit-stats': 1.0.0-beta.1(@galacean/engine@packages+galacean) + transitivePeerDependencies: + - '@galacean/engine' + dev: false + /@humanwhocodes/config-array@0.11.10: resolution: {integrity: sha512-KVVjQmNUepDVGXNuoRRdmmEjruj0KfiGSbS8LVc12LMsWDQzRXJ0qdhN8L8uUigKpfEHRhlaQFY0ib1tnUbNeQ==} engines: {node: '>=10.10.0'} dependencies: '@humanwhocodes/object-schema': 1.2.1 - debug: 4.3.4 + debug: 4.3.4(supports-color@8.1.1) minimatch: 3.1.2 transitivePeerDependencies: - supports-color @@ -1245,10 +1462,26 @@ packages: resolution: {integrity: sha512-G8hZ6XJiHnuhQKR7ZmysCeJWE08o8T0AXtk5darsCaTVsYZhhgUrq53jizaR2FvsoeCwJhlmwTjkXBY5Pn/ZHw==} dev: true - /@types/webxr@0.5.1: - resolution: {integrity: sha512-xlFXPfgJR5vIuDefhaHuUM9uUgvPaXB6GKdXy2gdEh8gBWQZ2ul24AJz3foUd8NNKlSTQuWYJpCb1/pL81m1KQ==} + /@types/sinonjs__fake-timers@8.1.1: + resolution: {integrity: sha512-0kSuKjAS0TrGLJ0M/+8MaFkGsQhZpB6pxOmvS3K8FYI72K//YmdfoW9X2qPsAKh1mkwxGD5zib9s1FIFed6E8g==} dev: true + /@types/sizzle@2.3.8: + resolution: {integrity: sha512-0vWLNK2D5MT9dg0iOo8GlKguPAU02QjmZitPEsXRuJXU/OGIOt9vT9Fc26wtYuavLxtO45v9PGleoL9Z0k1LHg==} + dev: true + + /@types/webxr@0.5.2: + resolution: {integrity: sha512-szL74BnIcok9m7QwYtVmQ+EdIKwbjPANudfuvDrAF8Cljg9MKUlIoc1w5tjj9PMpeSH3U1Xnx//czQybJ0EfSw==} + dev: true + + /@types/yauzl@2.10.3: + resolution: {integrity: sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==} + requiresBuild: true + dependencies: + '@types/node': 18.17.0 + dev: true + optional: true + /@typescript-eslint/eslint-plugin@6.2.0(@typescript-eslint/parser@6.2.0)(eslint@8.46.0)(typescript@5.1.6): resolution: {integrity: sha512-rClGrMuyS/3j0ETa1Ui7s6GkLhfZGKZL3ZrChLeAiACBE/tRc1wq8SNZESUuluxhLj9FkUefRs2l6bCIArWBiQ==} engines: {node: ^16.0.0 || >=18.0.0} @@ -1266,7 +1499,7 @@ packages: '@typescript-eslint/type-utils': 6.2.0(eslint@8.46.0)(typescript@5.1.6) '@typescript-eslint/utils': 6.2.0(eslint@8.46.0)(typescript@5.1.6) '@typescript-eslint/visitor-keys': 6.2.0 - debug: 4.3.4 + debug: 4.3.4(supports-color@8.1.1) eslint: 8.46.0 graphemer: 1.4.0 ignore: 5.2.4 @@ -1293,7 +1526,7 @@ packages: '@typescript-eslint/types': 6.2.0 '@typescript-eslint/typescript-estree': 6.2.0(typescript@5.1.6) '@typescript-eslint/visitor-keys': 6.2.0 - debug: 4.3.4 + debug: 4.3.4(supports-color@8.1.1) eslint: 8.46.0 typescript: 5.1.6 transitivePeerDependencies: @@ -1320,7 +1553,7 @@ packages: dependencies: '@typescript-eslint/typescript-estree': 6.2.0(typescript@5.1.6) '@typescript-eslint/utils': 6.2.0(eslint@8.46.0)(typescript@5.1.6) - debug: 4.3.4 + debug: 4.3.4(supports-color@8.1.1) eslint: 8.46.0 ts-api-utils: 1.0.1(typescript@5.1.6) typescript: 5.1.6 @@ -1344,7 +1577,7 @@ packages: dependencies: '@typescript-eslint/types': 6.2.0 '@typescript-eslint/visitor-keys': 6.2.0 - debug: 4.3.4 + debug: 4.3.4(supports-color@8.1.1) globby: 11.1.0 is-glob: 4.0.3 semver: 7.5.4 @@ -1482,7 +1715,6 @@ packages: dependencies: normalize-path: 3.0.0 picomatch: 2.3.1 - dev: true /append-transform@2.0.0: resolution: {integrity: sha512-7yeyCEurROLQJFv5Xj4lEGTy0borxepjFv1g22oAdqFu//SrAlDl1O1Nxx15SH1RoliUml6p8dwJW9jvZughhg==} @@ -1491,6 +1723,10 @@ packages: default-require-extensions: 3.0.1 dev: true + /arch@2.2.0: + resolution: {integrity: sha512-Of/R0wqp83cgHozfIYLbBMnej79U/SVGOOyuB3VVFv1NRM/PSFMK12x9KVtiYzJqmnU5WR2qp0Z5rHb7sWGnFQ==} + dev: true + /archy@1.0.0: resolution: {integrity: sha512-Xg+9RwCg/0p32teKdGMPTPnVXKD0w3DfHnFTficozsAgsvq2XenPJq/MYpzzQ/v8zrOyJn6Ds39VA4JIDwFfqw==} dev: true @@ -1523,6 +1759,17 @@ packages: engines: {node: '>=0.10.0'} dev: true + /asn1@0.2.6: + resolution: {integrity: sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==} + dependencies: + safer-buffer: 2.1.2 + dev: true + + /assert-plus@1.0.0: + resolution: {integrity: sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==} + engines: {node: '>=0.8'} + dev: true + /assertion-error@1.1.0: resolution: {integrity: sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==} dev: true @@ -1532,15 +1779,41 @@ packages: engines: {node: '>=8'} dev: true + /async@3.2.5: + resolution: {integrity: sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg==} + dev: true + + /asynckit@0.4.0: + resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} + dev: true + /at-least-node@1.0.0: resolution: {integrity: sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==} engines: {node: '>= 4.0.0'} dev: true + /aws-sign2@0.7.0: + resolution: {integrity: sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==} + dev: true + + /aws4@1.12.0: + resolution: {integrity: sha512-NmWvPnx0F1SfrQbYwOi7OeaNGokp9XhzNioJ/CSBs8Qa4vxug81mhJEAVZwxXuBmYB5KDRfMq/F3RR0BIU7sWg==} + dev: true + /balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} dev: true + /base64-js@1.5.1: + resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} + dev: true + + /bcrypt-pbkdf@1.0.2: + resolution: {integrity: sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==} + dependencies: + tweetnacl: 0.14.5 + dev: true + /big-integer@1.6.51: resolution: {integrity: sha512-GPEid2Y9QU1Exl1rpO9B2IPJGHPSupF5GnVIP0blYvNOMer2bTvSWs1jGOUg04hTmu67nmLsQ9TBo1puaotBHg==} engines: {node: '>=0.6'} @@ -1549,7 +1822,6 @@ packages: /binary-extensions@2.2.0: resolution: {integrity: sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==} engines: {node: '>=8'} - dev: true /bl@2.2.1: resolution: {integrity: sha512-6Pesp1w0DEX1N550i/uGV/TqucVL4AM/pgThFSN/Qq9si1/DF9aIHs1BxD8V/QU0HoeHO6cQRTAuYnLPKq1e4g==} @@ -1558,6 +1830,14 @@ packages: safe-buffer: 5.2.1 dev: true + /blob-util@2.0.2: + resolution: {integrity: sha512-T7JQa+zsXXEa6/8ZhHcQEW1UFfVM49Ts65uBkFL6fz2QmrElqmbajIDJvuA0tEhRe5eIjpV9ZF+0RfZR9voJFQ==} + dev: true + + /bluebird@3.7.2: + resolution: {integrity: sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==} + dev: true + /boolean@3.2.0: resolution: {integrity: sha512-d0II/GO9uf9lfUHH2BQsjxzRJZBdsjgsBiW4BvhWk/3qoKwQFjIDVN19PfX8F2D/r9PCMTtLWjYVCFrpeYUzsw==} requiresBuild: true @@ -1583,7 +1863,6 @@ packages: engines: {node: '>=8'} dependencies: fill-range: 7.0.1 - dev: true /browser-stdout@1.3.1: resolution: {integrity: sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==} @@ -1608,6 +1887,13 @@ packages: resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} dev: true + /buffer@5.7.1: + resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==} + dependencies: + base64-js: 1.5.1 + ieee754: 1.2.1 + dev: true + /builtin-modules@3.3.0: resolution: {integrity: sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==} engines: {node: '>=6'} @@ -1633,6 +1919,11 @@ packages: responselike: 1.0.2 dev: true + /cachedir@2.4.0: + resolution: {integrity: sha512-9EtFOZR8g22CL7BWjJ9BUx1+A/djkofnyW3aOXZORNW2kxoUpx2h+uN2cOqwPmFhnpVmxg+KW2OjOSgChTEvsQ==} + engines: {node: '>=6'} + dev: true + /caching-transform@4.0.0: resolution: {integrity: sha512-kpqOvwXnjjN44D89K5ccQC+RUrsy7jB/XLlRrx0D7/2HNcTPqzsb6XgYoErwko6QsV184CA2YgS1fxDiiDZMWA==} engines: {node: '>=8'} @@ -1643,6 +1934,14 @@ packages: write-file-atomic: 3.0.3 dev: true + /call-bind@1.0.5: + resolution: {integrity: sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ==} + dependencies: + function-bind: 1.1.2 + get-intrinsic: 1.2.1 + set-function-length: 1.1.1 + dev: true + /callsites@3.1.0: resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} engines: {node: '>=6'} @@ -1671,6 +1970,10 @@ packages: resolution: {integrity: sha512-Vdhm5S11DaFVLlyiKu4hiUTkpZu+y1KA/rZZqVQfOD5YdDT/eQKlkt7NaE0WGOFgX32diqt9MiP9CAiFeRklaA==} dev: true + /caseless@0.12.0: + resolution: {integrity: sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==} + dev: true + /chai-spies@1.0.0(chai@4.3.7): resolution: {integrity: sha512-elF2ZUczBsFoP07qCfMO/zeggs8pqCf3fZGyK5+2X4AndS8jycZYID91ztD9oQ7d/0tnS963dPkd0frQEThDsg==} engines: {node: '>= 4.0.0'} @@ -1722,6 +2025,11 @@ packages: resolution: {integrity: sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA==} dev: true + /check-more-types@2.24.0: + resolution: {integrity: sha512-Pj779qHxV2tuapviy1bSZNEL1maXr13bPYpsvSDB68HlYcYuhlDrmGd63i0JHMCLKzc7rUSNIrpdJlhVlNwrxA==} + engines: {node: '>= 0.8.0'} + dev: true + /chevrotain@10.5.0: resolution: {integrity: sha512-Pkv5rBY3+CsHOYfV5g/Vs5JY9WTHHDEKOlohI2XeygaZhUeqhAlldZ8Hz9cRmxu709bvS08YzxHdTPHhffc13A==} dependencies: @@ -1746,6 +2054,10 @@ packages: readdirp: 3.5.0 optionalDependencies: fsevents: 2.3.2 + + /ci-info@3.9.0: + resolution: {integrity: sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==} + engines: {node: '>=8'} dev: true /clean-stack@2.2.0: @@ -1760,6 +2072,15 @@ packages: restore-cursor: 3.1.0 dev: true + /cli-table3@0.6.3: + resolution: {integrity: sha512-w5Jac5SykAeZJKntOxJCrm63Eg5/4dhMWIcuTbo9rpE+brgaSZo0RuNJZeOyMgsUdhDeojvgyQLmjI+K50ZGyg==} + engines: {node: 10.* || >= 12.*} + dependencies: + string-width: 4.2.3 + optionalDependencies: + '@colors/colors': 1.5.0 + dev: true + /cli-truncate@2.1.0: resolution: {integrity: sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==} engines: {node: '>=8'} @@ -1815,6 +2136,13 @@ packages: resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==} dev: true + /combined-stream@1.0.8: + resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} + engines: {node: '>= 0.8'} + dependencies: + delayed-stream: 1.0.0 + dev: true + /commander@2.20.3: resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} dev: true @@ -1829,6 +2157,11 @@ packages: engines: {node: '>= 10'} dev: true + /common-tags@1.8.2: + resolution: {integrity: sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA==} + engines: {node: '>=4.0.0'} + dev: true + /commondir@1.0.1: resolution: {integrity: sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==} dev: true @@ -1902,6 +2235,10 @@ packages: requiresBuild: true dev: true + /core-util-is@1.0.2: + resolution: {integrity: sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==} + dev: true + /core-util-is@1.0.3: resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} dev: true @@ -1949,11 +2286,80 @@ packages: which: 2.0.2 dev: true + /cypress-recurse@1.23.0: + resolution: {integrity: sha512-CAsdvynhuR3SUEXVJRO2jBEnZRJ6nJp7nMXHwzV4UQq9Lap3Bj72AwcJK0cl51fJXcTaGDXYTQQ9zvGe3TyaQA==} + dev: true + + /cypress@12.17.1: + resolution: {integrity: sha512-eKfBgO6t8waEyhegL4gxD7tcI6uTCGttu+ZU7y9Hq8BlpMztd7iLeIF4AJFAnbZH1xjX+wwgg4cRKFNSvv3VWQ==} + engines: {node: ^14.0.0 || ^16.0.0 || >=18.0.0} + hasBin: true + requiresBuild: true + dependencies: + '@cypress/request': 2.88.12 + '@cypress/xvfb': 1.2.4(supports-color@8.1.1) + '@types/node': 14.18.54 + '@types/sinonjs__fake-timers': 8.1.1 + '@types/sizzle': 2.3.8 + arch: 2.2.0 + blob-util: 2.0.2 + bluebird: 3.7.2 + buffer: 5.7.1 + cachedir: 2.4.0 + chalk: 4.1.2 + check-more-types: 2.24.0 + cli-cursor: 3.1.0 + cli-table3: 0.6.3 + commander: 6.2.1 + common-tags: 1.8.2 + dayjs: 1.11.10 + debug: 4.3.4(supports-color@8.1.1) + enquirer: 2.3.6 + eventemitter2: 6.4.7 + execa: 4.1.0 + executable: 4.1.1 + extract-zip: 2.0.1(supports-color@8.1.1) + figures: 3.2.0 + fs-extra: 9.1.0 + getos: 3.2.1 + is-ci: 3.0.1 + is-installed-globally: 0.4.0 + lazy-ass: 1.6.0 + listr2: 3.14.0(enquirer@2.3.6) + lodash: 4.17.21 + log-symbols: 4.1.0 + minimist: 1.2.8 + ospath: 1.2.2 + pretty-bytes: 5.6.0 + proxy-from-env: 1.0.0 + request-progress: 3.0.0 + semver: 7.5.4 + supports-color: 8.1.1 + tmp: 0.2.1 + untildify: 4.0.0 + yauzl: 2.10.0 + dev: true + /dargs@7.0.0: resolution: {integrity: sha512-2iy1EkLdlBzQGvbweYRFxmFath8+K7+AKB0TlhHWkNuH+TmovaMH/Wp7V7R4u7f4SnX3OgLsU9t1NI9ioDnUpg==} engines: {node: '>=8'} dev: true + /dashdash@1.14.1: + resolution: {integrity: sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==} + engines: {node: '>=0.10'} + dependencies: + assert-plus: 1.0.0 + dev: true + + /dat.gui@0.7.9: + resolution: {integrity: sha512-sCNc1OHobc+Erc1HqiswYgHdVNpSJUlk/Hz8vzOCsER7rl+oF/4+v8GXFUyCgtXpoCX6+bnmg07DedLvBLwYKQ==} + dev: false + + /dayjs@1.11.10: + resolution: {integrity: sha512-vjAczensTgRcqDERK0SR2XMwsF/tSvnvlv6VcF2GIhg6Sx4yOIt/irsr1RDJsKiIyBzJDpCoXiWWq28MqH2cnQ==} + dev: true + /debug@2.6.9: resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==} peerDependencies: @@ -1965,6 +2371,18 @@ packages: ms: 2.0.0 dev: true + /debug@3.2.7(supports-color@8.1.1): + resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + dependencies: + ms: 2.1.3 + supports-color: 8.1.1 + dev: true + /debug@4.3.1(supports-color@8.1.1): resolution: {integrity: sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==} engines: {node: '>=6.0'} @@ -1978,7 +2396,7 @@ packages: supports-color: 8.1.1 dev: true - /debug@4.3.4: + /debug@4.3.4(supports-color@8.1.1): resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} engines: {node: '>=6.0'} peerDependencies: @@ -1988,6 +2406,7 @@ packages: optional: true dependencies: ms: 2.1.2 + supports-color: 8.1.1 dev: true /decamelize-keys@1.1.1: @@ -2064,6 +2483,15 @@ packages: resolution: {integrity: sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==} dev: true + /define-data-property@1.1.1: + resolution: {integrity: sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==} + engines: {node: '>= 0.4'} + dependencies: + get-intrinsic: 1.2.1 + gopd: 1.0.1 + has-property-descriptors: 1.0.0 + dev: true + /define-lazy-prop@3.0.0: resolution: {integrity: sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==} engines: {node: '>=12'} @@ -2079,6 +2507,11 @@ packages: dev: true optional: true + /delayed-stream@1.0.0: + resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} + engines: {node: '>=0.4.0'} + dev: true + /detect-node@2.1.0: resolution: {integrity: sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==} requiresBuild: true @@ -2129,6 +2562,13 @@ packages: stream-shift: 1.0.1 dev: true + /ecc-jsbn@0.1.2: + resolution: {integrity: sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==} + dependencies: + jsbn: 0.1.1 + safer-buffer: 2.1.2 + dev: true + /electron-to-chromium@1.4.468: resolution: {integrity: sha512-6M1qyhaJOt7rQtNti1lBA0GwclPH+oKCmsra/hkcWs5INLxfXXD/dtdnaKUYQu/pjOBP/8Osoe4mAcNvvzoFag==} dev: true @@ -2185,6 +2625,216 @@ packages: resolution: {integrity: sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==} dev: true + /esbuild-android-64@0.15.18: + resolution: {integrity: sha512-wnpt3OXRhcjfIDSZu9bnzT4/TNTDsOUvip0foZOUBG7QbSt//w3QV4FInVJxNhKc/ErhUxc5z4QjHtMi7/TbgA==} + engines: {node: '>=12'} + cpu: [x64] + os: [android] + requiresBuild: true + dev: false + optional: true + + /esbuild-android-arm64@0.15.18: + resolution: {integrity: sha512-G4xu89B8FCzav9XU8EjsXacCKSG2FT7wW9J6hOc18soEHJdtWu03L3TQDGf0geNxfLTtxENKBzMSq9LlbjS8OQ==} + engines: {node: '>=12'} + cpu: [arm64] + os: [android] + requiresBuild: true + dev: false + optional: true + + /esbuild-darwin-64@0.15.18: + resolution: {integrity: sha512-2WAvs95uPnVJPuYKP0Eqx+Dl/jaYseZEUUT1sjg97TJa4oBtbAKnPnl3b5M9l51/nbx7+QAEtuummJZW0sBEmg==} + engines: {node: '>=12'} + cpu: [x64] + os: [darwin] + requiresBuild: true + dev: false + optional: true + + /esbuild-darwin-arm64@0.15.18: + resolution: {integrity: sha512-tKPSxcTJ5OmNb1btVikATJ8NftlyNlc8BVNtyT/UAr62JFOhwHlnoPrhYWz09akBLHI9nElFVfWSTSRsrZiDUA==} + engines: {node: '>=12'} + cpu: [arm64] + os: [darwin] + requiresBuild: true + dev: false + optional: true + + /esbuild-freebsd-64@0.15.18: + resolution: {integrity: sha512-TT3uBUxkteAjR1QbsmvSsjpKjOX6UkCstr8nMr+q7zi3NuZ1oIpa8U41Y8I8dJH2fJgdC3Dj3CXO5biLQpfdZA==} + engines: {node: '>=12'} + cpu: [x64] + os: [freebsd] + requiresBuild: true + dev: false + optional: true + + /esbuild-freebsd-arm64@0.15.18: + resolution: {integrity: sha512-R/oVr+X3Tkh+S0+tL41wRMbdWtpWB8hEAMsOXDumSSa6qJR89U0S/PpLXrGF7Wk/JykfpWNokERUpCeHDl47wA==} + engines: {node: '>=12'} + cpu: [arm64] + os: [freebsd] + requiresBuild: true + dev: false + optional: true + + /esbuild-linux-32@0.15.18: + resolution: {integrity: sha512-lphF3HiCSYtaa9p1DtXndiQEeQDKPl9eN/XNoBf2amEghugNuqXNZA/ZovthNE2aa4EN43WroO0B85xVSjYkbg==} + engines: {node: '>=12'} + cpu: [ia32] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /esbuild-linux-64@0.15.18: + resolution: {integrity: sha512-hNSeP97IviD7oxLKFuii5sDPJ+QHeiFTFLoLm7NZQligur8poNOWGIgpQ7Qf8Balb69hptMZzyOBIPtY09GZYw==} + engines: {node: '>=12'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /esbuild-linux-arm64@0.15.18: + resolution: {integrity: sha512-54qr8kg/6ilcxd+0V3h9rjT4qmjc0CccMVWrjOEM/pEcUzt8X62HfBSeZfT2ECpM7104mk4yfQXkosY8Quptug==} + engines: {node: '>=12'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /esbuild-linux-arm@0.15.18: + resolution: {integrity: sha512-UH779gstRblS4aoS2qpMl3wjg7U0j+ygu3GjIeTonCcN79ZvpPee12Qun3vcdxX+37O5LFxz39XeW2I9bybMVA==} + engines: {node: '>=12'} + cpu: [arm] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /esbuild-linux-mips64le@0.15.18: + resolution: {integrity: sha512-Mk6Ppwzzz3YbMl/ZZL2P0q1tnYqh/trYZ1VfNP47C31yT0K8t9s7Z077QrDA/guU60tGNp2GOwCQnp+DYv7bxQ==} + engines: {node: '>=12'} + cpu: [mips64el] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /esbuild-linux-ppc64le@0.15.18: + resolution: {integrity: sha512-b0XkN4pL9WUulPTa/VKHx2wLCgvIAbgwABGnKMY19WhKZPT+8BxhZdqz6EgkqCLld7X5qiCY2F/bfpUUlnFZ9w==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /esbuild-linux-riscv64@0.15.18: + resolution: {integrity: sha512-ba2COaoF5wL6VLZWn04k+ACZjZ6NYniMSQStodFKH/Pu6RxzQqzsmjR1t9QC89VYJxBeyVPTaHuBMCejl3O/xg==} + engines: {node: '>=12'} + cpu: [riscv64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /esbuild-linux-s390x@0.15.18: + resolution: {integrity: sha512-VbpGuXEl5FCs1wDVp93O8UIzl3ZrglgnSQ+Hu79g7hZu6te6/YHgVJxCM2SqfIila0J3k0csfnf8VD2W7u2kzQ==} + engines: {node: '>=12'} + cpu: [s390x] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /esbuild-netbsd-64@0.15.18: + resolution: {integrity: sha512-98ukeCdvdX7wr1vUYQzKo4kQ0N2p27H7I11maINv73fVEXt2kyh4K4m9f35U1K43Xc2QGXlzAw0K9yoU7JUjOg==} + engines: {node: '>=12'} + cpu: [x64] + os: [netbsd] + requiresBuild: true + dev: false + optional: true + + /esbuild-openbsd-64@0.15.18: + resolution: {integrity: sha512-yK5NCcH31Uae076AyQAXeJzt/vxIo9+omZRKj1pauhk3ITuADzuOx5N2fdHrAKPxN+zH3w96uFKlY7yIn490xQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [openbsd] + requiresBuild: true + dev: false + optional: true + + /esbuild-sunos-64@0.15.18: + resolution: {integrity: sha512-On22LLFlBeLNj/YF3FT+cXcyKPEI263nflYlAhz5crxtp3yRG1Ugfr7ITyxmCmjm4vbN/dGrb/B7w7U8yJR9yw==} + engines: {node: '>=12'} + cpu: [x64] + os: [sunos] + requiresBuild: true + dev: false + optional: true + + /esbuild-windows-32@0.15.18: + resolution: {integrity: sha512-o+eyLu2MjVny/nt+E0uPnBxYuJHBvho8vWsC2lV61A7wwTWC3jkN2w36jtA+yv1UgYkHRihPuQsL23hsCYGcOQ==} + engines: {node: '>=12'} + cpu: [ia32] + os: [win32] + requiresBuild: true + dev: false + optional: true + + /esbuild-windows-64@0.15.18: + resolution: {integrity: sha512-qinug1iTTaIIrCorAUjR0fcBk24fjzEedFYhhispP8Oc7SFvs+XeW3YpAKiKp8dRpizl4YYAhxMjlftAMJiaUw==} + engines: {node: '>=12'} + cpu: [x64] + os: [win32] + requiresBuild: true + dev: false + optional: true + + /esbuild-windows-arm64@0.15.18: + resolution: {integrity: sha512-q9bsYzegpZcLziq0zgUi5KqGVtfhjxGbnksaBFYmWLxeV/S1fK4OLdq2DFYnXcLMjlZw2L0jLsk1eGoB522WXQ==} + engines: {node: '>=12'} + cpu: [arm64] + os: [win32] + requiresBuild: true + dev: false + optional: true + + /esbuild@0.15.18: + resolution: {integrity: sha512-x/R72SmW3sSFRm5zrrIjAhCeQSAWoni3CmHEqfQrZIQTM3lVCdehdwuIqaOtfC2slvpdlLa62GYoN8SxT23m6Q==} + engines: {node: '>=12'} + hasBin: true + requiresBuild: true + optionalDependencies: + '@esbuild/android-arm': 0.15.18 + '@esbuild/linux-loong64': 0.15.18 + esbuild-android-64: 0.15.18 + esbuild-android-arm64: 0.15.18 + esbuild-darwin-64: 0.15.18 + esbuild-darwin-arm64: 0.15.18 + esbuild-freebsd-64: 0.15.18 + esbuild-freebsd-arm64: 0.15.18 + esbuild-linux-32: 0.15.18 + esbuild-linux-64: 0.15.18 + esbuild-linux-arm: 0.15.18 + esbuild-linux-arm64: 0.15.18 + esbuild-linux-mips64le: 0.15.18 + esbuild-linux-ppc64le: 0.15.18 + esbuild-linux-riscv64: 0.15.18 + esbuild-linux-s390x: 0.15.18 + esbuild-netbsd-64: 0.15.18 + esbuild-openbsd-64: 0.15.18 + esbuild-sunos-64: 0.15.18 + esbuild-windows-32: 0.15.18 + esbuild-windows-64: 0.15.18 + esbuild-windows-arm64: 0.15.18 + dev: false + /escalade@3.1.1: resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==} engines: {node: '>=6'} @@ -2271,7 +2921,7 @@ packages: ajv: 6.12.6 chalk: 4.1.2 cross-spawn: 7.0.3 - debug: 4.3.4 + debug: 4.3.4(supports-color@8.1.1) doctrine: 3.0.0 escape-string-regexp: 4.0.0 eslint-scope: 7.2.2 @@ -2358,6 +3008,10 @@ packages: engines: {node: '>=0.10.0'} dev: true + /eventemitter2@6.4.7: + resolution: {integrity: sha512-tYUSVOGeQPKt/eC1ABfhHy5Xd96N3oIijJvN3O9+TsC28T5V9yX9oEfEK5faP0EFSNVOG97qtAS68GBrQB2hDg==} + dev: true + /events@3.3.0: resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==} engines: {node: '>=0.8.x'} @@ -2408,6 +3062,17 @@ packages: strip-final-newline: 3.0.0 dev: true + /executable@4.1.1: + resolution: {integrity: sha512-8iA79xD3uAch729dUG8xaaBBFGaEa0wdD2VkYLFHwlqosEj/jT66AzcreRDSgV7ehnNLBW2WR5jIXwGKjVdTLg==} + engines: {node: '>=4'} + dependencies: + pify: 2.3.0 + dev: true + + /extend@3.0.2: + resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==} + dev: true + /extract-zip@1.7.0: resolution: {integrity: sha512-xoh5G1W/PB0/27lXgMQyIhP5DSY/LhoCsOyZgb+6iMmRtCwVBo55uKaMoEYrDCKQhWvqEip5ZPKAc6eFNyf/MA==} hasBin: true @@ -2420,6 +3085,25 @@ packages: - supports-color dev: true + /extract-zip@2.0.1(supports-color@8.1.1): + resolution: {integrity: sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==} + engines: {node: '>= 10.17.0'} + hasBin: true + dependencies: + debug: 4.3.4(supports-color@8.1.1) + get-stream: 5.2.0 + yauzl: 2.10.0 + optionalDependencies: + '@types/yauzl': 2.10.3 + transitivePeerDependencies: + - supports-color + dev: true + + /extsprintf@1.3.0: + resolution: {integrity: sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==} + engines: {'0': node >=0.6.0} + dev: true + /falafel@2.2.5: resolution: {integrity: sha512-HuC1qF9iTnHDnML9YZAdCDQwT0yKl/U55K4XSUXqGAA2GLoafFgWRqdAbhWJxXaYD4pyoVxAJ8wH670jMpI9DQ==} engines: {node: '>=0.4.0'} @@ -2467,6 +3151,13 @@ packages: pend: 1.2.0 dev: true + /figures@3.2.0: + resolution: {integrity: sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==} + engines: {node: '>=8'} + dependencies: + escape-string-regexp: 1.0.5 + dev: true + /file-entry-cache@6.0.1: resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==} engines: {node: ^10.12.0 || >=12.0.0} @@ -2479,7 +3170,6 @@ packages: engines: {node: '>=8'} dependencies: to-regex-range: 5.0.1 - dev: true /find-cache-dir@3.3.2: resolution: {integrity: sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==} @@ -2548,6 +3238,19 @@ packages: signal-exit: 3.0.7 dev: true + /forever-agent@0.6.1: + resolution: {integrity: sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==} + dev: true + + /form-data@2.3.3: + resolution: {integrity: sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==} + engines: {node: '>= 0.12'} + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + mime-types: 2.1.35 + dev: true + /from2@2.3.0: resolution: {integrity: sha512-OMcX/4IC/uqEPVgGeyfN22LJk6AZrMkRZHxcHBMBvHScDGgwTm2GT2Wkgtocyd3JfZffjj2kYUDXXII0Fk9W0g==} dependencies: @@ -2559,6 +3262,15 @@ packages: resolution: {integrity: sha512-cHEpEQHUg0f8XdtZCc2ZAhrHzKzT0MrFUTcvx+hfxYu7rGMDc5SKoXFh+n4YigxsHXRzc6OrCshdR1bWH6HHyg==} dev: true + /fs-extra@10.1.0: + resolution: {integrity: sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==} + engines: {node: '>=12'} + dependencies: + graceful-fs: 4.2.11 + jsonfile: 6.1.0 + universalify: 2.0.0 + dev: true + /fs-extra@8.1.0: resolution: {integrity: sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==} engines: {node: '>=6 <7 || >=8'} @@ -2587,11 +3299,13 @@ packages: engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} os: [darwin] requiresBuild: true - dev: true optional: true /function-bind@1.1.1: resolution: {integrity: sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==} + + /function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} dev: true /gensync@1.0.0-beta.2: @@ -2617,7 +3331,6 @@ packages: has-proto: 1.0.1 has-symbols: 1.0.3 dev: true - optional: true /get-own-enumerable-property-symbols@3.0.2: resolution: {integrity: sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g==} @@ -2658,6 +3371,18 @@ packages: resolve-pkg-maps: 1.0.0 dev: true + /getos@3.2.1: + resolution: {integrity: sha512-U56CfOK17OKgTVqozZjUKNdkfEv6jk5WISBJ8SHoagjE6L69zOwl3Z+O8myjY9MEW3i2HPWQBt/LTbCgcC973Q==} + dependencies: + async: 3.2.5 + dev: true + + /getpass@0.1.7: + resolution: {integrity: sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==} + dependencies: + assert-plus: 1.0.0 + dev: true + /git-raw-commits@2.0.11: resolution: {integrity: sha512-VnctFhw+xfj8Va1xtfEqCUD2XDrbAPSJx+hSrE5K7fGdjZruW7XV+QOrN7LF/RJyvspRiD2I0asWsxFp0ya26A==} engines: {node: '>=10'} @@ -2675,7 +3400,6 @@ packages: engines: {node: '>= 6'} dependencies: is-glob: 4.0.3 - dev: true /glob-parent@6.0.2: resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} @@ -2727,6 +3451,13 @@ packages: ini: 1.3.8 dev: true + /global-dirs@3.0.1: + resolution: {integrity: sha512-NBcGGFbBA9s1VzD41QXDG+3++t9Mn5t1FpLdhESY6oKY4gYTFpX4wO3sqGUa0Srjtbfj3szX0RnemmrVRUdULA==} + engines: {node: '>=10'} + dependencies: + ini: 2.0.0 + dev: true + /global-tunnel-ng@2.7.1: resolution: {integrity: sha512-4s+DyciWBV0eK148wqXxcmVAbFVPqtc3sEtUE/GTQfuU80rySLcMhUmHKSHI7/LDj8q0gDYI1lIhRRB7ieRAqg==} engines: {node: '>=0.10'} @@ -2885,6 +3616,12 @@ packages: xtend: 4.0.2 dev: true + /gopd@1.0.1: + resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==} + dependencies: + get-intrinsic: 1.2.1 + dev: true + /got@9.6.0: resolution: {integrity: sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==} engines: {node: '>=8.6'} @@ -2938,28 +3675,24 @@ packages: dependencies: get-intrinsic: 1.2.1 dev: true - optional: true /has-proto@1.0.1: resolution: {integrity: sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==} engines: {node: '>= 0.4'} requiresBuild: true dev: true - optional: true /has-symbols@1.0.3: resolution: {integrity: sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==} engines: {node: '>= 0.4'} requiresBuild: true dev: true - optional: true /has@1.0.3: resolution: {integrity: sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==} engines: {node: '>= 0.4.0'} dependencies: function-bind: 1.1.1 - dev: true /hasha@5.2.2: resolution: {integrity: sha512-Hrp5vIK/xr5SkeN2onO32H0MgNZ0f17HRNH39WfL0SYUNOTZ5Lz1TJ8Pajo/87dYGEFlLMm7mIc/k/s6Bvz9HQ==} @@ -2993,6 +3726,15 @@ packages: resolution: {integrity: sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==} dev: true + /http-signature@1.3.6: + resolution: {integrity: sha512-3adrsD6zqo4GsTqtO7FyrejHNv+NgiIfAfv68+jVlFmSr9OGy7zrxONceFRLKvnnZA5jbxQBX1u9PpB6Wi32Gw==} + engines: {node: '>=0.10'} + dependencies: + assert-plus: 1.0.0 + jsprim: 2.0.2 + sshpk: 1.18.0 + dev: true + /human-signals@1.1.1: resolution: {integrity: sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==} engines: {node: '>=8.12.0'} @@ -3014,11 +3756,19 @@ packages: hasBin: true dev: true + /ieee754@1.2.1: + resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} + dev: true + /ignore@5.2.4: resolution: {integrity: sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==} engines: {node: '>= 4'} dev: true + /immutable@4.3.4: + resolution: {integrity: sha512-fsXeu4J4i6WNWSikpI88v/PcVflZz+6kMhUfIwc5SY+poQRPnaf5V7qds6SUyUN3cVxEzuCab7QIoLOQ+DQ1wA==} + dev: false + /import-fresh@3.3.0: resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==} engines: {node: '>=6'} @@ -3052,6 +3802,11 @@ packages: resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==} dev: true + /ini@2.0.0: + resolution: {integrity: sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==} + engines: {node: '>=10'} + dev: true + /is-arrayish@0.2.1: resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} dev: true @@ -3061,13 +3816,18 @@ packages: engines: {node: '>=8'} dependencies: binary-extensions: 2.2.0 + + /is-ci@3.0.1: + resolution: {integrity: sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ==} + hasBin: true + dependencies: + ci-info: 3.9.0 dev: true /is-core-module@2.12.1: resolution: {integrity: sha512-Q4ZuBAe2FUsKtyQJoQHlvP8OvBERxO3jEmy1I7hcRXcJBGGHFh/aJBswbXuS9sgrDH2QUO8ilkwNPHvHMd8clg==} dependencies: has: 1.0.3 - dev: true /is-docker@2.2.1: resolution: {integrity: sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==} @@ -3084,7 +3844,6 @@ packages: /is-extglob@2.1.1: resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} engines: {node: '>=0.10.0'} - dev: true /is-fullwidth-code-point@2.0.0: resolution: {integrity: sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==} @@ -3101,7 +3860,6 @@ packages: engines: {node: '>=0.10.0'} dependencies: is-extglob: 2.1.1 - dev: true /is-inside-container@1.0.0: resolution: {integrity: sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==} @@ -3111,6 +3869,14 @@ packages: is-docker: 3.0.0 dev: true + /is-installed-globally@0.4.0: + resolution: {integrity: sha512-iwGqO3J21aaSkC7jWnHP/difazwS7SFeIqxv6wEtLU8Y5KlzFTjyqcSIT0d8s4+dDhKytsk9PJZ2BkS5eZwQRQ==} + engines: {node: '>=10'} + dependencies: + global-dirs: 3.0.1 + is-path-inside: 3.0.3 + dev: true + /is-module@1.0.0: resolution: {integrity: sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==} dev: true @@ -3118,7 +3884,6 @@ packages: /is-number@7.0.0: resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} engines: {node: '>=0.12.0'} - dev: true /is-obj@1.0.1: resolution: {integrity: sha512-l4RyHgRqGN4Y3+9JHVrNqO+tN0rV5My76uW5/nuO4K1b6vw5G8d/cmFjP9tRfEsdhZNt0IFdZuK/c2Vr4Nb+Qg==} @@ -3210,6 +3975,10 @@ packages: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} dev: true + /isstream@0.1.2: + resolution: {integrity: sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==} + dev: true + /istanbul-lib-coverage@3.2.0: resolution: {integrity: sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==} engines: {node: '>=8'} @@ -3259,7 +4028,7 @@ packages: resolution: {integrity: sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==} engines: {node: '>=10'} dependencies: - debug: 4.3.4 + debug: 4.3.4(supports-color@8.1.1) istanbul-lib-coverage: 3.2.0 source-map: 0.6.1 transitivePeerDependencies: @@ -3300,6 +4069,10 @@ packages: argparse: 2.0.1 dev: true + /jsbn@0.1.1: + resolution: {integrity: sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==} + dev: true + /jsesc@2.5.2: resolution: {integrity: sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==} engines: {node: '>=4'} @@ -3318,6 +4091,10 @@ packages: resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} dev: true + /json-schema@0.4.0: + resolution: {integrity: sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==} + dev: true + /json-stable-stringify-without-jsonify@1.0.1: resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} dev: true @@ -3326,7 +4103,6 @@ packages: resolution: {integrity: sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==} requiresBuild: true dev: true - optional: true /json5@2.2.3: resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} @@ -3353,6 +4129,16 @@ packages: engines: {'0': node >= 0.2.0} dev: true + /jsprim@2.0.2: + resolution: {integrity: sha512-gqXddjPqQ6G40VdnI6T6yObEC+pDNvyP95wdQhkWkg7crHH3km5qP1FsOXEkzEQwnz6gz5qGTn1c2Y52wP3OyQ==} + engines: {'0': node >=0.6.0} + dependencies: + assert-plus: 1.0.0 + extsprintf: 1.3.0 + json-schema: 0.4.0 + verror: 1.10.0 + dev: true + /keyv@3.1.0: resolution: {integrity: sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==} dependencies: @@ -3364,6 +4150,11 @@ packages: engines: {node: '>=0.10.0'} dev: true + /lazy-ass@1.6.0: + resolution: {integrity: sha512-cc8oEVoctTvsFZ/Oje/kGnHbpWHYBe8IAJe4C0QNc3t8uM/0Y8+erSz/7Y1ALuXTEZTMvxXwO6YbX1ey3ujiZw==} + engines: {node: '> 0.8'} + dev: true + /levn@0.3.0: resolution: {integrity: sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==} engines: {node: '>= 0.8.0'} @@ -3392,7 +4183,7 @@ packages: cli-truncate: 2.1.0 commander: 6.2.1 cosmiconfig: 7.1.0 - debug: 4.3.4 + debug: 4.3.4(supports-color@8.1.1) dedent: 0.7.0 enquirer: 2.3.6 execa: 4.1.0 @@ -3449,6 +4240,10 @@ packages: resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} dev: true + /lodash.once@4.1.1: + resolution: {integrity: sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==} + dev: true + /lodash@4.17.21: resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} @@ -3588,6 +4383,18 @@ packages: picomatch: 2.3.1 dev: true + /mime-db@1.52.0: + resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} + engines: {node: '>= 0.6'} + dev: true + + /mime-types@2.1.35: + resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} + engines: {node: '>= 0.6'} + dependencies: + mime-db: 1.52.0 + dev: true + /mime@3.0.0: resolution: {integrity: sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==} engines: {node: '>=10.0.0'} @@ -3700,6 +4507,12 @@ packages: hasBin: true dev: true + /nanoid@3.3.7: + resolution: {integrity: sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + dev: false + /natural-compare-lite@1.4.0: resolution: {integrity: sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==} dev: true @@ -3745,7 +4558,6 @@ packages: /normalize-path@3.0.0: resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} engines: {node: '>=0.10.0'} - dev: true /normalize-url@4.5.1: resolution: {integrity: sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA==} @@ -3812,6 +4624,10 @@ packages: - supports-color dev: true + /object-inspect@1.13.1: + resolution: {integrity: sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==} + dev: true + /object-keys@1.1.1: resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} engines: {node: '>= 0.4'} @@ -3819,6 +4635,12 @@ packages: dev: true optional: true + /odiff-bin@2.5.0: + resolution: {integrity: sha512-wquvVqZltr0w3IFWTjiWloNjlIDaMq0aWoWLStV9GHWRjio1Pznh1UkWkVWp8UukT/TiHoFKrRC47viZVOnmsA==} + hasBin: true + requiresBuild: true + dev: true + /once@1.3.3: resolution: {integrity: sha512-6vaNInhu+CHxtONf3zw3vq4SP2DOQhjBvIa3rNcG0+P7eKWlYH6Peu7rHizSloRU2EwMz6GraLieis9Ac9+p1w==} dependencies: @@ -3884,6 +4706,10 @@ packages: type-check: 0.4.0 dev: true + /ospath@1.2.2: + resolution: {integrity: sha512-o6E5qJV5zkAbIDNhGSIlyOhScKXgQrSRMilfph0clDfM0nEnBOlKlH4sWDmG95BW/CvwNz0vmm7dJVtU2KlMiA==} + dev: true + /ospec@3.1.0: resolution: {integrity: sha512-+nGtjV3vlADp+UGfL51miAh/hB4awPBkQrArhcgG4trAaoA2gKt5bf9w0m9ch9zOr555cHWaCHZEDiBOkNZSxw==} hasBin: true @@ -3997,7 +4823,6 @@ packages: /path-parse@1.0.7: resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} - dev: true /path-type@4.0.0: resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} @@ -4012,13 +4837,20 @@ packages: resolution: {integrity: sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==} dev: true + /performance-now@2.1.0: + resolution: {integrity: sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==} + dev: true + /picocolors@1.0.0: resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==} - dev: true /picomatch@2.3.1: resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} engines: {node: '>=8.6'} + + /pify@2.3.0: + resolution: {integrity: sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==} + engines: {node: '>=0.10.0'} dev: true /pify@3.0.0: @@ -4041,6 +4873,15 @@ packages: semver-compare: 1.0.0 dev: true + /postcss@8.4.32: + resolution: {integrity: sha512-D/kj5JNu6oo2EIy+XL/26JEDTlIbB8hw85G8StOE6L74RQAVVP5rej6wxCNqyMbR4RkPfqvezVbPw81Ngd6Kcw==} + engines: {node: ^10 || ^12 || >=14} + dependencies: + nanoid: 3.3.7 + picocolors: 1.0.0 + source-map-js: 1.0.2 + dev: false + /prelude-ls@1.1.2: resolution: {integrity: sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==} engines: {node: '>= 0.8.0'} @@ -4069,6 +4910,11 @@ packages: hasBin: true dev: true + /pretty-bytes@5.6.0: + resolution: {integrity: sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==} + engines: {node: '>=6'} + dev: true + /process-nextick-args@2.0.1: resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} dev: true @@ -4091,6 +4937,14 @@ packages: dev: true optional: true + /proxy-from-env@1.0.0: + resolution: {integrity: sha512-F2JHgJQ1iqwnHDcQjVBsq3n/uoaFL+iPW/eAeL7kVxy/2RrWaN4WroKjjvbsoRtv0ftelNyC01bjRhn/bhcf4A==} + dev: true + + /psl@1.9.0: + resolution: {integrity: sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==} + dev: true + /pump@3.0.0: resolution: {integrity: sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==} dependencies: @@ -4108,6 +4962,17 @@ packages: engines: {node: '>=0.6.0', teleport: '>=0.2.0'} dev: true + /qs@6.10.4: + resolution: {integrity: sha512-OQiU+C+Ds5qiH91qh/mg0w+8nwQuLjM4F4M/PbmhDOoYehPh+Fb0bDjtR1sOvy7YKxvj28Y/M0PhP5uVX0kB+g==} + engines: {node: '>=0.6'} + dependencies: + side-channel: 1.0.4 + dev: true + + /querystringify@2.2.0: + resolution: {integrity: sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==} + dev: true + /queue-microtask@1.2.3: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} dev: true @@ -4177,7 +5042,6 @@ packages: engines: {node: '>=8.10.0'} dependencies: picomatch: 2.3.1 - dev: true /redent@3.0.0: resolution: {integrity: sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==} @@ -4202,6 +5066,12 @@ packages: es6-error: 4.1.1 dev: true + /request-progress@3.0.0: + resolution: {integrity: sha512-MnWzEHHaxHO2iWiQuHrUPBi/1WeBf5PkxQqNyNvLl9VAYSdXkP8tQ3pBSeCPD+yw0v0Aq1zosWLz0BdeXpWwZg==} + dependencies: + throttleit: 1.0.1 + dev: true + /require-directory@2.1.1: resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} engines: {node: '>=0.10.0'} @@ -4211,6 +5081,10 @@ packages: resolution: {integrity: sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==} dev: true + /requires-port@1.0.0: + resolution: {integrity: sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==} + dev: true + /resolve-from@4.0.0: resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} engines: {node: '>=4'} @@ -4243,7 +5117,6 @@ packages: is-core-module: 2.12.1 path-parse: 1.0.7 supports-preserve-symlinks-flag: 1.0.0 - dev: true /responselike@1.0.2: resolution: {integrity: sha512-/Fpe5guzJk1gPqdJLJR5u7eG/gNY4nImjbRDaVWVMRhne55TCmj2i9Q+54PBRfatRC8v/rIiv9BN0pMd9OV5EQ==} @@ -4342,6 +5215,14 @@ packages: rollup: 2.79.1 dev: true + /rollup@2.78.1: + resolution: {integrity: sha512-VeeCgtGi4P+o9hIg+xz4qQpRl6R401LWEXBmxYKOV4zlF82lyhgh2hTZnheFUbANE8l2A41F458iwj2vEYaXJg==} + engines: {node: '>=10.0.0'} + hasBin: true + optionalDependencies: + fsevents: 2.3.2 + dev: false + /rollup@2.79.1: resolution: {integrity: sha512-uKxbd0IhMZOhjAiD5oAFp7BqvkA4Dv47qpOCtaNvng4HBwdbWtdOh8f5nZNuk2rp51PMGk3bzfWu5oayNEuYnw==} engines: {node: '>=10.0.0'} @@ -4377,6 +5258,20 @@ packages: resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} dev: true + /safer-buffer@2.1.2: + resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + dev: true + + /sass@1.55.0: + resolution: {integrity: sha512-Pk+PMy7OGLs9WaxZGJMn7S96dvlyVBwwtToX895WmCpAOr5YiJYEUJfiJidMuKb613z2xNWcXCHEuOvjZbqC6A==} + engines: {node: '>=12.0.0'} + hasBin: true + dependencies: + chokidar: 3.5.1 + immutable: 4.3.4 + source-map-js: 1.0.2 + dev: false + /semver-compare@1.0.0: resolution: {integrity: sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow==} dev: true @@ -4424,6 +5319,16 @@ packages: resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==} dev: true + /set-function-length@1.1.1: + resolution: {integrity: sha512-VoaqjbBJKiWtg4yRcKBQ7g7wnGnLV3M8oLvVWwOk2PdYY6PEFegR1vezXR0tw6fZGF9csVakIRjrJiy2veSBFQ==} + engines: {node: '>= 0.4'} + dependencies: + define-data-property: 1.1.1 + get-intrinsic: 1.2.1 + gopd: 1.0.1 + has-property-descriptors: 1.0.0 + dev: true + /shallow-copy@0.0.1: resolution: {integrity: sha512-b6i4ZpVuUxB9h5gfCxPiusKYkqTMOjEbBs4wMaFbkfia4yFv92UKZ6Df8WXcKbn08JNL/abvg3FnMAOfakDvUw==} dev: true @@ -4452,6 +5357,14 @@ packages: engines: {node: '>=8'} dev: true + /side-channel@1.0.4: + resolution: {integrity: sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==} + dependencies: + call-bind: 1.0.5 + get-intrinsic: 1.2.1 + object-inspect: 1.13.1 + dev: true + /signal-exit@3.0.7: resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} dev: true @@ -4479,6 +5392,11 @@ packages: is-fullwidth-code-point: 3.0.0 dev: true + /source-map-js@1.0.2: + resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==} + engines: {node: '>=0.10.0'} + dev: false + /source-map@0.6.1: resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} engines: {node: '>=0.10.0'} @@ -4539,6 +5457,22 @@ packages: dev: true optional: true + /sshpk@1.18.0: + resolution: {integrity: sha512-2p2KJZTSqQ/I3+HX42EpYOa2l3f8Erv8MWKsy2I9uf4wA7yFIkXRffYdsx86y6z4vHtV8u7g+pPlr8/4ouAxsQ==} + engines: {node: '>=0.10.0'} + hasBin: true + dependencies: + asn1: 0.2.6 + assert-plus: 1.0.0 + bcrypt-pbkdf: 1.0.2 + dashdash: 1.14.1 + ecc-jsbn: 0.1.2 + getpass: 0.1.7 + jsbn: 0.1.1 + safer-buffer: 2.1.2 + tweetnacl: 0.14.5 + dev: true + /stack-trace@0.0.9: resolution: {integrity: sha512-vjUc6sfgtgY0dxCdnc40mK6Oftjo9+2K8H/NG81TMhgL392FtiPA9tn9RLyTxXmTLPJPjF3VyzFp6bsWFLisMQ==} dev: true @@ -4645,7 +5579,7 @@ packages: resolution: {integrity: sha512-MvjXzkz/BOfyVDkG0oFOtBxHX2u3gKbMHIF/dXblZsgD3BWOFLmHovIpZY7BykJdAjcqRCBi1WYBNdEC9yI7vg==} engines: {node: '>= 8.0'} dependencies: - debug: 4.3.4 + debug: 4.3.4(supports-color@8.1.1) transitivePeerDependencies: - supports-color dev: true @@ -4674,7 +5608,6 @@ packages: /supports-preserve-symlinks-flag@1.0.0: resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} engines: {node: '>= 0.4'} - dev: true /synckit@0.8.5: resolution: {integrity: sha512-L1dapNV6vu2s/4Sputv8xGsCdAVlb5nRDMFU/E27D44l5U6cw1g0dGd45uLc+OXjNMmF4ntiMdCimzcjFKQI8Q==} @@ -4702,6 +5635,10 @@ packages: resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} dev: true + /throttleit@1.0.1: + resolution: {integrity: sha512-vDZpf9Chs9mAdfY046mcPt8fg5QSZr37hEH4TXYBnDF+izxgrbRGUAAaBvIk/fJm9aOFCGFd1EsNg5AZCbnQCQ==} + dev: true + /through2@0.6.5: resolution: {integrity: sha512-RkK/CCESdTKQZHdmKICijdKKsCRVHs5KsLZ6pACAmF/1GPUQhonHSXWNERctxEp7RmvjdNbZTL5z9V7nSCXKcg==} dependencies: @@ -4731,6 +5668,13 @@ packages: engines: {node: '>=12'} dev: true + /tmp@0.2.1: + resolution: {integrity: sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==} + engines: {node: '>=8.17.0'} + dependencies: + rimraf: 3.0.2 + dev: true + /to-fast-properties@2.0.0: resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==} engines: {node: '>=4'} @@ -4746,6 +5690,15 @@ packages: engines: {node: '>=8.0'} dependencies: is-number: 7.0.0 + + /tough-cookie@4.1.3: + resolution: {integrity: sha512-aX/y5pVRkfRnfmuX+OdbSdXvPe6ieKX/G2s7e98f4poJHnqH3281gDPm/metm6E/WRamfx7WC4HUqkWHfQHprw==} + engines: {node: '>=6'} + dependencies: + psl: 1.9.0 + punycode: 2.3.0 + universalify: 0.2.0 + url-parse: 1.5.10 dev: true /trim-newlines@3.0.1: @@ -4798,6 +5751,12 @@ packages: resolution: {integrity: sha512-7At1WUettjcSRHXCyYtTselblcHl9PJFFVKiCAy/bY97+BPZXSQ2wbq0P9s8tK2G7dFQfNnlJnPAiArVBVBsfA==} dev: true + /tunnel-agent@0.6.0: + resolution: {integrity: sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==} + dependencies: + safe-buffer: 5.2.1 + dev: true + /tunnel@0.0.6: resolution: {integrity: sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==} engines: {node: '>=0.6.11 <=0.7.0 || >=0.7.3'} @@ -4805,6 +5764,10 @@ packages: dev: true optional: true + /tweetnacl@0.14.5: + resolution: {integrity: sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==} + dev: true + /type-check@0.3.2: resolution: {integrity: sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==} engines: {node: '>= 0.8.0'} @@ -4877,6 +5840,11 @@ packages: engines: {node: '>= 4.0.0'} dev: true + /universalify@0.2.0: + resolution: {integrity: sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==} + engines: {node: '>= 4.0.0'} + dev: true + /universalify@2.0.0: resolution: {integrity: sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==} engines: {node: '>= 10.0.0'} @@ -4911,6 +5879,13 @@ packages: prepend-http: 2.0.0 dev: true + /url-parse@1.5.10: + resolution: {integrity: sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==} + dependencies: + querystringify: 2.2.0 + requires-port: 1.0.0 + dev: true + /util-deprecate@1.0.2: resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} dev: true @@ -4931,6 +5906,43 @@ packages: spdx-expression-parse: 3.0.1 dev: true + /verror@1.10.0: + resolution: {integrity: sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==} + engines: {'0': node >=0.6.0} + dependencies: + assert-plus: 1.0.0 + core-util-is: 1.0.2 + extsprintf: 1.3.0 + dev: true + + /vite@3.1.6(sass@1.55.0): + resolution: {integrity: sha512-qMXIwnehvvcK5XfJiXQUiTxoYAEMKhM+jqCY6ZSTKFBKu1hJnAKEzP3AOcnTerI0cMZYAaJ4wpW1wiXLMDt4mA==} + engines: {node: ^14.18.0 || >=16.0.0} + hasBin: true + peerDependencies: + less: '*' + sass: '*' + stylus: '*' + terser: ^5.4.0 + peerDependenciesMeta: + less: + optional: true + sass: + optional: true + stylus: + optional: true + terser: + optional: true + dependencies: + esbuild: 0.15.18 + postcss: 8.4.32 + resolve: 1.22.2 + rollup: 2.78.1 + sass: 1.55.0 + optionalDependencies: + fsevents: 2.3.2 + dev: false + /which-module@2.0.1: resolution: {integrity: sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==} dev: true diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 125e8583e..c4b9bddc9 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -2,4 +2,5 @@ packages: # all packages in direct subdirs of packages/ - 'packages/*' # all packages in subdirs of components/ - - 'tests' \ No newline at end of file + - 'tests' + - 'e2e' diff --git a/tests/src/core/2d/text/TextUtils.test.ts b/tests/src/core/2d/text/TextUtils.test.ts index a719796ba..ff62826bd 100644 --- a/tests/src/core/2d/text/TextUtils.test.ts +++ b/tests/src/core/2d/text/TextUtils.test.ts @@ -8,8 +8,12 @@ describe("TextUtils", () => { let scene: Scene; let textEntity1: Entity; let textEntity2: Entity; + let textEntity3: Entity; + let textEntity4: Entity; let textRendererTruncate: TextRenderer; let textRendererOverflow: TextRenderer; + let wrap1TextRenderer: TextRenderer; + let wrap2TextRenderer: TextRenderer; before(async function () { engine = await WebGLEngine.create({ @@ -29,6 +33,8 @@ describe("TextUtils", () => { textEntity1 = rootEntity.createChild("text1"); textEntity2 = rootEntity.createChild("text2"); + textEntity3 = rootEntity.createChild("text3"); + textEntity4 = rootEntity.createChild("text4"); textRendererTruncate = textEntity1.addComponent(TextRenderer); textRendererTruncate.font = Font.createFromOS(engine, "Arial"); @@ -36,6 +42,11 @@ describe("TextUtils", () => { textRendererOverflow = textEntity2.addComponent(TextRenderer); textRendererOverflow.font = Font.createFromOS(engine, "Arial"); + wrap1TextRenderer = textEntity3.addComponent(TextRenderer); + wrap1TextRenderer.font = Font.createFromOS(engine, "Arial"); + wrap2TextRenderer = textEntity4.addComponent(TextRenderer); + wrap2TextRenderer.font = Font.createFromOS(engine, "Arial"); + engine.run(); }); @@ -200,6 +211,18 @@ describe("TextUtils", () => { expect(result.height).to.be.equal(162); expect(result.lines).to.be.deep.equal([" ", " ", "W", "o", "rl", "d"]); expect(result.lineHeight).to.be.equal(27); + + wrap1TextRenderer.enableWrapping = true; + wrap1TextRenderer.width = 5; + wrap1TextRenderer.fontSize = 60; + wrap1TextRenderer.text = "测试"; + const text1Metrics = TextUtils.measureTextWithWrap(wrap1TextRenderer); + wrap2TextRenderer.enableWrapping = true; + wrap2TextRenderer.width = 5; + wrap2TextRenderer.fontSize = 60; + wrap2TextRenderer.text = "测试。"; + const text2Metrics = TextUtils.measureTextWithWrap(wrap2TextRenderer); + expect(text1Metrics.lineMaxSizes[0].size).to.be.equal(text2Metrics.lineMaxSizes[0].size); }); it("measureTextWithoutWrap", () => { diff --git a/tests/src/core/Animator.test.ts b/tests/src/core/Animator.test.ts index 3aa11a647..2a3ee2371 100644 --- a/tests/src/core/Animator.test.ts +++ b/tests/src/core/Animator.test.ts @@ -1,15 +1,17 @@ -import { WebGLEngine } from "@galacean/engine-rhi-webgl"; import { + AnimationEvent, Animator, AnimatorControllerLayer, AnimatorLayerBlendingMode, AnimatorLayerMask, AnimatorStateMachine, AnimatorStateTransition, - Camera + Camera, + Script } from "@galacean/engine-core"; -import { Quaternion } from "@galacean/engine-math"; import { GLTFResource } from "@galacean/engine-loader"; +import { Quaternion } from "@galacean/engine-math"; +import { WebGLEngine } from "@galacean/engine-rhi-webgl"; import chai, { expect } from "chai"; import spies from "chai-spies"; import { glbResource } from "./model/fox"; @@ -272,4 +274,23 @@ describe("Animator test", function () { expect(parentLayerCurveOwner.isActive).to.eq(true); expect(childLayerCurveOwner.isActive).to.eq(false); }); + it("animation event", () => { + animator.play("Walk"); + + class TestScript extends Script { + event0(): void {} + } + TestScript.prototype.event0 = chai.spy(TestScript.prototype.event0); + + animator.entity.addComponent(TestScript); + + const event0 = new AnimationEvent(); + event0.functionName = "event0"; + event0.time = 0; + + const state = animator.findAnimatorState("Walk"); + state.clip.addEvent(event0); + animator.update(10); + expect(TestScript.prototype.event0).to.have.been.called.exactly(1); + }); }); diff --git a/tests/src/core/Script.test.ts b/tests/src/core/Script.test.ts index 207270d89..25028dc88 100644 --- a/tests/src/core/Script.test.ts +++ b/tests/src/core/Script.test.ts @@ -287,6 +287,31 @@ describe("Script", () => { }, 1000); }); + it("Enable Disable components", async () => { + const engine = await WebGLEngine.create({ canvas: document.createElement("canvas") }); + class KKK extends Script { + cmdStr = ""; + onEnable(): void { + this.cmdStr += "A"; + } + onDisable(): void { + this.cmdStr += "D"; + } + } + const root = new Entity(engine); + const kkk = root.addComponent(KKK); + root.addComponent( + class extends Script { + onEnable(): void { + kkk.enabled = false; + kkk.enabled = true; + } + } + ); + engine.sceneManager.activeScene.addRootEntity(root); + expect(kkk.cmdStr[0]).to.eql("A"); + }); + it("Dependent components", async () => { @dependentComponents(Camera, DependentMode.CheckOnly) class CheckScript extends Script {}