From c12f244196ff61d5ffd77b9f8ca2f1c26767199a Mon Sep 17 00:00:00 2001 From: Aaron Dodson Date: Fri, 12 Apr 2024 09:36:00 -0700 Subject: [PATCH 001/130] chore: Replace package/webpack config files with minimal versions --- package-lock.json | 18764 +++++++++++++------------------------------- package.json | 62 +- webpack.config.js | 120 +- 3 files changed, 5291 insertions(+), 13655 deletions(-) diff --git a/package-lock.json b/package-lock.json index b2c2694953..3ae254c832 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,1378 +1,1075 @@ { "name": "scratch-blocks", - "version": "1.1.86", - "lockfileVersion": 3, + "version": "2.0.0", + "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "scratch-blocks", - "version": "1.1.86", + "version": "2.0.0", "license": "Apache-2.0", "dependencies": { - "exports-loader": "^0.7.0", - "google-closure-library": "^20190301.0.0", - "imports-loader": "^0.8.0", - "scratch-l10n": "^3.18.3" + "blockly": "^10.0.0" }, "devDependencies": { - "@commitlint/cli": "17.8.1", - "@commitlint/config-conventional": "17.8.1", - "async": "2.6.4", - "copy-webpack-plugin": "4.6.0", - "eslint": "4.19.1", - "event-stream": "3.3.5", - "gh-pages": "0.12.0", - "glob": "7.2.3", - "google-closure-compiler": "20180402.0.0", - "graceful-fs": "4.2.11", - "husky": "8.0.3", - "json": "9.0.6", - "rimraf": "2.7.1", - "scratch-semantic-release-config": "1.0.14", - "selenium-webdriver": "4.16.0", - "semantic-release": "19.0.5", - "transifex": "1.6.6", - "uglifyjs-webpack-plugin": "1.3.0", - "webpack": "4.47.0", - "webpack-cli": "3.3.12" - } - }, - "node_modules/@babel/code-frame": { - "version": "7.24.2", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.2.tgz", - "integrity": "sha512-y5+tLQyV8pg3fsiln67BVLD1P13Eg4lh5RW9mF0zUuvLrv9uIQ4MCL+CRT+FTsBlBjcIan6PGsLcBN0m3ClUyQ==", - "dev": true, - "dependencies": { - "@babel/highlight": "^7.24.2", - "picocolors": "^1.0.0" - }, - "engines": { - "node": ">=6.9.0" + "source-map-loader": "^4.0.1", + "webpack": "^5.76.0", + "webpack-cli": "^4.10.0", + "webpack-dev-server": "^4.11.1" } }, - "node_modules/@babel/helper-validator-identifier": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", - "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", + "node_modules/@discoveryjs/json-ext": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz", + "integrity": "sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==", "dev": true, "engines": { - "node": ">=6.9.0" + "node": ">=10.0.0" } }, - "node_modules/@babel/highlight": { - "version": "7.24.2", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.2.tgz", - "integrity": "sha512-Yac1ao4flkTxTteCDZLEvdxg2fZfz1v8M4QpaGypq/WPDqg3ijHYbDfs+LG5hvzSoqaSZ9/Z9lKSP3CjZjv+pA==", + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", + "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", "dev": true, "dependencies": { - "@babel/helper-validator-identifier": "^7.22.20", - "chalk": "^2.4.2", - "js-tokens": "^4.0.0", - "picocolors": "^1.0.0" + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" }, "engines": { - "node": ">=6.9.0" + "node": ">=6.0.0" } }, - "node_modules/@babel/highlight/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", + "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==", "dev": true, - "dependencies": { - "color-convert": "^1.9.0" - }, "engines": { - "node": ">=4" + "node": ">=6.0.0" } }, - "node_modules/@babel/highlight/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "node_modules/@jridgewell/set-array": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", + "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", "dev": true, - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, "engines": { - "node": ">=4" + "node": ">=6.0.0" } }, - "node_modules/@babel/highlight/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "node_modules/@jridgewell/source-map": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.5.tgz", + "integrity": "sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ==", "dev": true, "dependencies": { - "color-name": "1.1.3" + "@jridgewell/gen-mapping": "^0.3.0", + "@jridgewell/trace-mapping": "^0.3.9" } }, - "node_modules/@babel/highlight/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", "dev": true }, - "node_modules/@babel/highlight/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.20", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.20.tgz", + "integrity": "sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q==", "dev": true, - "engines": { - "node": ">=4" + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" } }, - "node_modules/@babel/highlight/node_modules/js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "node_modules/@leichtgewicht/ip-codec": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.4.tgz", + "integrity": "sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A==", "dev": true }, - "node_modules/@babel/highlight/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@colors/colors": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", - "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", - "dev": true, - "optional": true, + "node_modules/@tootallnate/once": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", + "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==", "engines": { - "node": ">=0.1.90" + "node": ">= 10" } }, - "node_modules/@commitlint/cli": { - "version": "17.8.1", - "resolved": "https://registry.npmjs.org/@commitlint/cli/-/cli-17.8.1.tgz", - "integrity": "sha512-ay+WbzQesE0Rv4EQKfNbSMiJJ12KdKTDzIt0tcK4k11FdsWmtwP0Kp1NWMOUswfIWo6Eb7p7Ln721Nx9FLNBjg==", + "node_modules/@types/body-parser": { + "version": "1.19.5", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz", + "integrity": "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==", "dev": true, "dependencies": { - "@commitlint/format": "^17.8.1", - "@commitlint/lint": "^17.8.1", - "@commitlint/load": "^17.8.1", - "@commitlint/read": "^17.8.1", - "@commitlint/types": "^17.8.1", - "execa": "^5.0.0", - "lodash.isfunction": "^3.0.9", - "resolve-from": "5.0.0", - "resolve-global": "1.0.0", - "yargs": "^17.0.0" - }, - "bin": { - "commitlint": "cli.js" - }, - "engines": { - "node": ">=v14" + "@types/connect": "*", + "@types/node": "*" } }, - "node_modules/@commitlint/config-conventional": { - "version": "17.8.1", - "resolved": "https://registry.npmjs.org/@commitlint/config-conventional/-/config-conventional-17.8.1.tgz", - "integrity": "sha512-NxCOHx1kgneig3VLauWJcDWS40DVjg7nKOpBEEK9E5fjJpQqLCilcnKkIIjdBH98kEO1q3NpE5NSrZ2kl/QGJg==", + "node_modules/@types/bonjour": { + "version": "3.5.13", + "resolved": "https://registry.npmjs.org/@types/bonjour/-/bonjour-3.5.13.tgz", + "integrity": "sha512-z9fJ5Im06zvUL548KvYNecEVlA7cVDkGUi6kZusb04mpyEFKCIZJvloCcmpmLaIahDpOQGHaHmG6imtPMmPXGQ==", "dev": true, "dependencies": { - "conventional-changelog-conventionalcommits": "^6.1.0" - }, - "engines": { - "node": ">=v14" + "@types/node": "*" } }, - "node_modules/@commitlint/config-validator": { - "version": "17.8.1", - "resolved": "https://registry.npmjs.org/@commitlint/config-validator/-/config-validator-17.8.1.tgz", - "integrity": "sha512-UUgUC+sNiiMwkyiuIFR7JG2cfd9t/7MV8VB4TZ+q02ZFkHoduUS4tJGsCBWvBOGD9Btev6IecPMvlWUfJorkEA==", + "node_modules/@types/connect": { + "version": "3.4.38", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", + "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", "dev": true, "dependencies": { - "@commitlint/types": "^17.8.1", - "ajv": "^8.11.0" - }, - "engines": { - "node": ">=v14" + "@types/node": "*" } }, - "node_modules/@commitlint/ensure": { - "version": "17.8.1", - "resolved": "https://registry.npmjs.org/@commitlint/ensure/-/ensure-17.8.1.tgz", - "integrity": "sha512-xjafwKxid8s1K23NFpL8JNo6JnY/ysetKo8kegVM7c8vs+kWLP8VrQq+NbhgVlmCojhEDbzQKp4eRXSjVOGsow==", + "node_modules/@types/connect-history-api-fallback": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.5.4.tgz", + "integrity": "sha512-n6Cr2xS1h4uAulPRdlw6Jl6s1oG8KrVilPN2yUITEs+K48EzMJJ3W1xy8K5eWuFvjp3R74AOIGSmp2UfBJ8HFw==", "dev": true, "dependencies": { - "@commitlint/types": "^17.8.1", - "lodash.camelcase": "^4.3.0", - "lodash.kebabcase": "^4.1.1", - "lodash.snakecase": "^4.1.1", - "lodash.startcase": "^4.4.0", - "lodash.upperfirst": "^4.3.1" - }, - "engines": { - "node": ">=v14" + "@types/express-serve-static-core": "*", + "@types/node": "*" } }, - "node_modules/@commitlint/execute-rule": { - "version": "17.8.1", - "resolved": "https://registry.npmjs.org/@commitlint/execute-rule/-/execute-rule-17.8.1.tgz", - "integrity": "sha512-JHVupQeSdNI6xzA9SqMF+p/JjrHTcrJdI02PwesQIDCIGUrv04hicJgCcws5nzaoZbROapPs0s6zeVHoxpMwFQ==", + "node_modules/@types/eslint": { + "version": "8.56.0", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.0.tgz", + "integrity": "sha512-FlsN0p4FhuYRjIxpbdXovvHQhtlG05O1GG/RNWvdAxTboR438IOTwmrY/vLA+Xfgg06BTkP045M3vpFwTMv1dg==", "dev": true, - "engines": { - "node": ">=v14" + "dependencies": { + "@types/estree": "*", + "@types/json-schema": "*" } }, - "node_modules/@commitlint/format": { - "version": "17.8.1", - "resolved": "https://registry.npmjs.org/@commitlint/format/-/format-17.8.1.tgz", - "integrity": "sha512-f3oMTyZ84M9ht7fb93wbCKmWxO5/kKSbwuYvS867duVomoOsgrgljkGGIztmT/srZnaiGbaK8+Wf8Ik2tSr5eg==", + "node_modules/@types/eslint-scope": { + "version": "3.7.7", + "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz", + "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==", "dev": true, "dependencies": { - "@commitlint/types": "^17.8.1", - "chalk": "^4.1.0" - }, - "engines": { - "node": ">=v14" + "@types/eslint": "*", + "@types/estree": "*" } }, - "node_modules/@commitlint/is-ignored": { - "version": "17.8.1", - "resolved": "https://registry.npmjs.org/@commitlint/is-ignored/-/is-ignored-17.8.1.tgz", - "integrity": "sha512-UshMi4Ltb4ZlNn4F7WtSEugFDZmctzFpmbqvpyxD3la510J+PLcnyhf9chs7EryaRFJMdAKwsEKfNK0jL/QM4g==", + "node_modules/@types/estree": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", + "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", + "dev": true + }, + "node_modules/@types/express": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz", + "integrity": "sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==", "dev": true, "dependencies": { - "@commitlint/types": "^17.8.1", - "semver": "7.5.4" - }, - "engines": { - "node": ">=v14" + "@types/body-parser": "*", + "@types/express-serve-static-core": "^4.17.33", + "@types/qs": "*", + "@types/serve-static": "*" } }, - "node_modules/@commitlint/lint": { - "version": "17.8.1", - "resolved": "https://registry.npmjs.org/@commitlint/lint/-/lint-17.8.1.tgz", - "integrity": "sha512-aQUlwIR1/VMv2D4GXSk7PfL5hIaFSfy6hSHV94O8Y27T5q+DlDEgd/cZ4KmVI+MWKzFfCTiTuWqjfRSfdRllCA==", + "node_modules/@types/express-serve-static-core": { + "version": "4.17.41", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.41.tgz", + "integrity": "sha512-OaJ7XLaelTgrvlZD8/aa0vvvxZdUmlCn6MtWeB7TkiKW70BQLc9XEPpDLPdbo52ZhXUCrznlWdCHWxJWtdyajA==", "dev": true, "dependencies": { - "@commitlint/is-ignored": "^17.8.1", - "@commitlint/parse": "^17.8.1", - "@commitlint/rules": "^17.8.1", - "@commitlint/types": "^17.8.1" - }, - "engines": { - "node": ">=v14" + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*", + "@types/send": "*" } }, - "node_modules/@commitlint/load": { - "version": "17.8.1", - "resolved": "https://registry.npmjs.org/@commitlint/load/-/load-17.8.1.tgz", - "integrity": "sha512-iF4CL7KDFstP1kpVUkT8K2Wl17h2yx9VaR1ztTc8vzByWWcbO/WaKwxsnCOqow9tVAlzPfo1ywk9m2oJ9ucMqA==", + "node_modules/@types/http-errors": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz", + "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==", + "dev": true + }, + "node_modules/@types/http-proxy": { + "version": "1.17.14", + "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.14.tgz", + "integrity": "sha512-SSrD0c1OQzlFX7pGu1eXxSEjemej64aaNPRhhVYUGqXh0BtldAAx37MG8btcumvpgKyZp1F5Gn3JkktdxiFv6w==", "dev": true, "dependencies": { - "@commitlint/config-validator": "^17.8.1", - "@commitlint/execute-rule": "^17.8.1", - "@commitlint/resolve-extends": "^17.8.1", - "@commitlint/types": "^17.8.1", - "@types/node": "20.5.1", - "chalk": "^4.1.0", - "cosmiconfig": "^8.0.0", - "cosmiconfig-typescript-loader": "^4.0.0", - "lodash.isplainobject": "^4.0.6", - "lodash.merge": "^4.6.2", - "lodash.uniq": "^4.5.0", - "resolve-from": "^5.0.0", - "ts-node": "^10.8.1", - "typescript": "^4.6.4 || ^5.2.2" - }, - "engines": { - "node": ">=v14" + "@types/node": "*" } }, - "node_modules/@commitlint/message": { - "version": "17.8.1", - "resolved": "https://registry.npmjs.org/@commitlint/message/-/message-17.8.1.tgz", - "integrity": "sha512-6bYL1GUQsD6bLhTH3QQty8pVFoETfFQlMn2Nzmz3AOLqRVfNNtXBaSY0dhZ0dM6A2MEq4+2d7L/2LP8TjqGRkA==", - "dev": true, - "engines": { - "node": ">=v14" - } + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true + }, + "node_modules/@types/mime": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", + "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==", + "dev": true }, - "node_modules/@commitlint/parse": { - "version": "17.8.1", - "resolved": "https://registry.npmjs.org/@commitlint/parse/-/parse-17.8.1.tgz", - "integrity": "sha512-/wLUickTo0rNpQgWwLPavTm7WbwkZoBy3X8PpkUmlSmQJyWQTj0m6bDjiykMaDt41qcUbfeFfaCvXfiR4EGnfw==", + "node_modules/@types/node": { + "version": "20.10.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.10.5.tgz", + "integrity": "sha512-nNPsNE65wjMxEKI93yOP+NPGGBJz/PoN3kZsVLee0XMiJolxSekEVD8wRwBUBqkwc7UWop0edW50yrCQW4CyRw==", "dev": true, "dependencies": { - "@commitlint/types": "^17.8.1", - "conventional-changelog-angular": "^6.0.0", - "conventional-commits-parser": "^4.0.0" - }, - "engines": { - "node": ">=v14" + "undici-types": "~5.26.4" } }, - "node_modules/@commitlint/read": { - "version": "17.8.1", - "resolved": "https://registry.npmjs.org/@commitlint/read/-/read-17.8.1.tgz", - "integrity": "sha512-Fd55Oaz9irzBESPCdMd8vWWgxsW3OWR99wOntBDHgf9h7Y6OOHjWEdS9Xzen1GFndqgyoaFplQS5y7KZe0kO2w==", + "node_modules/@types/node-forge": { + "version": "1.3.10", + "resolved": "https://registry.npmjs.org/@types/node-forge/-/node-forge-1.3.10.tgz", + "integrity": "sha512-y6PJDYN4xYBxwd22l+OVH35N+1fCYWiuC3aiP2SlXVE6Lo7SS+rSx9r89hLxrP4pn6n1lBGhHJ12pj3F3Mpttw==", "dev": true, "dependencies": { - "@commitlint/top-level": "^17.8.1", - "@commitlint/types": "^17.8.1", - "fs-extra": "^11.0.0", - "git-raw-commits": "^2.0.11", - "minimist": "^1.2.6" - }, - "engines": { - "node": ">=v14" + "@types/node": "*" } }, - "node_modules/@commitlint/resolve-extends": { - "version": "17.8.1", - "resolved": "https://registry.npmjs.org/@commitlint/resolve-extends/-/resolve-extends-17.8.1.tgz", - "integrity": "sha512-W/ryRoQ0TSVXqJrx5SGkaYuAaE/BUontL1j1HsKckvM6e5ZaG0M9126zcwL6peKSuIetJi7E87PRQF8O86EW0Q==", + "node_modules/@types/qs": { + "version": "6.9.10", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.10.tgz", + "integrity": "sha512-3Gnx08Ns1sEoCrWssEgTSJs/rsT2vhGP+Ja9cnnk9k4ALxinORlQneLXFeFKOTJMOeZUFD1s7w+w2AphTpvzZw==", + "dev": true + }, + "node_modules/@types/range-parser": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", + "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==", + "dev": true + }, + "node_modules/@types/retry": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.0.tgz", + "integrity": "sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==", + "dev": true + }, + "node_modules/@types/send": { + "version": "0.17.4", + "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz", + "integrity": "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==", "dev": true, "dependencies": { - "@commitlint/config-validator": "^17.8.1", - "@commitlint/types": "^17.8.1", - "import-fresh": "^3.0.0", - "lodash.mergewith": "^4.6.2", - "resolve-from": "^5.0.0", - "resolve-global": "^1.0.0" - }, - "engines": { - "node": ">=v14" + "@types/mime": "^1", + "@types/node": "*" } }, - "node_modules/@commitlint/rules": { - "version": "17.8.1", - "resolved": "https://registry.npmjs.org/@commitlint/rules/-/rules-17.8.1.tgz", - "integrity": "sha512-2b7OdVbN7MTAt9U0vKOYKCDsOvESVXxQmrvuVUZ0rGFMCrCPJWWP1GJ7f0lAypbDAhaGb8zqtdOr47192LBrIA==", + "node_modules/@types/serve-index": { + "version": "1.9.4", + "resolved": "https://registry.npmjs.org/@types/serve-index/-/serve-index-1.9.4.tgz", + "integrity": "sha512-qLpGZ/c2fhSs5gnYsQxtDEq3Oy8SXPClIXkW5ghvAvsNuVSA8k+gCONcUCS/UjLEYvYps+e8uBtfgXgvhwfNug==", "dev": true, "dependencies": { - "@commitlint/ensure": "^17.8.1", - "@commitlint/message": "^17.8.1", - "@commitlint/to-lines": "^17.8.1", - "@commitlint/types": "^17.8.1", - "execa": "^5.0.0" - }, - "engines": { - "node": ">=v14" + "@types/express": "*" } }, - "node_modules/@commitlint/to-lines": { - "version": "17.8.1", - "resolved": "https://registry.npmjs.org/@commitlint/to-lines/-/to-lines-17.8.1.tgz", - "integrity": "sha512-LE0jb8CuR/mj6xJyrIk8VLz03OEzXFgLdivBytoooKO5xLt5yalc8Ma5guTWobw998sbR3ogDd+2jed03CFmJA==", + "node_modules/@types/serve-static": { + "version": "1.15.5", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.5.tgz", + "integrity": "sha512-PDRk21MnK70hja/YF8AHfC7yIsiQHn1rcXx7ijCFBX/k+XQJhQT/gw3xekXKJvx+5SXaMMS8oqQy09Mzvz2TuQ==", "dev": true, - "engines": { - "node": ">=v14" + "dependencies": { + "@types/http-errors": "*", + "@types/mime": "*", + "@types/node": "*" } }, - "node_modules/@commitlint/top-level": { - "version": "17.8.1", - "resolved": "https://registry.npmjs.org/@commitlint/top-level/-/top-level-17.8.1.tgz", - "integrity": "sha512-l6+Z6rrNf5p333SHfEte6r+WkOxGlWK4bLuZKbtf/2TXRN+qhrvn1XE63VhD8Oe9oIHQ7F7W1nG2k/TJFhx2yA==", + "node_modules/@types/sockjs": { + "version": "0.3.36", + "resolved": "https://registry.npmjs.org/@types/sockjs/-/sockjs-0.3.36.tgz", + "integrity": "sha512-MK9V6NzAS1+Ud7JV9lJLFqW85VbC9dq3LmwZCuBe4wBDgKC0Kj/jd8Xl+nSviU+Qc3+m7umHHyHg//2KSa0a0Q==", "dev": true, "dependencies": { - "find-up": "^5.0.0" - }, - "engines": { - "node": ">=v14" + "@types/node": "*" } }, - "node_modules/@commitlint/types": { - "version": "17.8.1", - "resolved": "https://registry.npmjs.org/@commitlint/types/-/types-17.8.1.tgz", - "integrity": "sha512-PXDQXkAmiMEG162Bqdh9ChML/GJZo6vU+7F03ALKDK8zYc6SuAr47LjG7hGYRqUOz+WK0dU7bQ0xzuqFMdxzeQ==", + "node_modules/@types/ws": { + "version": "8.5.10", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.10.tgz", + "integrity": "sha512-vmQSUcfalpIq0R9q7uTo2lXs6eGIpt9wtnLdMv9LVpIjCA/+ufZRozlVoVelIYixx1ugCBKDhn89vnsEGOCx9A==", "dev": true, "dependencies": { - "chalk": "^4.1.0" - }, - "engines": { - "node": ">=v14" + "@types/node": "*" } }, - "node_modules/@cspotcode/source-map-support": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", - "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "node_modules/@webassemblyjs/ast": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.6.tgz", + "integrity": "sha512-IN1xI7PwOvLPgjcf180gC1bqn3q/QaOCwYUahIOhbYUu8KA/3tw2RT/T0Gidi1l7Hhj5D/INhJxiICObqpMu4Q==", "dev": true, "dependencies": { - "@jridgewell/trace-mapping": "0.3.9" - }, - "engines": { - "node": ">=12" + "@webassemblyjs/helper-numbers": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6" } }, - "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", - "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", - "dev": true, - "engines": { - "node": ">=6.0.0" - } + "node_modules/@webassemblyjs/floating-point-hex-parser": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz", + "integrity": "sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==", + "dev": true }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.15", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", - "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", + "node_modules/@webassemblyjs/helper-api-error": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz", + "integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==", "dev": true }, - "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", - "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "node_modules/@webassemblyjs/helper-buffer": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.6.tgz", + "integrity": "sha512-z3nFzdcp1mb8nEOFFk8DrYLpHvhKC3grJD2ardfKOzmbmJvEf/tPIqCY+sNcwZIY8ZD7IkB2l7/pqhUhqm7hLA==", + "dev": true + }, + "node_modules/@webassemblyjs/helper-numbers": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz", + "integrity": "sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==", "dev": true, "dependencies": { - "@jridgewell/resolve-uri": "^3.0.3", - "@jridgewell/sourcemap-codec": "^1.4.10" + "@webassemblyjs/floating-point-hex-parser": "1.11.6", + "@webassemblyjs/helper-api-error": "1.11.6", + "@xtuc/long": "4.2.2" } }, - "node_modules/@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "node_modules/@webassemblyjs/helper-wasm-bytecode": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz", + "integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==", + "dev": true + }, + "node_modules/@webassemblyjs/helper-wasm-section": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.6.tgz", + "integrity": "sha512-LPpZbSOwTpEC2cgn4hTydySy1Ke+XEu+ETXuoyvuyezHO3Kjdu90KK95Sh9xTbmjrCsUwvWwCOQQNta37VrS9g==", "dev": true, "dependencies": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - }, - "engines": { - "node": ">= 8" + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-buffer": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/wasm-gen": "1.11.6" } }, - "node_modules/@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "node_modules/@webassemblyjs/ieee754": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz", + "integrity": "sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==", "dev": true, - "engines": { - "node": ">= 8" + "dependencies": { + "@xtuc/ieee754": "^1.2.0" } }, - "node_modules/@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "node_modules/@webassemblyjs/leb128": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.6.tgz", + "integrity": "sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==", "dev": true, "dependencies": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - }, - "engines": { - "node": ">= 8" + "@xtuc/long": "4.2.2" } }, - "node_modules/@octokit/auth-token": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-3.0.4.tgz", - "integrity": "sha512-TWFX7cZF2LXoCvdmJWY7XVPi74aSY0+FfBZNSXEXFkMpjcqsQwDSYVv5FhRFaI0V1ECnwbz4j59T/G+rXNWaIQ==", - "dev": true, - "engines": { - "node": ">= 14" - } + "node_modules/@webassemblyjs/utf8": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.6.tgz", + "integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==", + "dev": true }, - "node_modules/@octokit/core": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/@octokit/core/-/core-4.2.4.tgz", - "integrity": "sha512-rYKilwgzQ7/imScn3M9/pFfUf4I1AZEH3KhyJmtPdE2zfaXAn2mFfUy4FbKewzc2We5y/LlKLj36fWJLKC2SIQ==", + "node_modules/@webassemblyjs/wasm-edit": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.6.tgz", + "integrity": "sha512-Ybn2I6fnfIGuCR+Faaz7YcvtBKxvoLV3Lebn1tM4o/IAJzmi9AWYIPWpyBfU8cC+JxAO57bk4+zdsTjJR+VTOw==", "dev": true, "dependencies": { - "@octokit/auth-token": "^3.0.0", - "@octokit/graphql": "^5.0.0", - "@octokit/request": "^6.0.0", - "@octokit/request-error": "^3.0.0", - "@octokit/types": "^9.0.0", - "before-after-hook": "^2.2.0", - "universal-user-agent": "^6.0.0" - }, - "engines": { - "node": ">= 14" + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-buffer": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/helper-wasm-section": "1.11.6", + "@webassemblyjs/wasm-gen": "1.11.6", + "@webassemblyjs/wasm-opt": "1.11.6", + "@webassemblyjs/wasm-parser": "1.11.6", + "@webassemblyjs/wast-printer": "1.11.6" } }, - "node_modules/@octokit/endpoint": { - "version": "7.0.6", - "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-7.0.6.tgz", - "integrity": "sha512-5L4fseVRUsDFGR00tMWD/Trdeeihn999rTMGRMC1G/Ldi1uWlWJzI98H4Iak5DB/RVvQuyMYKqSK/R6mbSOQyg==", + "node_modules/@webassemblyjs/wasm-gen": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.6.tgz", + "integrity": "sha512-3XOqkZP/y6B4F0PBAXvI1/bky7GryoogUtfwExeP/v7Nzwo1QLcq5oQmpKlftZLbT+ERUOAZVQjuNVak6UXjPA==", "dev": true, "dependencies": { - "@octokit/types": "^9.0.0", - "is-plain-object": "^5.0.0", - "universal-user-agent": "^6.0.0" - }, - "engines": { - "node": ">= 14" + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/ieee754": "1.11.6", + "@webassemblyjs/leb128": "1.11.6", + "@webassemblyjs/utf8": "1.11.6" } }, - "node_modules/@octokit/graphql": { - "version": "5.0.6", - "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-5.0.6.tgz", - "integrity": "sha512-Fxyxdy/JH0MnIB5h+UQ3yCoh1FG4kWXfFKkpWqjZHw/p+Kc8Y44Hu/kCgNBT6nU1shNumEchmW/sUO1JuQnPcw==", + "node_modules/@webassemblyjs/wasm-opt": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.6.tgz", + "integrity": "sha512-cOrKuLRE7PCe6AsOVl7WasYf3wbSo4CeOk6PkrjS7g57MFfVUF9u6ysQBBODX0LdgSvQqRiGz3CXvIDKcPNy4g==", "dev": true, "dependencies": { - "@octokit/request": "^6.0.0", - "@octokit/types": "^9.0.0", - "universal-user-agent": "^6.0.0" - }, - "engines": { - "node": ">= 14" + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-buffer": "1.11.6", + "@webassemblyjs/wasm-gen": "1.11.6", + "@webassemblyjs/wasm-parser": "1.11.6" } }, - "node_modules/@octokit/openapi-types": { - "version": "18.1.1", - "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-18.1.1.tgz", - "integrity": "sha512-VRaeH8nCDtF5aXWnjPuEMIYf1itK/s3JYyJcWFJT8X9pSNnBtriDf7wlEWsGuhPLl4QIH4xM8fqTXDwJ3Mu6sw==", - "dev": true - }, - "node_modules/@octokit/plugin-paginate-rest": { - "version": "6.1.2", - "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-6.1.2.tgz", - "integrity": "sha512-qhrmtQeHU/IivxucOV1bbI/xZyC/iOBhclokv7Sut5vnejAIAEXVcGQeRpQlU39E0WwK9lNvJHphHri/DB6lbQ==", + "node_modules/@webassemblyjs/wasm-parser": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.6.tgz", + "integrity": "sha512-6ZwPeGzMJM3Dqp3hCsLgESxBGtT/OeCvCZ4TA1JUPYgmhAx38tTPR9JaKy0S5H3evQpO/h2uWs2j6Yc/fjkpTQ==", "dev": true, "dependencies": { - "@octokit/tsconfig": "^1.0.2", - "@octokit/types": "^9.2.3" - }, - "engines": { - "node": ">= 14" - }, - "peerDependencies": { - "@octokit/core": ">=4" + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-api-error": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/ieee754": "1.11.6", + "@webassemblyjs/leb128": "1.11.6", + "@webassemblyjs/utf8": "1.11.6" } }, - "node_modules/@octokit/plugin-retry": { - "version": "4.1.6", - "resolved": "https://registry.npmjs.org/@octokit/plugin-retry/-/plugin-retry-4.1.6.tgz", - "integrity": "sha512-obkYzIgEC75r8+9Pnfiiqy3y/x1bc3QLE5B7qvv9wi9Kj0R5tGQFC6QMBg1154WQ9lAVypuQDGyp3hNpp15gQQ==", + "node_modules/@webassemblyjs/wast-printer": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.6.tgz", + "integrity": "sha512-JM7AhRcE+yW2GWYaKeHL5vt4xqee5N2WcezptmgyhNS+ScggqcT1OtXykhAb13Sn5Yas0j2uv9tHgrjwvzAP4A==", "dev": true, "dependencies": { - "@octokit/types": "^9.0.0", - "bottleneck": "^2.15.3" - }, - "engines": { - "node": ">= 14" - }, - "peerDependencies": { - "@octokit/core": ">=3" + "@webassemblyjs/ast": "1.11.6", + "@xtuc/long": "4.2.2" } }, - "node_modules/@octokit/plugin-throttling": { - "version": "5.2.3", - "resolved": "https://registry.npmjs.org/@octokit/plugin-throttling/-/plugin-throttling-5.2.3.tgz", - "integrity": "sha512-C9CFg9mrf6cugneKiaI841iG8DOv6P5XXkjmiNNut+swePxQ7RWEdAZRp5rJoE1hjsIqiYcKa/ZkOQ+ujPI39Q==", + "node_modules/@webpack-cli/configtest": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-1.2.0.tgz", + "integrity": "sha512-4FB8Tj6xyVkyqjj1OaTqCjXYULB9FMkqQ8yGrZjRDrYh0nOE+7Lhs45WioWQQMV+ceFlE368Ukhe6xdvJM9Egg==", "dev": true, - "dependencies": { - "@octokit/types": "^9.0.0", - "bottleneck": "^2.15.3" - }, - "engines": { - "node": ">= 14" - }, "peerDependencies": { - "@octokit/core": "^4.0.0" + "webpack": "4.x.x || 5.x.x", + "webpack-cli": "4.x.x" } }, - "node_modules/@octokit/request": { - "version": "6.2.8", - "resolved": "https://registry.npmjs.org/@octokit/request/-/request-6.2.8.tgz", - "integrity": "sha512-ow4+pkVQ+6XVVsekSYBzJC0VTVvh/FCTUUgTsboGq+DTeWdyIFV8WSCdo0RIxk6wSkBTHqIK1mYuY7nOBXOchw==", + "node_modules/@webpack-cli/info": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-1.5.0.tgz", + "integrity": "sha512-e8tSXZpw2hPl2uMJY6fsMswaok5FdlGNRTktvFk2sD8RjH0hE2+XistawJx1vmKteh4NmGmNUrp+Tb2w+udPcQ==", "dev": true, "dependencies": { - "@octokit/endpoint": "^7.0.0", - "@octokit/request-error": "^3.0.0", - "@octokit/types": "^9.0.0", - "is-plain-object": "^5.0.0", - "node-fetch": "^2.6.7", - "universal-user-agent": "^6.0.0" + "envinfo": "^7.7.3" }, - "engines": { - "node": ">= 14" + "peerDependencies": { + "webpack-cli": "4.x.x" } }, - "node_modules/@octokit/request-error": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-3.0.3.tgz", - "integrity": "sha512-crqw3V5Iy2uOU5Np+8M/YexTlT8zxCfI+qu+LxUB7SZpje4Qmx3mub5DfEKSO8Ylyk0aogi6TYdf6kxzh2BguQ==", + "node_modules/@webpack-cli/serve": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-1.7.0.tgz", + "integrity": "sha512-oxnCNGj88fL+xzV+dacXs44HcDwf1ovs3AuEzvP7mqXw7fQntqIhQ1BRmynh4qEKQSSSRSWVyXRjmTbZIX9V2Q==", "dev": true, - "dependencies": { - "@octokit/types": "^9.0.0", - "deprecation": "^2.0.0", - "once": "^1.4.0" + "peerDependencies": { + "webpack-cli": "4.x.x" }, - "engines": { - "node": ">= 14" + "peerDependenciesMeta": { + "webpack-dev-server": { + "optional": true + } } }, - "node_modules/@octokit/tsconfig": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@octokit/tsconfig/-/tsconfig-1.0.2.tgz", - "integrity": "sha512-I0vDR0rdtP8p2lGMzvsJzbhdOWy405HcGovrspJ8RRibHnyRgggUSNO5AIox5LmqiwmatHKYsvj6VGFHkqS7lA==", + "node_modules/@xtuc/ieee754": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", + "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", "dev": true }, - "node_modules/@octokit/types": { - "version": "9.3.2", - "resolved": "https://registry.npmjs.org/@octokit/types/-/types-9.3.2.tgz", - "integrity": "sha512-D4iHGTdAnEEVsB8fl95m1hiz7D5YiRdQ9b/OEb3BYRVwbLsGHcRVPz+u+BgRLNk0Q0/4iZCBqDN96j2XNxfXrA==", - "dev": true, - "dependencies": { - "@octokit/openapi-types": "^18.0.0" - } + "node_modules/@xtuc/long": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", + "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", + "dev": true }, - "node_modules/@pnpm/config.env-replace": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@pnpm/config.env-replace/-/config.env-replace-1.1.0.tgz", - "integrity": "sha512-htyl8TWnKL7K/ESFa1oW2UB5lVDxuF5DpM7tBi6Hu2LNL3mWkIzNLG6N4zoCUP1lCKNxWy/3iu8mS8MvToGd6w==", - "dev": true, - "engines": { - "node": ">=12.22.0" - } + "node_modules/abab": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz", + "integrity": "sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==", + "deprecated": "Use your platform's native atob() and btoa() methods instead" }, - "node_modules/@pnpm/network.ca-file": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@pnpm/network.ca-file/-/network.ca-file-1.0.2.tgz", - "integrity": "sha512-YcPQ8a0jwYU9bTdJDpXjMi7Brhkr1mXsXrUJvjqM2mQDgkRiz8jFaQGOdaLxgjtUfQgZhKy/O3cG/YwmgKaxLA==", + "node_modules/accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", "dev": true, "dependencies": { - "graceful-fs": "4.2.10" + "mime-types": "~2.1.34", + "negotiator": "0.6.3" }, "engines": { - "node": ">=12.22.0" + "node": ">= 0.6" } }, - "node_modules/@pnpm/network.ca-file/node_modules/graceful-fs": { - "version": "4.2.10", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", - "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", - "dev": true - }, - "node_modules/@pnpm/npm-conf": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/@pnpm/npm-conf/-/npm-conf-2.2.2.tgz", - "integrity": "sha512-UA91GwWPhFExt3IizW6bOeY/pQ0BkuNwKjk9iQW9KqxluGCrg4VenZ0/L+2Y0+ZOtme72EVvg6v0zo3AMQRCeA==", + "node_modules/acorn": { + "version": "8.11.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.2.tgz", + "integrity": "sha512-nc0Axzp/0FILLEVsm4fNwLCwMttvhEI263QtVPQcbpfZZ3ts0hLsZGOpE6czNlid7CJ9MlyH8reXkpsf3YUY4w==", "dev": true, - "dependencies": { - "@pnpm/config.env-replace": "^1.1.0", - "@pnpm/network.ca-file": "^1.0.1", - "config-chain": "^1.1.11" + "bin": { + "acorn": "bin/acorn" }, "engines": { - "node": ">=12" + "node": ">=0.4.0" } }, - "node_modules/@semantic-release/changelog": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/@semantic-release/changelog/-/changelog-6.0.3.tgz", - "integrity": "sha512-dZuR5qByyfe3Y03TpmCvAxCyTnp7r5XwtHRf/8vD9EAn4ZWbavUX8adMtXYzE86EVh0gyLA7lm5yW4IV30XUag==", + "node_modules/acorn-import-assertions": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz", + "integrity": "sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==", "dev": true, - "dependencies": { - "@semantic-release/error": "^3.0.0", - "aggregate-error": "^3.0.0", - "fs-extra": "^11.0.0", - "lodash": "^4.17.4" - }, - "engines": { - "node": ">=14.17" - }, "peerDependencies": { - "semantic-release": ">=18.0.0" + "acorn": "^8" } }, - "node_modules/@semantic-release/commit-analyzer": { - "version": "9.0.2", - "resolved": "https://registry.npmjs.org/@semantic-release/commit-analyzer/-/commit-analyzer-9.0.2.tgz", - "integrity": "sha512-E+dr6L+xIHZkX4zNMe6Rnwg4YQrWNXK+rNsvwOPpdFppvZO1olE2fIgWhv89TkQErygevbjsZFSIxp+u6w2e5g==", - "dev": true, + "node_modules/agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", "dependencies": { - "conventional-changelog-angular": "^5.0.0", - "conventional-commits-filter": "^2.0.0", - "conventional-commits-parser": "^3.2.3", - "debug": "^4.0.0", - "import-from": "^4.0.0", - "lodash": "^4.17.4", - "micromatch": "^4.0.2" + "debug": "4" }, "engines": { - "node": ">=14.17" - }, - "peerDependencies": { - "semantic-release": ">=18.0.0-beta.1" + "node": ">= 6.0.0" } }, - "node_modules/@semantic-release/commit-analyzer/node_modules/conventional-changelog-angular": { - "version": "5.0.13", - "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-5.0.13.tgz", - "integrity": "sha512-i/gipMxs7s8L/QeuavPF2hLnJgH6pEZAttySB6aiQLWcX3puWDL3ACVmvBhJGxnAy52Qc15ua26BufY6KpmrVA==", + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, "dependencies": { - "compare-func": "^2.0.0", - "q": "^1.5.1" + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" }, - "engines": { - "node": ">=10" + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/@semantic-release/commit-analyzer/node_modules/conventional-commits-parser": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-3.2.4.tgz", - "integrity": "sha512-nK7sAtfi+QXbxHCYfhpZsfRtaitZLIA6889kFIouLvz6repszQDgxBu7wf2WbU+Dco7sAnNCJYERCwt54WPC2Q==", + "node_modules/ajv-formats": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", + "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", "dev": true, "dependencies": { - "is-text-path": "^1.0.1", - "JSONStream": "^1.0.4", - "lodash": "^4.17.15", - "meow": "^8.0.0", - "split2": "^3.0.0", - "through2": "^4.0.0" + "ajv": "^8.0.0" }, - "bin": { - "conventional-commits-parser": "cli.js" + "peerDependencies": { + "ajv": "^8.0.0" }, - "engines": { - "node": ">=10" + "peerDependenciesMeta": { + "ajv": { + "optional": true + } } }, - "node_modules/@semantic-release/commit-analyzer/node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "node_modules/ajv-formats/node_modules/ajv": { + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", + "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", "dev": true, "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/@semantic-release/commit-analyzer/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "node_modules/ajv-formats/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", "dev": true }, - "node_modules/@semantic-release/commit-analyzer/node_modules/q": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", - "integrity": "sha512-kV/CThkXo6xyFEZUugw/+pIOywXcDbFYgSct5cT3gqlbkBE1SJdwy6UQoZvodiWF/ckQLZyDE/Bu1M6gVu5lVw==", + "node_modules/ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", "dev": true, - "engines": { - "node": ">=0.6.0", - "teleport": ">=0.2.0" + "peerDependencies": { + "ajv": "^6.9.1" } }, - "node_modules/@semantic-release/error": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@semantic-release/error/-/error-3.0.0.tgz", - "integrity": "sha512-5hiM4Un+tpl4cKw3lV4UgzJj+SmfNIDCLLw0TepzQxz9ZGV5ixnqkzIVF+3tp0ZHgcMKE+VNGHJjEeyFG2dcSw==", + "node_modules/ansi-html-community": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/ansi-html-community/-/ansi-html-community-0.0.8.tgz", + "integrity": "sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw==", "dev": true, - "engines": { - "node": ">=14.17" + "engines": [ + "node >= 0.8.0" + ], + "bin": { + "ansi-html": "bin/ansi-html" } }, - "node_modules/@semantic-release/git": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/@semantic-release/git/-/git-10.0.1.tgz", - "integrity": "sha512-eWrx5KguUcU2wUPaO6sfvZI0wPafUKAMNC18aXY4EnNcrZL86dEmpNVnC9uMpGZkmZJ9EfCVJBQx4pV4EMGT1w==", + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", "dev": true, "dependencies": { - "@semantic-release/error": "^3.0.0", - "aggregate-error": "^3.0.0", - "debug": "^4.0.0", - "dir-glob": "^3.0.0", - "execa": "^5.0.0", - "lodash": "^4.17.4", - "micromatch": "^4.0.0", - "p-reduce": "^2.0.0" + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" }, "engines": { - "node": ">=14.17" - }, - "peerDependencies": { - "semantic-release": ">=18.0.0" + "node": ">= 8" } }, - "node_modules/@semantic-release/git/node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } + "node_modules/array-flatten": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-2.1.2.tgz", + "integrity": "sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ==", + "dev": true }, - "node_modules/@semantic-release/git/node_modules/dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "node_modules/batch": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", + "integrity": "sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==", + "dev": true + }, + "node_modules/binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", "dev": true, - "dependencies": { - "path-type": "^4.0.0" - }, "engines": { "node": ">=8" } }, - "node_modules/@semantic-release/git/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true + "node_modules/blockly": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/blockly/-/blockly-10.3.0.tgz", + "integrity": "sha512-+95241EVK5o80F3b/iDP61+LfwKwueqscRyh/JfGKPRA4Tlcg8nngu1DdMhOyVCy8Z58AyXuFJ+96+QlCFx5MQ==", + "dependencies": { + "jsdom": "22.1.0" + } }, - "node_modules/@semantic-release/github": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@semantic-release/github/-/github-8.1.0.tgz", - "integrity": "sha512-erR9E5rpdsz0dW1I7785JtndQuMWN/iDcemcptf67tBNOmBUN0b2YNOgcjYUnBpgRpZ5ozfBHrK7Bz+2ets/Dg==", + "node_modules/body-parser": { + "version": "1.20.1", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", + "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", "dev": true, "dependencies": { - "@octokit/core": "^4.2.1", - "@octokit/plugin-paginate-rest": "^6.1.2", - "@octokit/plugin-retry": "^4.1.3", - "@octokit/plugin-throttling": "^5.2.3", - "@semantic-release/error": "^3.0.0", - "aggregate-error": "^3.0.0", - "debug": "^4.0.0", - "dir-glob": "^3.0.0", - "fs-extra": "^11.0.0", - "globby": "^11.0.0", - "http-proxy-agent": "^7.0.0", - "https-proxy-agent": "^7.0.0", - "issue-parser": "^6.0.0", - "lodash": "^4.17.4", - "mime": "^3.0.0", - "p-filter": "^2.0.0", - "url-join": "^4.0.0" + "bytes": "3.1.2", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.11.0", + "raw-body": "2.5.1", + "type-is": "~1.6.18", + "unpipe": "1.0.0" }, "engines": { - "node": ">=14.17" - }, - "peerDependencies": { - "semantic-release": ">=18.0.0-beta.1" + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" } }, - "node_modules/@semantic-release/github/node_modules/array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "node_modules/body-parser/node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", "dev": true, "engines": { - "node": ">=8" + "node": ">= 0.8" } }, - "node_modules/@semantic-release/github/node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "node_modules/body-parser/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } + "ms": "2.0.0" } }, - "node_modules/@semantic-release/github/node_modules/dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "node_modules/body-parser/node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", "dev": true, "dependencies": { - "path-type": "^4.0.0" + "safer-buffer": ">= 2.1.2 < 3" }, "engines": { - "node": ">=8" + "node": ">=0.10.0" + } + }, + "node_modules/body-parser/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + }, + "node_modules/bonjour-service": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/bonjour-service/-/bonjour-service-1.1.1.tgz", + "integrity": "sha512-Z/5lQRMOG9k7W+FkeGTNjh7htqn/2LMnfOvBZ8pynNZCM9MwkQkI3zeI4oz09uWdcgmgHugVvBqxGg4VQJ5PCg==", + "dev": true, + "dependencies": { + "array-flatten": "^2.1.2", + "dns-equal": "^1.0.0", + "fast-deep-equal": "^3.1.3", + "multicast-dns": "^7.2.5" } }, - "node_modules/@semantic-release/github/node_modules/globby": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", - "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, "dependencies": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.2.9", - "ignore": "^5.2.0", - "merge2": "^1.4.1", - "slash": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" } }, - "node_modules/@semantic-release/github/node_modules/ignore": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", - "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", "dev": true, + "dependencies": { + "fill-range": "^7.0.1" + }, "engines": { - "node": ">= 4" + "node": ">=8" } }, - "node_modules/@semantic-release/github/node_modules/mime": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-3.0.0.tgz", - "integrity": "sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==", + "node_modules/browserslist": { + "version": "4.22.2", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.2.tgz", + "integrity": "sha512-0UgcrvQmBDvZHFGdYUehrCNIazki7/lUP3kkoi/r3YB2amZbFM9J43ZRkJTXBUZK4gmx56+Sqk9+Vs9mwZx9+A==", "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "caniuse-lite": "^1.0.30001565", + "electron-to-chromium": "^1.4.601", + "node-releases": "^2.0.14", + "update-browserslist-db": "^1.0.13" + }, "bin": { - "mime": "cli.js" + "browserslist": "cli.js" }, "engines": { - "node": ">=10.0.0" + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" } }, - "node_modules/@semantic-release/github/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", "dev": true }, - "node_modules/@semantic-release/github/node_modules/slash": { + "node_modules/bytes": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", + "integrity": "sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==", "dev": true, "engines": { - "node": ">=8" + "node": ">= 0.8" } }, - "node_modules/@semantic-release/npm": { - "version": "9.0.2", - "resolved": "https://registry.npmjs.org/@semantic-release/npm/-/npm-9.0.2.tgz", - "integrity": "sha512-zgsynF6McdzxPnFet+a4iO9HpAlARXOM5adz7VGVCvj0ne8wtL2ZOQoDV2wZPDmdEotDIbVeJjafhelZjs9j6g==", + "node_modules/call-bind": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.5.tgz", + "integrity": "sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ==", "dev": true, "dependencies": { - "@semantic-release/error": "^3.0.0", - "aggregate-error": "^3.0.0", - "execa": "^5.0.0", - "fs-extra": "^11.0.0", - "lodash": "^4.17.15", - "nerf-dart": "^1.0.0", - "normalize-url": "^6.0.0", - "npm": "^8.3.0", - "rc": "^1.2.8", - "read-pkg": "^5.0.0", - "registry-auth-token": "^5.0.0", - "semver": "^7.1.2", - "tempy": "^1.0.0" - }, - "engines": { - "node": ">=16 || ^14.17" + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.1", + "set-function-length": "^1.1.1" }, - "peerDependencies": { - "semantic-release": ">=19.0.0" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/@semantic-release/release-notes-generator": { - "version": "10.0.3", - "resolved": "https://registry.npmjs.org/@semantic-release/release-notes-generator/-/release-notes-generator-10.0.3.tgz", - "integrity": "sha512-k4x4VhIKneOWoBGHkx0qZogNjCldLPRiAjnIpMnlUh6PtaWXp/T+C9U7/TaNDDtgDa5HMbHl4WlREdxHio6/3w==", + "node_modules/caniuse-lite": { + "version": "1.0.30001570", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001570.tgz", + "integrity": "sha512-+3e0ASu4sw1SWaoCtvPeyXp+5PsjigkSt8OXZbF9StH5pQWbxEjLAZE3n8Aup5udop1uRiKA7a4utUk/uoSpUw==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ] + }, + "node_modules/chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], "dependencies": { - "conventional-changelog-angular": "^5.0.0", - "conventional-changelog-writer": "^5.0.0", - "conventional-commits-filter": "^2.0.0", - "conventional-commits-parser": "^3.2.3", - "debug": "^4.0.0", - "get-stream": "^6.0.0", - "import-from": "^4.0.0", - "into-stream": "^6.0.0", - "lodash": "^4.17.4", - "read-pkg-up": "^7.0.0" + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" }, "engines": { - "node": ">=14.17" + "node": ">= 8.10.0" }, - "peerDependencies": { - "semantic-release": ">=18.0.0-beta.1" + "optionalDependencies": { + "fsevents": "~2.3.2" } }, - "node_modules/@semantic-release/release-notes-generator/node_modules/conventional-changelog-angular": { - "version": "5.0.13", - "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-5.0.13.tgz", - "integrity": "sha512-i/gipMxs7s8L/QeuavPF2hLnJgH6pEZAttySB6aiQLWcX3puWDL3ACVmvBhJGxnAy52Qc15ua26BufY6KpmrVA==", + "node_modules/chrome-trace-event": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", + "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==", "dev": true, - "dependencies": { - "compare-func": "^2.0.0", - "q": "^1.5.1" - }, "engines": { - "node": ">=10" + "node": ">=6.0" } }, - "node_modules/@semantic-release/release-notes-generator/node_modules/conventional-commits-parser": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-3.2.4.tgz", - "integrity": "sha512-nK7sAtfi+QXbxHCYfhpZsfRtaitZLIA6889kFIouLvz6repszQDgxBu7wf2WbU+Dco7sAnNCJYERCwt54WPC2Q==", + "node_modules/clone-deep": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", + "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", "dev": true, "dependencies": { - "is-text-path": "^1.0.1", - "JSONStream": "^1.0.4", - "lodash": "^4.17.15", - "meow": "^8.0.0", - "split2": "^3.0.0", - "through2": "^4.0.0" - }, - "bin": { - "conventional-commits-parser": "cli.js" + "is-plain-object": "^2.0.4", + "kind-of": "^6.0.2", + "shallow-clone": "^3.0.0" }, "engines": { - "node": ">=10" + "node": ">=6" } }, - "node_modules/@semantic-release/release-notes-generator/node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, + "node_modules/colorette": { + "version": "2.0.20", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", + "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", + "dev": true + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", "dependencies": { - "ms": "2.1.2" + "delayed-stream": "~1.0.0" }, "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } + "node": ">= 0.8" } }, - "node_modules/@semantic-release/release-notes-generator/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", "dev": true }, - "node_modules/@semantic-release/release-notes-generator/node_modules/q": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", - "integrity": "sha512-kV/CThkXo6xyFEZUugw/+pIOywXcDbFYgSct5cT3gqlbkBE1SJdwy6UQoZvodiWF/ckQLZyDE/Bu1M6gVu5lVw==", + "node_modules/compressible": { + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", + "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", "dev": true, + "dependencies": { + "mime-db": ">= 1.43.0 < 2" + }, "engines": { - "node": ">=0.6.0", - "teleport": ">=0.2.0" + "node": ">= 0.6" } }, - "node_modules/@tsconfig/node10": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz", - "integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==", - "dev": true - }, - "node_modules/@tsconfig/node12": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", - "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", - "dev": true - }, - "node_modules/@tsconfig/node14": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", - "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", - "dev": true + "node_modules/compression": { + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz", + "integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==", + "dev": true, + "dependencies": { + "accepts": "~1.3.5", + "bytes": "3.0.0", + "compressible": "~2.0.16", + "debug": "2.6.9", + "on-headers": "~1.0.2", + "safe-buffer": "5.1.2", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.8.0" + } }, - "node_modules/@tsconfig/node16": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", - "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", - "dev": true - }, - "node_modules/@types/minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-hov8bUuiLiyFPGyFPE1lwWhmzYbirOXQNNo40+y3zow8aFVTeyn3VWL0VFFfdNddA8S4Vf0Tc062rzyNr7Paag==", - "dev": true - }, - "node_modules/@types/node": { - "version": "20.5.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.5.1.tgz", - "integrity": "sha512-4tT2UrL5LBqDwoed9wZ6N3umC4Yhz3W3FloMmiiG4JwmUJWpie0c7lcnUNd4gtMKuDEO4wRVS8B6Xa0uMRsMKg==", - "dev": true - }, - "node_modules/@types/normalize-package-data": { - "version": "2.4.4", - "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.4.tgz", - "integrity": "sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==", - "dev": true - }, - "node_modules/@types/parse-json": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.2.tgz", - "integrity": "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==", - "dev": true - }, - "node_modules/@webassemblyjs/ast": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.9.0.tgz", - "integrity": "sha512-C6wW5L+b7ogSDVqymbkkvuW9kruN//YisMED04xzeBBqjHa2FYnmvOlS6Xj68xWQRgWvI9cIglsjFowH/RJyEA==", - "dev": true, - "dependencies": { - "@webassemblyjs/helper-module-context": "1.9.0", - "@webassemblyjs/helper-wasm-bytecode": "1.9.0", - "@webassemblyjs/wast-parser": "1.9.0" - } - }, - "node_modules/@webassemblyjs/floating-point-hex-parser": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.9.0.tgz", - "integrity": "sha512-TG5qcFsS8QB4g4MhrxK5TqfdNe7Ey/7YL/xN+36rRjl/BlGE/NcBvJcqsRgCP6Z92mRE+7N50pRIi8SmKUbcQA==", - "dev": true - }, - "node_modules/@webassemblyjs/helper-api-error": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.9.0.tgz", - "integrity": "sha512-NcMLjoFMXpsASZFxJ5h2HZRcEhDkvnNFOAKneP5RbKRzaWJN36NC4jqQHKwStIhGXu5mUWlUUk7ygdtrO8lbmw==", - "dev": true - }, - "node_modules/@webassemblyjs/helper-buffer": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.9.0.tgz", - "integrity": "sha512-qZol43oqhq6yBPx7YM3m9Bv7WMV9Eevj6kMi6InKOuZxhw+q9hOkvq5e/PpKSiLfyetpaBnogSbNCfBwyB00CA==", - "dev": true - }, - "node_modules/@webassemblyjs/helper-code-frame": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.9.0.tgz", - "integrity": "sha512-ERCYdJBkD9Vu4vtjUYe8LZruWuNIToYq/ME22igL+2vj2dQ2OOujIZr3MEFvfEaqKoVqpsFKAGsRdBSBjrIvZA==", + "node_modules/compression/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, "dependencies": { - "@webassemblyjs/wast-printer": "1.9.0" + "ms": "2.0.0" } }, - "node_modules/@webassemblyjs/helper-fsm": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-fsm/-/helper-fsm-1.9.0.tgz", - "integrity": "sha512-OPRowhGbshCb5PxJ8LocpdX9Kl0uB4XsAjl6jH/dWKlk/mzsANvhwbiULsaiqT5GZGT9qinTICdj6PLuM5gslw==", + "node_modules/compression/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", "dev": true }, - "node_modules/@webassemblyjs/helper-module-context": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-module-context/-/helper-module-context-1.9.0.tgz", - "integrity": "sha512-MJCW8iGC08tMk2enck1aPW+BE5Cw8/7ph/VGZxwyvGbJwjktKkDK7vy7gAmMDx88D7mhDTCNKAW5tED+gZ0W8g==", - "dev": true, - "dependencies": { - "@webassemblyjs/ast": "1.9.0" - } - }, - "node_modules/@webassemblyjs/helper-wasm-bytecode": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.9.0.tgz", - "integrity": "sha512-R7FStIzyNcd7xKxCZH5lE0Bqy+hGTwS3LJjuv1ZVxd9O7eHCedSdrId/hMOd20I+v8wDXEn+bjfKDLzTepoaUw==", + "node_modules/compression/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", "dev": true }, - "node_modules/@webassemblyjs/helper-wasm-section": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.9.0.tgz", - "integrity": "sha512-XnMB8l3ek4tvrKUUku+IVaXNHz2YsJyOOmz+MMkZvh8h1uSJpSen6vYnw3IoQ7WwEuAhL8Efjms1ZWjqh2agvw==", - "dev": true, - "dependencies": { - "@webassemblyjs/ast": "1.9.0", - "@webassemblyjs/helper-buffer": "1.9.0", - "@webassemblyjs/helper-wasm-bytecode": "1.9.0", - "@webassemblyjs/wasm-gen": "1.9.0" - } - }, - "node_modules/@webassemblyjs/ieee754": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.9.0.tgz", - "integrity": "sha512-dcX8JuYU/gvymzIHc9DgxTzUUTLexWwt8uCTWP3otys596io0L5aW02Gb1RjYpx2+0Jus1h4ZFqjla7umFniTg==", - "dev": true, - "dependencies": { - "@xtuc/ieee754": "^1.2.0" - } - }, - "node_modules/@webassemblyjs/leb128": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.9.0.tgz", - "integrity": "sha512-ENVzM5VwV1ojs9jam6vPys97B/S65YQtv/aanqnU7D8aSoHFX8GyhGg0CMfyKNIHBuAVjy3tlzd5QMMINa7wpw==", - "dev": true, - "dependencies": { - "@xtuc/long": "4.2.2" - } - }, - "node_modules/@webassemblyjs/utf8": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.9.0.tgz", - "integrity": "sha512-GZbQlWtopBTP0u7cHrEx+73yZKrQoBMpwkGEIqlacljhXCkVM1kMQge/Mf+csMJAjEdSwhOyLAS0AoR3AG5P8w==", + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", "dev": true }, - "node_modules/@webassemblyjs/wasm-edit": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.9.0.tgz", - "integrity": "sha512-FgHzBm80uwz5M8WKnMTn6j/sVbqilPdQXTWraSjBwFXSYGirpkSWE2R9Qvz9tNiTKQvoKILpCuTjBKzOIm0nxw==", - "dev": true, - "dependencies": { - "@webassemblyjs/ast": "1.9.0", - "@webassemblyjs/helper-buffer": "1.9.0", - "@webassemblyjs/helper-wasm-bytecode": "1.9.0", - "@webassemblyjs/helper-wasm-section": "1.9.0", - "@webassemblyjs/wasm-gen": "1.9.0", - "@webassemblyjs/wasm-opt": "1.9.0", - "@webassemblyjs/wasm-parser": "1.9.0", - "@webassemblyjs/wast-printer": "1.9.0" - } - }, - "node_modules/@webassemblyjs/wasm-gen": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.9.0.tgz", - "integrity": "sha512-cPE3o44YzOOHvlsb4+E9qSqjc9Qf9Na1OO/BHFy4OI91XDE14MjFN4lTMezzaIWdPqHnsTodGGNP+iRSYfGkjA==", - "dev": true, - "dependencies": { - "@webassemblyjs/ast": "1.9.0", - "@webassemblyjs/helper-wasm-bytecode": "1.9.0", - "@webassemblyjs/ieee754": "1.9.0", - "@webassemblyjs/leb128": "1.9.0", - "@webassemblyjs/utf8": "1.9.0" - } - }, - "node_modules/@webassemblyjs/wasm-opt": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.9.0.tgz", - "integrity": "sha512-Qkjgm6Anhm+OMbIL0iokO7meajkzQD71ioelnfPEj6r4eOFuqm4YC3VBPqXjFyyNwowzbMD+hizmprP/Fwkl2A==", + "node_modules/connect-history-api-fallback": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-2.0.0.tgz", + "integrity": "sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA==", "dev": true, - "dependencies": { - "@webassemblyjs/ast": "1.9.0", - "@webassemblyjs/helper-buffer": "1.9.0", - "@webassemblyjs/wasm-gen": "1.9.0", - "@webassemblyjs/wasm-parser": "1.9.0" + "engines": { + "node": ">=0.8" } }, - "node_modules/@webassemblyjs/wasm-parser": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.9.0.tgz", - "integrity": "sha512-9+wkMowR2AmdSWQzsPEjFU7njh8HTO5MqO8vjwEHuM+AMHioNqSBONRdr0NQQ3dVQrzp0s8lTcYqzUdb7YgELA==", + "node_modules/content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", "dev": true, "dependencies": { - "@webassemblyjs/ast": "1.9.0", - "@webassemblyjs/helper-api-error": "1.9.0", - "@webassemblyjs/helper-wasm-bytecode": "1.9.0", - "@webassemblyjs/ieee754": "1.9.0", - "@webassemblyjs/leb128": "1.9.0", - "@webassemblyjs/utf8": "1.9.0" + "safe-buffer": "5.2.1" + }, + "engines": { + "node": ">= 0.6" } }, - "node_modules/@webassemblyjs/wast-parser": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-parser/-/wast-parser-1.9.0.tgz", - "integrity": "sha512-qsqSAP3QQ3LyZjNC/0jBJ/ToSxfYJ8kYyuiGvtn/8MK89VrNEfwj7BPQzJVHi0jGTRK2dGdJ5PRqhtjzoww+bw==", + "node_modules/content-type": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", "dev": true, - "dependencies": { - "@webassemblyjs/ast": "1.9.0", - "@webassemblyjs/floating-point-hex-parser": "1.9.0", - "@webassemblyjs/helper-api-error": "1.9.0", - "@webassemblyjs/helper-code-frame": "1.9.0", - "@webassemblyjs/helper-fsm": "1.9.0", - "@xtuc/long": "4.2.2" + "engines": { + "node": ">= 0.6" } }, - "node_modules/@webassemblyjs/wast-printer": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.9.0.tgz", - "integrity": "sha512-2J0nE95rHXHyQ24cWjMKJ1tqB/ds8z/cyeOZxJhcb+rW+SQASVjuznUSmdz5GpVJTzU8JkhYut0D3siFDD6wsA==", + "node_modules/cookie": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", + "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", "dev": true, - "dependencies": { - "@webassemblyjs/ast": "1.9.0", - "@webassemblyjs/wast-parser": "1.9.0", - "@xtuc/long": "4.2.2" + "engines": { + "node": ">= 0.6" } }, - "node_modules/@xtuc/ieee754": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", - "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", + "node_modules/cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", "dev": true }, - "node_modules/@xtuc/long": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", - "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", "dev": true }, - "node_modules/acorn": { - "version": "5.7.4", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.4.tgz", - "integrity": "sha512-1D++VG7BhrtvQpNbBzovKNc1FLGGEE/oGe7b9xJm/RFHMBeUaUGpluV9RLjZa47YFdPcDAenEYuq9pQPcMdLJg==", + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", "dev": true, - "bin": { - "acorn": "bin/acorn" + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" }, "engines": { - "node": ">=0.4.0" + "node": ">= 8" } }, - "node_modules/acorn-jsx": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz", - "integrity": "sha512-AU7pnZkguthwBjKgCg6998ByQNIMjbuDQZ8bb78QAFZwPfmKia8AIzgY/gWgqCjnht8JLdXmB4YxA0KaV60ncQ==", - "dev": true, + "node_modules/cssstyle": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-3.0.0.tgz", + "integrity": "sha512-N4u2ABATi3Qplzf0hWbVCdjenim8F3ojEXpBDF5hBpjzW182MjNGLqfmQ0SkSPeQ+V86ZXgeH8aXj6kayd4jgg==", "dependencies": { - "acorn": "^3.0.4" - } - }, - "node_modules/acorn-jsx/node_modules/acorn": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz", - "integrity": "sha512-OLUyIIZ7mF5oaAUT1w0TFqQS81q3saT46x8t7ukpPjMNk+nbs4ZHhs7ToV8EWnLYLepjETXd4XaCE4uxkMeqUw==", - "dev": true, - "bin": { - "acorn": "bin/acorn" + "rrweb-cssom": "^0.6.0" }, "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/acorn-walk": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.2.tgz", - "integrity": "sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==", - "dev": true, - "engines": { - "node": ">=0.4.0" + "node": ">=14" } }, - "node_modules/agent-base": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz", - "integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==", - "dev": true, + "node_modules/data-urls": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-4.0.0.tgz", + "integrity": "sha512-/mMTei/JXPqvFqQtfyTowxmJVwr2PVAeCcDxyFf6LhoOu/09TX2OX3kb2wzi4DMXcfj4OItwDOnhl5oziPnT6g==", "dependencies": { - "debug": "^4.3.4" + "abab": "^2.0.6", + "whatwg-mimetype": "^3.0.0", + "whatwg-url": "^12.0.0" }, "engines": { - "node": ">= 14" + "node": ">=14" } }, - "node_modules/agent-base/node_modules/debug": { + "node_modules/debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, "dependencies": { "ms": "2.1.2" }, @@ -1385,775 +1082,653 @@ } } }, - "node_modules/agent-base/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true + "node_modules/decimal.js": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.3.tgz", + "integrity": "sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==" }, - "node_modules/aggregate-error": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", - "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", + "node_modules/default-gateway": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-6.0.3.tgz", + "integrity": "sha512-fwSOJsbbNzZ/CUFpqFBqYfYNLj1NbMPm8MMCIzHjC83iSJRBEGmDUxU+WP661BaBQImeC2yHwXtz+P/O9o+XEg==", "dev": true, "dependencies": { - "clean-stack": "^2.0.0", - "indent-string": "^4.0.0" + "execa": "^5.0.0" }, "engines": { - "node": ">=8" + "node": ">= 10" } }, - "node_modules/ajv": { - "version": "8.12.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", - "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "node_modules/define-data-property": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.1.tgz", + "integrity": "sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==", "dev": true, "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" + "get-intrinsic": "^1.2.1", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.0" }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" + "engines": { + "node": ">= 0.4" } }, - "node_modules/ajv-errors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/ajv-errors/-/ajv-errors-1.0.1.tgz", - "integrity": "sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ==", + "node_modules/define-lazy-prop": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", + "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==", "dev": true, - "peerDependencies": { - "ajv": ">=5.0.0" + "engines": { + "node": ">=8" } }, - "node_modules/ansi-escapes": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz", - "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==", - "dev": true, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", "engines": { - "node": ">=4" + "node": ">=0.4.0" } }, - "node_modules/ansi-regex": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz", - "integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==", + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", "dev": true, "engines": { - "node": ">=4" + "node": ">= 0.8" } }, - "node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "node_modules/destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" } }, - "node_modules/ansicolors": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/ansicolors/-/ansicolors-0.3.2.tgz", - "integrity": "sha512-QXu7BPrP29VllRxH8GwB7x5iX5qWKAAMLqKQGWTeLWVlNHNOpVMJ91dsxQAIWXpjuW5wqvxu3Jd/nRjrJ+0pqg==", + "node_modules/detect-node": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", + "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==", "dev": true }, - "node_modules/anymatch": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", - "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "node_modules/dns-equal": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/dns-equal/-/dns-equal-1.0.0.tgz", + "integrity": "sha512-z+paD6YUQsk+AbGCEM4PrOXSss5gd66QfcVBFTKR/HpFL9jCqikS94HYwKww6fQyO7IxrIIyUu+g0Ka9tUS2Cg==", + "dev": true + }, + "node_modules/dns-packet": { + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-5.6.1.tgz", + "integrity": "sha512-l4gcSouhcgIKRvyy99RNVOgxXiicE+2jZoNmaNmZ6JXiGajBOJAesk1OBlJuM5k2c+eudGdLxDqXuPCKIj6kpw==", "dev": true, - "optional": true, "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" + "@leichtgewicht/ip-codec": "^2.0.1" }, "engines": { - "node": ">= 8" + "node": ">=6" } }, - "node_modules/aproba": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", - "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", - "dev": true - }, - "node_modules/arg": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", - "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", - "dev": true + "node_modules/domexception": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/domexception/-/domexception-4.0.0.tgz", + "integrity": "sha512-A2is4PLG+eeSfoTMA95/s4pvAoSo2mKtiM5jlHkAVewmiO8ISFTFKZjH7UAM1Atli/OT/7JHOrJRJiMKUZKYBw==", + "deprecated": "Use your platform's native DOMException instead", + "dependencies": { + "webidl-conversions": "^7.0.0" + }, + "engines": { + "node": ">=12" + } }, - "node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", "dev": true }, - "node_modules/argv-formatter": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/argv-formatter/-/argv-formatter-1.0.0.tgz", - "integrity": "sha512-F2+Hkm9xFaRg+GkaNnbwXNDV5O6pnCFEmqyhvfC/Ic5LbgOWjJh3L+mN/s91rxVL3znE7DYVpW0GJFT+4YBgWw==", + "node_modules/electron-to-chromium": { + "version": "1.4.615", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.615.tgz", + "integrity": "sha512-/bKPPcgZVUziECqDc+0HkT87+0zhaWSZHNXqF8FLd2lQcptpmUFwoCSWjCdOng9Gdq+afKArPdEg/0ZW461Eng==", "dev": true }, - "node_modules/arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha512-YVIQ82gZPGBebQV/a8dar4AitzCQs0jjXwMPZllpXMaGjXPYVUawSxQrRsjhjupyVxEvbHgUmIhKVlND+j02kA==", + "node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", "dev": true, "engines": { - "node": ">=0.10.0" + "node": ">= 0.8" } }, - "node_modules/arr-flatten": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", - "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", + "node_modules/enhanced-resolve": { + "version": "5.15.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.15.0.tgz", + "integrity": "sha512-LXYT42KJ7lpIKECr2mAXIaMldcNCh/7E0KBKOu4KSfkHmP+mZmSs+8V5gBAqisWBy0OO4W5Oyys0GO1Y8KtdKg==", "dev": true, + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + }, "engines": { - "node": ">=0.10.0" + "node": ">=10.13.0" } }, - "node_modules/arr-union": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", - "integrity": "sha512-sKpyeERZ02v1FeCZT8lrfJq5u6goHCtpTAzPwJYe7c8SPFOboNjNg1vz2L4VTn9T4PQxEx13TbXLmYUcS6Ug7Q==", - "dev": true, + "node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", "engines": { - "node": ">=0.10.0" + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" } }, - "node_modules/array-buffer-byte-length": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz", - "integrity": "sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==", + "node_modules/envinfo": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.11.0.tgz", + "integrity": "sha512-G9/6xF1FPbIw0TtalAMaVPpiq2aDEuKLXM314jPVAO9r2fo2a4BLqMNkmRS7O/xPPZ+COAhGIz3ETvHEV3eUcg==", "dev": true, - "dependencies": { - "call-bind": "^1.0.5", - "is-array-buffer": "^3.0.4" + "bin": { + "envinfo": "dist/cli.js" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=4" } }, - "node_modules/array-ify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/array-ify/-/array-ify-1.0.0.tgz", - "integrity": "sha512-c5AMf34bKdvPhQ7tBGhqkgKNUzMr4WUs+WDtC2ZUGOUncbxKMTvqxYctiseW3+L4bA8ec+GcZ6/A/FW4m8ukng==", + "node_modules/es-module-lexer": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.4.1.tgz", + "integrity": "sha512-cXLGjP0c4T3flZJKQSuziYoq7MlT+rnvfZjfp7h+I7K9BNX54kP9nyWvdbwjQ4u1iWbOL4u96fgeZLToQlZC7w==", "dev": true }, - "node_modules/array-union": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", - "integrity": "sha512-Dxr6QJj/RdU/hCaBjOfxW+q6lyuVE6JFWIrAUpuOOhoJJoQ99cUn3igRaHVB5P9WrgFVN0FfArM3x0cueOU8ng==", + "node_modules/escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", "dev": true, - "dependencies": { - "array-uniq": "^1.0.1" - }, "engines": { - "node": ">=0.10.0" + "node": ">=6" } }, - "node_modules/array-uniq": { + "node_modules/escape-html": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", - "integrity": "sha512-MNha4BWQ6JbwhFhj03YK552f7cb3AzoE8SzeljgChvL1dl3IcvggXVz1DilzySZkCja+CXuZbdW7yATchWn8/Q==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", + "dev": true }, - "node_modules/array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha512-SleRWjh9JUud2wH1hPs9rZBZ33H6T9HOiL0uwGnGx9FpE6wKGyfWugmbkEOIs6qWrZhg0LWeLziLrEwQJhs5mQ==", + "node_modules/eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, "engines": { - "node": ">=0.10.0" + "node": ">=8.0.0" } }, - "node_modules/arraybuffer.prototype.slice": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.3.tgz", - "integrity": "sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==", + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", "dev": true, "dependencies": { - "array-buffer-byte-length": "^1.0.1", - "call-bind": "^1.0.5", - "define-properties": "^1.2.1", - "es-abstract": "^1.22.3", - "es-errors": "^1.2.1", - "get-intrinsic": "^1.2.3", - "is-array-buffer": "^3.0.4", - "is-shared-array-buffer": "^1.0.2" + "estraverse": "^5.2.0" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=4.0" } }, - "node_modules/arrify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==", + "node_modules/esrecurse/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true, "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/asn1": { - "version": "0.2.6", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", - "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==", - "dev": true, - "dependencies": { - "safer-buffer": "~2.1.0" - } - }, - "node_modules/asn1.js": { - "version": "4.10.1", - "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz", - "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==", - "dev": true, - "dependencies": { - "bn.js": "^4.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" - } - }, - "node_modules/asn1.js/node_modules/bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true - }, - "node_modules/assert": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/assert/-/assert-1.5.1.tgz", - "integrity": "sha512-zzw1uCAgLbsKwBfFc8CX78DDg+xZeBksSO3vwVIDDN5i94eOrPsSSyiVhmsSABFDM/OcpE2aagCat9dnWQLG1A==", - "dev": true, - "dependencies": { - "object.assign": "^4.1.4", - "util": "^0.10.4" + "node": ">=4.0" } }, - "node_modules/assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", + "node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", "dev": true, "engines": { - "node": ">=0.8" - } - }, - "node_modules/assert/node_modules/inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==", - "dev": true - }, - "node_modules/assert/node_modules/util": { - "version": "0.10.4", - "resolved": "https://registry.npmjs.org/util/-/util-0.10.4.tgz", - "integrity": "sha512-0Pm9hTQ3se5ll1XihRic3FDIku70C+iHUdT/W926rSgHV5QgXsYbKZN8MSC3tJtSkhuROzvsQjAaFENRXr+19A==", - "dev": true, - "dependencies": { - "inherits": "2.0.3" + "node": ">=4.0" } }, - "node_modules/assign-symbols": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", - "integrity": "sha512-Q+JC7Whu8HhmTdBph/Tq59IoRtoy6KAm5zzPv00WdujX82lbAL8K7WVjne7vdCsAmbF4AYaDOPyO3k0kl8qIrw==", + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", "dev": true, "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/async": { - "version": "2.6.4", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.4.tgz", - "integrity": "sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==", - "dev": true, - "dependencies": { - "lodash": "^4.17.14" + "node": ">= 0.6" } }, - "node_modules/async-each": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.6.tgz", - "integrity": "sha512-c646jH1avxr+aVpndVMeAfYw7wAa6idufrlN3LPA4PmKS0QEGp6PIC9nwz0WQkkvBGAMEki3pFdtxaF39J9vvg==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - ], - "optional": true - }, - "node_modules/asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "node_modules/eventemitter3": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", "dev": true }, - "node_modules/atob": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", - "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", + "node_modules/events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", "dev": true, - "bin": { - "atob": "bin/atob.js" - }, "engines": { - "node": ">= 4.5.0" + "node": ">=0.8.x" } }, - "node_modules/available-typed-arrays": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", - "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", + "node_modules/execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", "dev": true, "dependencies": { - "possible-typed-array-names": "^1.0.0" + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" }, "engines": { - "node": ">= 0.4" + "node": ">=10" }, "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/aws-sign2": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==", - "dev": true, - "engines": { - "node": "*" + "url": "https://github.com/sindresorhus/execa?sponsor=1" } }, - "node_modules/aws4": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.12.0.tgz", - "integrity": "sha512-NmWvPnx0F1SfrQbYwOi7OeaNGokp9XhzNioJ/CSBs8Qa4vxug81mhJEAVZwxXuBmYB5KDRfMq/F3RR0BIU7sWg==", + "node_modules/express": { + "version": "4.18.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", + "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", + "dev": true, + "dependencies": { + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "1.20.1", + "content-disposition": "0.5.4", + "content-type": "~1.0.4", + "cookie": "0.5.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "2.0.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "1.2.0", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.7", + "qs": "6.11.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "0.18.0", + "serve-static": "1.15.0", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/express/node_modules/array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", "dev": true }, - "node_modules/babel-code-frame": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", - "integrity": "sha512-XqYMR2dfdGMW+hd0IUZ2PwK+fGeFkOxZJ0wY+JaQAHzt1Zx8LcvpiZD2NiGkEG8qx0CfkAOr5xt76d1e8vG90g==", + "node_modules/express/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, "dependencies": { - "chalk": "^1.1.3", - "esutils": "^2.0.2", - "js-tokens": "^3.0.2" + "ms": "2.0.0" } }, - "node_modules/babel-code-frame/node_modules/ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", + "node_modules/express/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "node_modules/fastest-levenshtein": { + "version": "1.0.16", + "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz", + "integrity": "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==", "dev": true, "engines": { - "node": ">=0.10.0" + "node": ">= 4.9.1" } }, - "node_modules/babel-code-frame/node_modules/ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha512-kmCevFghRiWM7HB5zTPULl4r9bVFSWjz62MhqizDGUrq2NWuNMQyuv4tHHoKJHs69M/MF64lEcHdYIocrdWQYA==", + "node_modules/faye-websocket": { + "version": "0.11.4", + "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz", + "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==", "dev": true, + "dependencies": { + "websocket-driver": ">=0.5.1" + }, "engines": { - "node": ">=0.10.0" + "node": ">=0.8.0" } }, - "node_modules/babel-code-frame/node_modules/chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha512-U3lRVLMSlsCfjqYPbLyVv11M9CPW4I728d6TCKMAOJueEeB9/8o+eSsMnxPJD+Q+K909sdESg7C+tIkoH6on1A==", + "node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", "dev": true, "dependencies": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" + "to-regex-range": "^5.0.1" }, "engines": { - "node": ">=0.10.0" + "node": ">=8" } }, - "node_modules/babel-code-frame/node_modules/strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==", + "node_modules/finalhandler": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", + "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", "dev": true, "dependencies": { - "ansi-regex": "^2.0.0" + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "statuses": "2.0.1", + "unpipe": "~1.0.0" }, "engines": { - "node": ">=0.10.0" + "node": ">= 0.8" } }, - "node_modules/babel-code-frame/node_modules/supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha512-KKNVtd6pCYgPIKU4cp2733HWYCpplQhddZLBUryaAHou723x+FRzQ5Df824Fj+IyyuiQTRoub4SnIFfIcrp70g==", + "node_modules/finalhandler/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, - "engines": { - "node": ">=0.8.0" + "dependencies": { + "ms": "2.0.0" } }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "node_modules/finalhandler/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", "dev": true }, - "node_modules/base": { - "version": "0.11.2", - "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", - "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", + "node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", "dev": true, "dependencies": { - "cache-base": "^1.0.1", - "class-utils": "^0.3.5", - "component-emitter": "^1.2.1", - "define-property": "^1.0.0", - "isobject": "^3.0.1", - "mixin-deep": "^1.2.0", - "pascalcase": "^0.1.1" + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" }, "engines": { - "node": ">=0.10.0" + "node": ">=8" } }, - "node_modules/base/node_modules/define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==", + "node_modules/flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", "dev": true, - "dependencies": { - "is-descriptor": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" + "bin": { + "flat": "cli.js" } }, - "node_modules/base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "node_modules/follow-redirects": { + "version": "1.15.3", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.3.tgz", + "integrity": "sha512-1VzOtuEM8pC9SFU1E+8KfTjZyMztRsgEfwQl44z8A25uy13jSzTj6dyK2Df52iV0vgHCfBwLhDWevLn95w5v6Q==", "dev": true, "funding": [ { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true } - ] - }, - "node_modules/bcrypt-pbkdf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==", - "dev": true, - "dependencies": { - "tweetnacl": "^0.14.3" } }, - "node_modules/before-after-hook": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.3.tgz", - "integrity": "sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ==", - "dev": true - }, - "node_modules/big.js": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", - "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", + "node_modules/form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, "engines": { - "node": "*" + "node": ">= 6" } }, - "node_modules/binary-extensions": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", - "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", + "node_modules/forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", "dev": true, - "optional": true, "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">= 0.6" } }, - "node_modules/bindings": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", - "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", + "node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", "dev": true, - "optional": true, - "dependencies": { - "file-uri-to-path": "1.0.0" + "engines": { + "node": ">= 0.6" } }, - "node_modules/bluebird": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", - "dev": true - }, - "node_modules/bn.js": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", - "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==", + "node_modules/fs-monkey": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.0.5.tgz", + "integrity": "sha512-8uMbBjrhzW76TYgEV27Y5E//W2f/lTFmx78P2w19FZSxarhI/798APGQyuGCwmkNxgwGRhrLfvWyLBvNtuOmew==", "dev": true }, - "node_modules/bottleneck": { - "version": "2.19.5", - "resolved": "https://registry.npmjs.org/bottleneck/-/bottleneck-2.19.5.tgz", - "integrity": "sha512-VHiNCbI1lKdl44tGrhNfU3lup0Tj/ZBMJB5/2ZbNXRCPuRCO7ed2mgcK4r17y+KB2EfuYuRaVlwNbAeaWGSpbw==", + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", "dev": true }, - "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", "dev": true, - "dependencies": { - "fill-range": "^7.0.1" - }, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], "engines": { - "node": ">=8" + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, - "node_modules/brorand": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", - "integrity": "sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==", - "dev": true - }, - "node_modules/browser-stdout": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.0.tgz", - "integrity": "sha512-7Rfk377tpSM9TWBEeHs0FlDZGoAIei2V/4MdZJoFMBFAK6BqLpxAIUepGRHGdPFgGsLb02PXovC4qddyHvQqTg==", - "dev": true - }, - "node_modules/browserify-aes": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", - "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", "dev": true, - "dependencies": { - "buffer-xor": "^1.0.3", - "cipher-base": "^1.0.0", - "create-hash": "^1.1.0", - "evp_bytestokey": "^1.0.3", - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/browserify-cipher": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", - "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", + "node_modules/get-intrinsic": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.2.tgz", + "integrity": "sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA==", "dev": true, "dependencies": { - "browserify-aes": "^1.0.4", - "browserify-des": "^1.0.0", - "evp_bytestokey": "^1.0.0" + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/browserify-des": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", - "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", + "node_modules/get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", "dev": true, - "dependencies": { - "cipher-base": "^1.0.1", - "des.js": "^1.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/browserify-rsa": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.1.0.tgz", - "integrity": "sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog==", + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", "dev": true, "dependencies": { - "bn.js": "^5.0.0", - "randombytes": "^2.0.1" + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/browserify-sign": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.3.tgz", - "integrity": "sha512-JWCZW6SKhfhjJxO8Tyiiy+XYB7cqd2S5/+WeYHsKdNKFlCBhKbblba1A/HN/90YwtxKc8tCErjffZl++UNmGiw==", + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "dev": true, "dependencies": { - "bn.js": "^5.2.1", - "browserify-rsa": "^4.1.0", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "elliptic": "^6.5.5", - "hash-base": "~3.0", - "inherits": "^2.0.4", - "parse-asn1": "^5.1.7", - "readable-stream": "^2.3.8", - "safe-buffer": "^5.2.1" + "is-glob": "^4.0.1" }, "engines": { - "node": ">= 0.12" + "node": ">= 6" } }, - "node_modules/browserify-sign/node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/browserify-zlib": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", - "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", - "dev": true, - "dependencies": { - "pako": "~1.0.5" - } + "node_modules/glob-to-regexp": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", + "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", + "dev": true }, - "node_modules/buffer": { - "version": "4.9.2", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", - "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==", + "node_modules/gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", "dev": true, "dependencies": { - "base64-js": "^1.0.2", - "ieee754": "^1.1.4", - "isarray": "^1.0.0" + "get-intrinsic": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "dev": true - }, - "node_modules/buffer-xor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", - "integrity": "sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ==", + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", "dev": true }, - "node_modules/builtin-status-codes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", - "integrity": "sha512-HpGFw18DgFWlncDfjTa2rcQ4W88O1mC8e8yZ2AvQY5KDaktSTwo+KRf6nHK6FRI5FyRyb/5T6+TSxfP7QyGsmQ==", + "node_modules/handle-thing": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz", + "integrity": "sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==", "dev": true }, - "node_modules/cacache": { - "version": "10.0.4", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-10.0.4.tgz", - "integrity": "sha512-Dph0MzuH+rTQzGPNT9fAnrPmMmjKfST6trxJeK7NQuHRaVw24VzPRWTmg9MpcwOVQZO0E1FBICUlFeNaKPIfHA==", + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true, - "dependencies": { - "bluebird": "^3.5.1", - "chownr": "^1.0.1", - "glob": "^7.1.2", - "graceful-fs": "^4.1.11", - "lru-cache": "^4.1.1", - "mississippi": "^2.0.0", - "mkdirp": "^0.5.1", - "move-concurrently": "^1.0.1", - "promise-inflight": "^1.0.1", - "rimraf": "^2.6.2", - "ssri": "^5.2.4", - "unique-filename": "^1.1.0", - "y18n": "^4.0.0" + "engines": { + "node": ">=8" } }, - "node_modules/cache-base": { + "node_modules/has-property-descriptors": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", - "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz", + "integrity": "sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg==", "dev": true, "dependencies": { - "collection-visit": "^1.0.0", - "component-emitter": "^1.2.1", - "get-value": "^2.0.6", - "has-value": "^1.0.0", - "isobject": "^3.0.1", - "set-value": "^2.0.0", - "to-object-path": "^0.3.0", - "union-value": "^1.0.0", - "unset-value": "^1.0.0" + "get-intrinsic": "^1.2.2" }, - "engines": { - "node": ">=0.10.0" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/call-bind": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", - "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", + "node_modules/has-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", + "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", "dev": true, - "dependencies": { - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.4", - "set-function-length": "^1.2.1" + "engines": { + "node": ">= 0.4" }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "dev": true, "engines": { "node": ">= 0.4" }, @@ -2161,13195 +1736,5344 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/caller-path": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz", - "integrity": "sha512-UJiE1otjXPF5/x+T3zTnSFiTOEmJoGTD9HmBoxnCUwho61a2eSNn/VwtwuIBDAo2SEOv1AJ7ARI5gCmohFLu/g==", + "node_modules/hasown": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz", + "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==", "dev": true, "dependencies": { - "callsites": "^0.2.0" + "function-bind": "^1.1.2" }, "engines": { - "node": ">=0.10.0" + "node": ">= 0.4" } }, - "node_modules/caller-path/node_modules/callsites": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz", - "integrity": "sha512-Zv4Dns9IbXXmPkgRRUjAaJQgfN4xX5p6+RQFhWUqscdvvK2xK/ZL8b3IXIJsj+4sD+f24NwnWy2BY8AJ82JB0A==", + "node_modules/hpack.js": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz", + "integrity": "sha512-zJxVehUdMGIKsRaNt7apO2Gqp0BdqW5yaiGHXXmbpvxgBYVZnAql+BJb4RO5ad2MgpbZKn5G6nMnegrH1FcNYQ==", "dev": true, - "engines": { - "node": ">=0.10.0" + "dependencies": { + "inherits": "^2.0.1", + "obuf": "^1.0.0", + "readable-stream": "^2.0.1", + "wbuf": "^1.1.0" } }, - "node_modules/callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "node_modules/hpack.js/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", "dev": true, - "engines": { - "node": ">=6" + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" } }, - "node_modules/camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "node_modules/hpack.js/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "node_modules/hpack.js/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "dev": true, - "engines": { - "node": ">=6" + "dependencies": { + "safe-buffer": "~5.1.0" } }, - "node_modules/camelcase-keys": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-6.2.2.tgz", - "integrity": "sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==", - "dev": true, + "node_modules/html-encoding-sniffer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-3.0.0.tgz", + "integrity": "sha512-oWv4T4yJ52iKrufjnyZPkrN0CH3QnrUqdB6In1g5Fe1mia8GmF36gnfNySxoZtxD5+NmYw1EElVXiBk93UeskA==", "dependencies": { - "camelcase": "^5.3.1", - "map-obj": "^4.0.0", - "quick-lru": "^4.0.1" + "whatwg-encoding": "^2.0.0" }, "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=12" } }, - "node_modules/cardinal": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/cardinal/-/cardinal-2.1.1.tgz", - "integrity": "sha512-JSr5eOgoEymtYHBjNWyjrMqet9Am2miJhlfKNdqLp6zoeAh0KN5dRAcxlecj5mAJrmQomgiOBj35xHLrFjqBpw==", + "node_modules/html-entities": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.4.0.tgz", + "integrity": "sha512-igBTJcNNNhvZFRtm8uA6xMY6xYleeDwn3PeBCkDz7tHttv4F2hsDI2aPgNERWzvRcNYHNT3ymRaQzllmXj4YsQ==", "dev": true, - "dependencies": { - "ansicolors": "~0.3.2", - "redeyed": "~2.1.0" - }, - "bin": { - "cdl": "bin/cdl.js" - } + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/mdevils" + }, + { + "type": "patreon", + "url": "https://patreon.com/mdevils" + } + ] }, - "node_modules/caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==", + "node_modules/http-deceiver": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz", + "integrity": "sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw==", "dev": true }, - "node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "node_modules/http-errors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", "dev": true, "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" }, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "node": ">= 0.8" } }, - "node_modules/chardet": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.4.2.tgz", - "integrity": "sha512-j/Toj7f1z98Hh2cYo2BVr85EpIRWqUi7rtRSGxh/cqUjqrnJe9l9UE7IUGd2vQ2p+kSHLkSzObQPZPLUC6TQwg==", + "node_modules/http-parser-js": { + "version": "0.5.8", + "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.8.tgz", + "integrity": "sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q==", "dev": true }, - "node_modules/chokidar": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", - "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "node_modules/http-proxy": { + "version": "1.18.1", + "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", + "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", "dev": true, - "optional": true, "dependencies": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" + "eventemitter3": "^4.0.0", + "follow-redirects": "^1.0.0", + "requires-port": "^1.0.0" }, "engines": { - "node": ">= 8.10.0" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" + "node": ">=8.0.0" } }, - "node_modules/chownr": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", - "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", - "dev": true - }, - "node_modules/chrome-trace-event": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", - "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==", - "dev": true, + "node_modules/http-proxy-agent": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", + "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==", + "dependencies": { + "@tootallnate/once": "2", + "agent-base": "6", + "debug": "4" + }, "engines": { - "node": ">=6.0" + "node": ">= 6" } }, - "node_modules/cipher-base": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", - "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", + "node_modules/http-proxy-middleware": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.6.tgz", + "integrity": "sha512-ya/UeJ6HVBYxrgYotAZo1KvPWlgB48kUJLDePFeneHsVujFaW5WNj2NgWCAE//B1Dl02BIfYlpNgBy8Kf8Rjmw==", "dev": true, "dependencies": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" + "@types/http-proxy": "^1.17.8", + "http-proxy": "^1.18.1", + "is-glob": "^4.0.1", + "is-plain-obj": "^3.0.0", + "micromatch": "^4.0.2" + }, + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "@types/express": "^4.17.13" + }, + "peerDependenciesMeta": { + "@types/express": { + "optional": true + } } }, - "node_modules/circular-json": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz", - "integrity": "sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A==", - "deprecated": "CircularJSON is in maintenance only, flatted is its successor.", - "dev": true - }, - "node_modules/class-utils": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", - "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", - "dev": true, + "node_modules/https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", "dependencies": { - "arr-union": "^3.1.0", - "define-property": "^0.2.5", - "isobject": "^3.0.0", - "static-extend": "^0.1.1" + "agent-base": "6", + "debug": "4" }, "engines": { - "node": ">=0.10.0" + "node": ">= 6" } }, - "node_modules/class-utils/node_modules/define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", + "node_modules/human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", "dev": true, + "engines": { + "node": ">=10.17.0" + } + }, + "node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", "dependencies": { - "is-descriptor": "^0.1.0" + "safer-buffer": ">= 2.1.2 < 3.0.0" }, "engines": { "node": ">=0.10.0" } }, - "node_modules/class-utils/node_modules/is-descriptor": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.7.tgz", - "integrity": "sha512-C3grZTvObeN1xud4cRWl366OMXZTj0+HGyk4hvfpx4ZHt1Pb60ANSXqCK7pdOTeUQpRzECBSTphqvD7U+l22Eg==", + "node_modules/import-local": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", + "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==", "dev": true, "dependencies": { - "is-accessor-descriptor": "^1.0.1", - "is-data-descriptor": "^1.0.1" + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.0.0" + }, + "bin": { + "import-local-fixture": "fixtures/cli.js" }, "engines": { - "node": ">= 0.4" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dev": true, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" } }, - "node_modules/clean-stack": { + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "node_modules/interpret": { "version": "2.2.0", - "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", - "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-2.2.0.tgz", + "integrity": "sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw==", "dev": true, "engines": { - "node": ">=6" + "node": ">= 0.10" } }, - "node_modules/cli-cursor": { + "node_modules/ipaddr.js": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", - "integrity": "sha512-8lgKz8LmCRYZZQDpRyT2m5rKJ08TnU4tR9FFFW2rxpxR1FzWi4PQ/NfyODchAatHaUgnSPVcx/R5w6NuTBzFiw==", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.1.0.tgz", + "integrity": "sha512-LlbxQ7xKzfBusov6UMi4MFpEg0m+mAm9xyNGEduwXMEDuf4WfzB/RZwMVYEd7IKGvh4IUkEXYxtAVu9T3OelJQ==", "dev": true, - "dependencies": { - "restore-cursor": "^2.0.0" - }, "engines": { - "node": ">=4" + "node": ">= 10" } }, - "node_modules/cli-table3": { - "version": "0.6.4", - "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.4.tgz", - "integrity": "sha512-Lm3L0p+/npIQWNIiyF/nAn7T5dnOwR3xNTHXYEBFBFVPXzCVNZ5lqEC/1eo/EVfpDsQ1I+TX4ORPQgp+UI0CRw==", + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", "dev": true, "dependencies": { - "string-width": "^4.2.0" - }, - "engines": { - "node": "10.* || >= 12.*" + "binary-extensions": "^2.0.0" }, - "optionalDependencies": { - "@colors/colors": "1.5.0" - } - }, - "node_modules/cli-table3/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, "engines": { "node": ">=8" } }, - "node_modules/cli-table3/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "node_modules/is-core-module": { + "version": "2.13.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", + "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", "dev": true, - "engines": { - "node": ">=8" + "dependencies": { + "hasown": "^2.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/cli-table3/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "node_modules/is-docker": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", + "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", "dev": true, - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" + "bin": { + "is-docker": "cli.js" }, "engines": { "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/cli-table3/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", "dev": true, - "dependencies": { - "ansi-regex": "^5.0.1" - }, "engines": { - "node": ">=8" + "node": ">=0.10.0" } }, - "node_modules/cli-width": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.1.tgz", - "integrity": "sha512-GRMWDxpOB6Dgk2E5Uo+3eEBvtOOlimMmpbFiKuLFnQzYDavtLFY3K5ona41jgN/WdRZtG7utuVSVTL4HbZHGkw==", - "dev": true - }, - "node_modules/cliui": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", - "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", "dev": true, "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.1", - "wrap-ansi": "^7.0.0" + "is-extglob": "^2.1.1" }, "engines": { - "node": ">=12" + "node": ">=0.10.0" } }, - "node_modules/cliui/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "dev": true, "engines": { - "node": ">=8" + "node": ">=0.12.0" } }, - "node_modules/cliui/node_modules/is-fullwidth-code-point": { + "node_modules/is-plain-obj": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-3.0.0.tgz", + "integrity": "sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==", "dev": true, "engines": { - "node": ">=8" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/cliui/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "node_modules/is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", "dev": true, "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" + "isobject": "^3.0.1" }, "engines": { - "node": ">=8" + "node": ">=0.10.0" } }, - "node_modules/cliui/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "node_modules/is-potential-custom-element-name": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", + "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==" + }, + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", "dev": true, - "dependencies": { - "ansi-regex": "^5.0.1" - }, "engines": { "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/clone": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", - "integrity": "sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==", + "node_modules/is-wsl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", "dev": true, + "dependencies": { + "is-docker": "^2.0.0" + }, "engines": { - "node": ">=0.8" + "node": ">=8" } }, - "node_modules/clone-buffer": { + "node_modules/isarray": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/clone-buffer/-/clone-buffer-1.0.0.tgz", - "integrity": "sha512-KLLTJWrvwIP+OPfMn0x2PheDEP20RPUcGXj/ERegTgdmPEZylALQldygiqrPPu8P45uNuPs7ckmReLY6v/iA5g==", - "dev": true, - "engines": { - "node": ">= 0.10" - } + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "dev": true }, - "node_modules/clone-stats": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-1.0.0.tgz", - "integrity": "sha512-au6ydSpg6nsrigcZ4m8Bc9hxjeW+GJ8xh5G3BJCMt4WXe1H10UNaVOamqQTmrx1kjVuxAHIQSNU6hY4Nsn9/ag==", + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", "dev": true }, - "node_modules/cloneable-readable": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/cloneable-readable/-/cloneable-readable-1.1.3.tgz", - "integrity": "sha512-2EF8zTQOxYq70Y4XKtorQupqF0m49MBz2/yf5Bj+MHjvpG3Hy7sImifnqD6UA+TKYxeSV+u6qqQPawN5UvnpKQ==", + "node_modules/isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", "dev": true, - "dependencies": { - "inherits": "^2.0.1", - "process-nextick-args": "^2.0.0", - "readable-stream": "^2.3.5" + "engines": { + "node": ">=0.10.0" } }, - "node_modules/co": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", - "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", + "node_modules/jest-worker": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", + "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", "dev": true, + "dependencies": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, "engines": { - "iojs": ">= 1.0.0", - "node": ">= 0.12.0" + "node": ">= 10.13.0" } }, - "node_modules/collection-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", - "integrity": "sha512-lNkKvzEeMBBjUGHZ+q6z9pSJla0KWAQPvtzhEV9+iGyQYG+pBpl7xKDhxoNSOZH2hhv0v5k0y2yAM4o4SjoSkw==", - "dev": true, + "node_modules/jsdom": { + "version": "22.1.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-22.1.0.tgz", + "integrity": "sha512-/9AVW7xNbsBv6GfWho4TTNjEo9fe6Zhf9O7s0Fhhr3u+awPwAJMKwAMXnkk5vBxflqLW9hTHX/0cs+P3gW+cQw==", "dependencies": { - "map-visit": "^1.0.0", - "object-visit": "^1.0.0" + "abab": "^2.0.6", + "cssstyle": "^3.0.0", + "data-urls": "^4.0.0", + "decimal.js": "^10.4.3", + "domexception": "^4.0.0", + "form-data": "^4.0.0", + "html-encoding-sniffer": "^3.0.0", + "http-proxy-agent": "^5.0.0", + "https-proxy-agent": "^5.0.1", + "is-potential-custom-element-name": "^1.0.1", + "nwsapi": "^2.2.4", + "parse5": "^7.1.2", + "rrweb-cssom": "^0.6.0", + "saxes": "^6.0.0", + "symbol-tree": "^3.2.4", + "tough-cookie": "^4.1.2", + "w3c-xmlserializer": "^4.0.0", + "webidl-conversions": "^7.0.0", + "whatwg-encoding": "^2.0.0", + "whatwg-mimetype": "^3.0.0", + "whatwg-url": "^12.0.1", + "ws": "^8.13.0", + "xml-name-validator": "^4.0.0" + }, + "engines": { + "node": ">=16" + }, + "peerDependencies": { + "canvas": "^2.5.0" }, + "peerDependenciesMeta": { + "canvas": { + "optional": true + } + } + }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true, "engines": { "node": ">=0.10.0" } }, - "node_modules/collections": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/collections/-/collections-0.2.2.tgz", - "integrity": "sha512-XMGG5GPXUnjERaZzrBIfJo3iY3ck2ChSlL73iRk0UrT39Ei0HaKxhWL4NdrFjF72SCI/QGGa3U5CnN0BgbSgnw==", + "node_modules/launch-editor": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.6.1.tgz", + "integrity": "sha512-eB/uXmFVpY4zezmGp5XtU21kwo7GBbKB+EQ+UZeWtGb9yAM5xt/Evk+lYH3eRNAtId+ej4u7TYPFZ07w4s7rRw==", "dev": true, "dependencies": { - "weak-map": "1.0.0" + "picocolors": "^1.0.0", + "shell-quote": "^1.8.1" } }, - "node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "node_modules/loader-runner": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", + "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==", "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, "engines": { - "node": ">=7.0.0" + "node": ">=6.11.5" } }, - "node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", "dev": true, "dependencies": { - "delayed-stream": "~1.0.0" + "p-locate": "^4.1.0" }, "engines": { - "node": ">= 0.8" + "node": ">=8" } }, - "node_modules/commander": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.9.0.tgz", - "integrity": "sha512-bmkUukX8wAOjHdN26xj5c4ctEV22TQ7dQYhSmuckKhToXrkUn0iIaolHdIxYYqD55nhpSPA9zPQ1yP57GdXP2A==", + "node_modules/media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/memfs": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.5.3.tgz", + "integrity": "sha512-UERzLsxzllchadvbPs5aolHh65ISpKpM+ccLbOJ8/vvpBKmAWf+la7dXFy7Mr0ySHbdHrFv5kGFCUHHe6GFEmw==", "dev": true, "dependencies": { - "graceful-readlink": ">= 1.0.0" + "fs-monkey": "^1.0.4" }, "engines": { - "node": ">= 0.6.x" + "node": ">= 4.0.0" } }, - "node_modules/commondir": { + "node_modules/merge-descriptors": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==", "dev": true }, - "node_modules/compare-func": { + "node_modules/merge-stream": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/compare-func/-/compare-func-2.0.0.tgz", - "integrity": "sha512-zHig5N+tPWARooBnb0Zx1MFcdfpyJrfTJ3Y5L+IFvUm8rM74hHz66z0gw0x4tijh5CorKkKUCnW82R2vmpeCRA==", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true + }, + "node_modules/methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", "dev": true, - "dependencies": { - "array-ify": "^1.0.0", - "dot-prop": "^5.1.0" + "engines": { + "node": ">= 0.6" } }, - "node_modules/component-emitter": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.1.tgz", - "integrity": "sha512-T0+barUSQRTUQASh8bx02dl+DhF54GtIDY13Y3m9oWTklKbb3Wv974meRpeZ3lp1JpLVECWWNHC4vaG2XHXouQ==", + "node_modules/micromatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", "dev": true, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "dependencies": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" } }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true - }, - "node_modules/concat-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", - "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", - "dev": true, - "engines": [ - "node >= 0.8" - ], - "dependencies": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" - } - }, - "node_modules/config-chain": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.13.tgz", - "integrity": "sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==", - "dev": true, - "dependencies": { - "ini": "^1.3.4", - "proto-list": "~1.2.1" - } - }, - "node_modules/console-browserify": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz", - "integrity": "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==", - "dev": true - }, - "node_modules/constants-browserify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", - "integrity": "sha512-xFxOwqIzR/e1k1gLiWEophSCMqXcwVHIH7akf7b/vxcUeGunlj3hvZaaqxwHsTgn+IndtkQJgSztIDWeumWJDQ==", - "dev": true - }, - "node_modules/conventional-changelog-angular": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-6.0.0.tgz", - "integrity": "sha512-6qLgrBF4gueoC7AFVHu51nHL9pF9FRjXrH+ceVf7WmAfH3gs+gEYOkvxhjMPjZu57I4AGUGoNTY8V7Hrgf1uqg==", + "node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", "dev": true, - "dependencies": { - "compare-func": "^2.0.0" + "bin": { + "mime": "cli.js" }, "engines": { - "node": ">=14" + "node": ">=4" } }, - "node_modules/conventional-changelog-conventionalcommits": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/conventional-changelog-conventionalcommits/-/conventional-changelog-conventionalcommits-6.1.0.tgz", - "integrity": "sha512-3cS3GEtR78zTfMzk0AizXKKIdN4OvSh7ibNz6/DPbhWWQu7LqE/8+/GqSodV+sywUR2gpJAdP/1JFf4XtN7Zpw==", - "dev": true, - "dependencies": { - "compare-func": "^2.0.0" - }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", "engines": { - "node": ">=14" + "node": ">= 0.6" } }, - "node_modules/conventional-changelog-writer": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/conventional-changelog-writer/-/conventional-changelog-writer-5.0.1.tgz", - "integrity": "sha512-5WsuKUfxW7suLblAbFnxAcrvf6r+0b7GvNaWUwUIk0bXMnENP/PEieGKVUQrjPqwPT4o3EPAASBXiY6iHooLOQ==", - "dev": true, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", "dependencies": { - "conventional-commits-filter": "^2.0.7", - "dateformat": "^3.0.0", - "handlebars": "^4.7.7", - "json-stringify-safe": "^5.0.1", - "lodash": "^4.17.15", - "meow": "^8.0.0", - "semver": "^6.0.0", - "split": "^1.0.0", - "through2": "^4.0.0" - }, - "bin": { - "conventional-changelog-writer": "cli.js" + "mime-db": "1.52.0" }, "engines": { - "node": ">=10" + "node": ">= 0.6" } }, - "node_modules/conventional-changelog-writer/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", "dev": true, - "bin": { - "semver": "bin/semver.js" + "engines": { + "node": ">=6" } }, - "node_modules/conventional-commits-filter": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/conventional-commits-filter/-/conventional-commits-filter-2.0.7.tgz", - "integrity": "sha512-ASS9SamOP4TbCClsRHxIHXRfcGCnIoQqkvAzCSbZzTFLfcTqJVugB0agRgsEELsqaeWgsXv513eS116wnlSSPA==", + "node_modules/minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", + "dev": true + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, "dependencies": { - "lodash.ismatch": "^4.4.0", - "modify-values": "^1.0.0" + "brace-expansion": "^1.1.7" }, "engines": { - "node": ">=10" + "node": "*" } }, - "node_modules/conventional-commits-parser": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-4.0.0.tgz", - "integrity": "sha512-WRv5j1FsVM5FISJkoYMR6tPk07fkKT0UodruX4je86V4owk451yjXAKzKAPOs9l7y59E2viHUS9eQ+dfUA9NSg==", + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "node_modules/multicast-dns": { + "version": "7.2.5", + "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-7.2.5.tgz", + "integrity": "sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg==", "dev": true, "dependencies": { - "is-text-path": "^1.0.1", - "JSONStream": "^1.3.5", - "meow": "^8.1.2", - "split2": "^3.2.2" + "dns-packet": "^5.2.2", + "thunky": "^1.0.2" }, "bin": { - "conventional-commits-parser": "cli.js" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/copy-concurrently": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/copy-concurrently/-/copy-concurrently-1.0.5.tgz", - "integrity": "sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A==", - "dev": true, - "dependencies": { - "aproba": "^1.1.1", - "fs-write-stream-atomic": "^1.0.8", - "iferr": "^0.1.5", - "mkdirp": "^0.5.1", - "rimraf": "^2.5.4", - "run-queue": "^1.0.0" - } - }, - "node_modules/copy-descriptor": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", - "integrity": "sha512-XgZ0pFcakEUlbwQEVNg3+QAis1FyTL3Qel9FYy8pSkQqoG3PNoT0bOCQtOXcOkur21r2Eq2kI+IE+gsmAEVlYw==", - "dev": true, - "engines": { - "node": ">=0.10.0" + "multicast-dns": "cli.js" } }, - "node_modules/copy-webpack-plugin": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-4.6.0.tgz", - "integrity": "sha512-Y+SQCF+0NoWQryez2zXn5J5knmr9z/9qSQt7fbL78u83rxmigOy8X5+BFn8CFSuX+nKT8gpYwJX68ekqtQt6ZA==", + "node_modules/negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", "dev": true, - "dependencies": { - "cacache": "^10.0.4", - "find-cache-dir": "^1.0.0", - "globby": "^7.1.1", - "is-glob": "^4.0.0", - "loader-utils": "^1.1.0", - "minimatch": "^3.0.4", - "p-limit": "^1.0.0", - "serialize-javascript": "^1.4.0" - }, "engines": { - "node": ">= 4" + "node": ">= 0.6" } }, - "node_modules/core-util-is": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", - "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", + "node_modules/neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", "dev": true }, - "node_modules/cosmiconfig": { - "version": "8.3.6", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.3.6.tgz", - "integrity": "sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==", + "node_modules/node-forge": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz", + "integrity": "sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==", "dev": true, - "dependencies": { - "import-fresh": "^3.3.0", - "js-yaml": "^4.1.0", - "parse-json": "^5.2.0", - "path-type": "^4.0.0" - }, "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/d-fischer" - }, - "peerDependencies": { - "typescript": ">=4.9.5" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "node": ">= 6.13.0" } }, - "node_modules/cosmiconfig-typescript-loader": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/cosmiconfig-typescript-loader/-/cosmiconfig-typescript-loader-4.4.0.tgz", - "integrity": "sha512-BabizFdC3wBHhbI4kJh0VkQP9GkBfoHPydD0COMce1nJ1kJAB3F2TmJ/I7diULBKtmEWSwEbuN/KDtgnmUUVmw==", + "node_modules/node-releases": { + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", + "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==", + "dev": true + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", "dev": true, "engines": { - "node": ">=v14.21.3" - }, - "peerDependencies": { - "@types/node": "*", - "cosmiconfig": ">=7", - "ts-node": ">=10", - "typescript": ">=4" + "node": ">=0.10.0" } }, - "node_modules/create-ecdh": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.4.tgz", - "integrity": "sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A==", + "node_modules/npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", "dev": true, "dependencies": { - "bn.js": "^4.1.0", - "elliptic": "^6.5.3" + "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" } }, - "node_modules/create-ecdh/node_modules/bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true - }, - "node_modules/create-hash": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", - "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", - "dev": true, - "dependencies": { - "cipher-base": "^1.0.1", - "inherits": "^2.0.1", - "md5.js": "^1.3.4", - "ripemd160": "^2.0.1", - "sha.js": "^2.4.0" - } + "node_modules/nwsapi": { + "version": "2.2.7", + "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.7.tgz", + "integrity": "sha512-ub5E4+FBPKwAZx0UwIQOjYWGHTEq5sPqHQNRN8Z9e4A7u3Tj1weLJsL59yH9vmvqEtBHaOmT6cYQKIZOxp35FQ==" }, - "node_modules/create-hmac": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", - "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", + "node_modules/object-inspect": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", + "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", "dev": true, - "dependencies": { - "cipher-base": "^1.0.3", - "create-hash": "^1.1.0", - "inherits": "^2.0.1", - "ripemd160": "^2.0.0", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/create-require": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", - "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", + "node_modules/obuf": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", + "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==", "dev": true }, - "node_modules/cross-spawn": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", - "integrity": "sha512-pTgQJ5KC0d2hcY8eyL1IzlBPYjTkyH72XRZPnLyKus2mBfNjQs3klqbJU2VILqZryAZUt9JOb3h/mWMy23/f5A==", - "dev": true, - "dependencies": { - "lru-cache": "^4.0.1", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } - }, - "node_modules/crypto-browserify": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", - "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", + "node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", "dev": true, "dependencies": { - "browserify-cipher": "^1.0.0", - "browserify-sign": "^4.0.0", - "create-ecdh": "^4.0.0", - "create-hash": "^1.1.0", - "create-hmac": "^1.1.0", - "diffie-hellman": "^5.0.0", - "inherits": "^2.0.1", - "pbkdf2": "^3.0.3", - "public-encrypt": "^4.0.0", - "randombytes": "^2.0.0", - "randomfill": "^1.0.3" + "ee-first": "1.1.1" }, "engines": { - "node": "*" - } - }, - "node_modules/crypto-random-string": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz", - "integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==", - "dev": true, - "engines": { - "node": ">=8" + "node": ">= 0.8" } }, - "node_modules/cyclist": { + "node_modules/on-headers": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/cyclist/-/cyclist-1.0.2.tgz", - "integrity": "sha512-0sVXIohTfLqVIW3kb/0n6IiWF3Ifj5nm2XaSrLq2DI6fKIGa2fYAZdk917rUneaeLVpYfFcyXE2ft0fe3remsA==", - "dev": true - }, - "node_modules/dargs": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/dargs/-/dargs-7.0.0.tgz", - "integrity": "sha512-2iy1EkLdlBzQGvbweYRFxmFath8+K7+AKB0TlhHWkNuH+TmovaMH/Wp7V7R4u7f4SnX3OgLsU9t1NI9ioDnUpg==", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", + "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", "dev": true, "engines": { - "node": ">=8" + "node": ">= 0.8" } }, - "node_modules/dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==", + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", "dev": true, "dependencies": { - "assert-plus": "^1.0.0" - }, - "engines": { - "node": ">=0.10" + "wrappy": "1" } }, - "node_modules/data-view-buffer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.1.tgz", - "integrity": "sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==", + "node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", "dev": true, "dependencies": { - "call-bind": "^1.0.6", - "es-errors": "^1.3.0", - "is-data-view": "^1.0.1" + "mimic-fn": "^2.1.0" }, "engines": { - "node": ">= 0.4" + "node": ">=6" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/data-view-byte-length": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.1.tgz", - "integrity": "sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==", + "node_modules/open": { + "version": "8.4.2", + "resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz", + "integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==", "dev": true, "dependencies": { - "call-bind": "^1.0.7", - "es-errors": "^1.3.0", - "is-data-view": "^1.0.1" + "define-lazy-prop": "^2.0.0", + "is-docker": "^2.1.1", + "is-wsl": "^2.2.0" }, "engines": { - "node": ">= 0.4" + "node": ">=12" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/data-view-byte-offset": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.0.tgz", - "integrity": "sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==", + "node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", "dev": true, "dependencies": { - "call-bind": "^1.0.6", - "es-errors": "^1.3.0", - "is-data-view": "^1.0.1" + "p-try": "^2.0.0" }, "engines": { - "node": ">= 0.4" + "node": ">=6" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/dateformat": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-3.0.3.tgz", - "integrity": "sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q==", + "node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", "dev": true, + "dependencies": { + "p-limit": "^2.2.0" + }, "engines": { - "node": "*" + "node": ">=8" } }, - "node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "node_modules/p-retry": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-4.6.2.tgz", + "integrity": "sha512-312Id396EbJdvRONlngUx0NydfrIQ5lsYu0znKVUzVvArzEIt08V1qhtyESbGVd1FGX7UKtiFp5uwKZdM8wIuQ==", "dev": true, "dependencies": { - "ms": "^2.1.1" + "@types/retry": "0.12.0", + "retry": "^0.13.1" + }, + "engines": { + "node": ">=8" } }, - "node_modules/decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", + "node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", "dev": true, "engines": { - "node": ">=0.10.0" + "node": ">=6" } }, - "node_modules/decamelize-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.1.tgz", - "integrity": "sha512-WiPxgEirIV0/eIOMcnFBA3/IJZAZqKnwAwWyvvdi4lsr1WCN22nhdf/3db3DoZcUjTV2SqfzIwNyp6y2xs3nmg==", - "dev": true, + "node_modules/parse5": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz", + "integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==", "dependencies": { - "decamelize": "^1.1.0", - "map-obj": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" + "entities": "^4.4.0" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/inikulin/parse5?sponsor=1" } }, - "node_modules/decamelize-keys/node_modules/map-obj": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", - "integrity": "sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==", + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", "dev": true, "engines": { - "node": ">=0.10.0" + "node": ">= 0.8" } }, - "node_modules/decode-uri-component": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.2.tgz", - "integrity": "sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==", + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "dev": true, "engines": { - "node": ">=0.10" + "node": ">=8" } }, - "node_modules/deep-extend": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", - "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", "dev": true, "engines": { - "node": ">=4.0.0" + "node": ">=0.10.0" } }, - "node_modules/deep-is": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "dev": true - }, - "node_modules/define-data-property": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", - "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "dev": true, - "dependencies": { - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "gopd": "^1.0.1" - }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=8" } }, - "node_modules/define-properties": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", - "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "node_modules/path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==", + "dev": true + }, + "node_modules/picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "dev": true + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "dev": true, - "dependencies": { - "define-data-property": "^1.0.1", - "has-property-descriptors": "^1.0.0", - "object-keys": "^1.1.1" - }, "engines": { - "node": ">= 0.4" + "node": ">=8.6" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/define-property": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", - "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", + "node_modules/pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", "dev": true, "dependencies": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" + "find-up": "^4.0.0" }, "engines": { - "node": ">=0.10.0" + "node": ">=8" } }, - "node_modules/del": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/del/-/del-6.1.1.tgz", - "integrity": "sha512-ua8BhapfP0JUJKC/zV9yHHDW/rDoDxP4Zhn3AkA6/xT6gY7jYXJiaeyBZznYVujhZZET+UgcbZiQ7sN3WqcImg==", + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "dev": true + }, + "node_modules/proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", "dev": true, "dependencies": { - "globby": "^11.0.1", - "graceful-fs": "^4.2.4", - "is-glob": "^4.0.1", - "is-path-cwd": "^2.2.0", - "is-path-inside": "^3.0.2", - "p-map": "^4.0.0", - "rimraf": "^3.0.2", - "slash": "^3.0.0" + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" }, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">= 0.10" } }, - "node_modules/del/node_modules/array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "node_modules/proxy-addr/node_modules/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", "dev": true, "engines": { - "node": ">=8" + "node": ">= 0.10" } }, - "node_modules/del/node_modules/dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", - "dev": true, - "dependencies": { - "path-type": "^4.0.0" - }, + "node_modules/psl": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", + "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==" + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", "engines": { - "node": ">=8" + "node": ">=6" } }, - "node_modules/del/node_modules/globby": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", - "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "node_modules/qs": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", + "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", "dev": true, "dependencies": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.2.9", - "ignore": "^5.2.0", - "merge2": "^1.4.1", - "slash": "^3.0.0" + "side-channel": "^1.0.4" }, "engines": { - "node": ">=10" + "node": ">=0.6" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/del/node_modules/ignore": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", - "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", + "node_modules/querystringify": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", + "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==" + }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", "dev": true, - "engines": { - "node": ">= 4" + "dependencies": { + "safe-buffer": "^5.1.0" } }, - "node_modules/del/node_modules/p-map": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", - "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", "dev": true, - "dependencies": { - "aggregate-error": "^3.0.0" - }, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">= 0.6" } }, - "node_modules/del/node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "node_modules/raw-body": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", + "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", "dev": true, "dependencies": { - "glob": "^7.1.3" + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "engines": { + "node": ">= 0.8" } }, - "node_modules/del/node_modules/slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "node_modules/raw-body/node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", "dev": true, "engines": { - "node": ">=8" + "node": ">= 0.8" } }, - "node_modules/delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "node_modules/raw-body/node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", "dev": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, "engines": { - "node": ">=0.4.0" + "node": ">=0.10.0" } }, - "node_modules/deprecation": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz", - "integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==", - "dev": true - }, - "node_modules/des.js": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.1.0.tgz", - "integrity": "sha512-r17GxjhUCjSRy8aiJpr8/UadFIzMzJGexI3Nmz4ADi9LYSFx4gTBp80+NaX/YsXWWLhpZ7v/v/ubEc/bCNfKwg==", + "node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", "dev": true, "dependencies": { - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" } }, - "node_modules/detect-file": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz", - "integrity": "sha512-DtCOLG98P007x7wiiOmfI0fi3eIKyWiLTGJ2MDnVi/E04lWGbf+JzrRHMm0rgIIZJGtHpKpbVgLWHrv8xXpc3Q==", + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", "dev": true, + "dependencies": { + "picomatch": "^2.2.1" + }, "engines": { - "node": ">=0.10.0" + "node": ">=8.10.0" } }, - "node_modules/diff": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.3.1.tgz", - "integrity": "sha512-MKPHZDMB0o6yHyDryUOScqZibp914ksXwAMYMTHj6KO8UeKsRYNJD3oNCKjTqZon+V488P7N/HzXF8t7ZR95ww==", + "node_modules/rechoir": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.7.1.tgz", + "integrity": "sha512-/njmZ8s1wVeR6pjTZ+0nCnv8SpZNRMT2D1RLOJQESlYFDBvwpTA4KWJpZ+sBJ4+vhjILRcK7JIFdGCdxEAAitg==", "dev": true, + "dependencies": { + "resolve": "^1.9.0" + }, "engines": { - "node": ">=0.3.1" + "node": ">= 0.10" } }, - "node_modules/diffie-hellman": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", - "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", "dev": true, - "dependencies": { - "bn.js": "^4.1.0", - "miller-rabin": "^4.0.0", - "randombytes": "^2.0.0" + "engines": { + "node": ">=0.10.0" } }, - "node_modules/diffie-hellman/node_modules/bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true + "node_modules/requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==" }, - "node_modules/dir-glob": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-2.2.2.tgz", - "integrity": "sha512-f9LBi5QWzIW3I6e//uxZoLBlUt9kcp66qo0sSCxL6YZKc75R1c4MFCoe/LaZiBGmgujvQdxc5Bn3QhfyvK5Hsw==", + "node_modules/resolve": { + "version": "1.22.8", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", + "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", "dev": true, "dependencies": { - "path-type": "^3.0.0" + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" }, - "engines": { - "node": ">=4" + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/dir-glob/node_modules/path-type": { + "node_modules/resolve-cwd": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", - "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", + "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", "dev": true, "dependencies": { - "pify": "^3.0.0" + "resolve-from": "^5.0.0" }, "engines": { - "node": ">=4" + "node": ">=8" } }, - "node_modules/doctrine": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", "dev": true, - "dependencies": { - "esutils": "^2.0.2" - }, "engines": { - "node": ">=0.10.0" + "node": ">=8" } }, - "node_modules/domain-browser": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz", - "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==", + "node_modules/retry": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", + "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", "dev": true, "engines": { - "node": ">=0.4", - "npm": ">=1.2" + "node": ">= 4" } }, - "node_modules/dot-prop": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", - "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==", + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", "dev": true, "dependencies": { - "is-obj": "^2.0.0" + "glob": "^7.1.3" }, - "engines": { - "node": ">=8" + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/duplexer": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", - "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==", - "dev": true + "node_modules/rrweb-cssom": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.6.0.tgz", + "integrity": "sha512-APM0Gt1KoXBz0iIkkdB/kfvGOwC4UuJFeG/c+yV7wSc7q96cG/kJ0HiYCnzivD9SB53cLV1MlHFNfOuPaadYSw==" }, - "node_modules/duplexer2": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz", - "integrity": "sha512-asLFVfWWtJ90ZyOUHMqk7/S2w2guQKxUI2itj3d92ADHhxUSbCMGi1f1cBcJ7xM1To+pE/Khbwo1yuNbMEPKeA==", + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", "dev": true, - "dependencies": { - "readable-stream": "^2.0.2" - } + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] }, - "node_modules/duplexify": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz", - "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==", - "dev": true, - "dependencies": { - "end-of-stream": "^1.0.0", - "inherits": "^2.0.1", - "readable-stream": "^2.0.0", - "stream-shift": "^1.0.0" - } + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, - "node_modules/ecc-jsbn": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==", - "dev": true, + "node_modules/saxes": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz", + "integrity": "sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==", "dependencies": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" + "xmlchars": "^2.2.0" + }, + "engines": { + "node": ">=v12.22.7" } }, - "node_modules/elliptic": { - "version": "6.5.5", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.5.tgz", - "integrity": "sha512-7EjbcmUm17NQFu4Pmgmq2olYMj8nwMnpcddByChSUjArp8F5DQWcIcpriwO4ZToLNAJig0yiyjswfyGNje/ixw==", + "node_modules/schema-utils": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", + "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", "dev": true, "dependencies": { - "bn.js": "^4.11.9", - "brorand": "^1.1.0", - "hash.js": "^1.0.0", - "hmac-drbg": "^1.0.1", - "inherits": "^2.0.4", - "minimalistic-assert": "^1.0.1", - "minimalistic-crypto-utils": "^1.0.1" + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" } }, - "node_modules/elliptic/node_modules/bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true - }, - "node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "node_modules/select-hose": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", + "integrity": "sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg==", "dev": true }, - "node_modules/emojis-list": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", - "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", + "node_modules/selfsigned": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-2.4.1.tgz", + "integrity": "sha512-th5B4L2U+eGLq1TVh7zNRGBapioSORUeymIydxgFpwww9d2qyKvtuPU2jJuHvYAwwqi2Y596QBL3eEqcPEYL8Q==", + "dev": true, + "dependencies": { + "@types/node-forge": "^1.3.0", + "node-forge": "^1" + }, "engines": { - "node": ">= 4" + "node": ">=10" } }, - "node_modules/end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "node_modules/send": { + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", + "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", "dev": true, "dependencies": { - "once": "^1.4.0" - } - }, - "node_modules/enhanced-resolve": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.5.0.tgz", - "integrity": "sha512-Nv9m36S/vxpsI+Hc4/ZGRs0n9mXqSWGGq49zxb/cJfPAQMbUtttJAlNPS4AQzaBdw/pKskw5bMbekT/Y7W/Wlg==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.1.2", - "memory-fs": "^0.5.0", - "tapable": "^1.0.0" + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "2.4.1", + "range-parser": "~1.2.1", + "statuses": "2.0.1" }, "engines": { - "node": ">=6.9.0" + "node": ">= 0.8.0" } }, - "node_modules/enhanced-resolve/node_modules/memory-fs": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.5.0.tgz", - "integrity": "sha512-jA0rdU5KoQMC0e6ppoNRtpp6vjFq6+NY7r8hywnC7V+1Xj/MtHwGIbB1QaK/dunyjWteJzmkpd7ooeWg10T7GA==", + "node_modules/send/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, "dependencies": { - "errno": "^0.1.3", - "readable-stream": "^2.0.1" - }, - "engines": { - "node": ">=4.3.0 <5.0.0 || >=5.10" + "ms": "2.0.0" } }, - "node_modules/env-ci": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/env-ci/-/env-ci-5.5.0.tgz", - "integrity": "sha512-o0JdWIbOLP+WJKIUt36hz1ImQQFuN92nhsfTkHHap+J8CiI8WgGpH/a9jEGHh4/TU5BUUGjlnKXNoDb57+ne+A==", + "node_modules/send/node_modules/debug/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + }, + "node_modules/send/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + }, + "node_modules/serialize-javascript": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.1.tgz", + "integrity": "sha512-owoXEFjWRllis8/M1Q+Cw5k8ZH40e3zhp/ovX+Xr/vi1qj6QesbyXXViFbpNvWvPNAD62SutwEXavefrLJWj7w==", "dev": true, "dependencies": { - "execa": "^5.0.0", - "fromentries": "^1.3.2", - "java-properties": "^1.0.0" - }, - "engines": { - "node": ">=10.17" + "randombytes": "^2.1.0" } }, - "node_modules/errno": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.8.tgz", - "integrity": "sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==", + "node_modules/serve-index": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz", + "integrity": "sha512-pXHfKNP4qujrtteMrSBb0rc8HJ9Ms/GrXwcUtUtD5s4ewDJI8bT3Cz2zTVRMKtri49pLx2e0Ya8ziP5Ya2pZZw==", "dev": true, "dependencies": { - "prr": "~1.0.1" + "accepts": "~1.3.4", + "batch": "0.6.1", + "debug": "2.6.9", + "escape-html": "~1.0.3", + "http-errors": "~1.6.2", + "mime-types": "~2.1.17", + "parseurl": "~1.3.2" }, - "bin": { - "errno": "cli.js" + "engines": { + "node": ">= 0.8.0" } }, - "node_modules/error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "node_modules/serve-index/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, "dependencies": { - "is-arrayish": "^0.2.1" + "ms": "2.0.0" } }, - "node_modules/es-abstract": { - "version": "1.23.3", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.3.tgz", - "integrity": "sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==", + "node_modules/serve-index/node_modules/depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==", "dev": true, - "dependencies": { - "array-buffer-byte-length": "^1.0.1", - "arraybuffer.prototype.slice": "^1.0.3", - "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.7", - "data-view-buffer": "^1.0.1", - "data-view-byte-length": "^1.0.1", - "data-view-byte-offset": "^1.0.0", - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.0.0", - "es-set-tostringtag": "^2.0.3", - "es-to-primitive": "^1.2.1", - "function.prototype.name": "^1.1.6", - "get-intrinsic": "^1.2.4", - "get-symbol-description": "^1.0.2", - "globalthis": "^1.0.3", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.2", - "has-proto": "^1.0.3", - "has-symbols": "^1.0.3", - "hasown": "^2.0.2", - "internal-slot": "^1.0.7", - "is-array-buffer": "^3.0.4", - "is-callable": "^1.2.7", - "is-data-view": "^1.0.1", - "is-negative-zero": "^2.0.3", - "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.3", - "is-string": "^1.0.7", - "is-typed-array": "^1.1.13", - "is-weakref": "^1.0.2", - "object-inspect": "^1.13.1", - "object-keys": "^1.1.1", - "object.assign": "^4.1.5", - "regexp.prototype.flags": "^1.5.2", - "safe-array-concat": "^1.1.2", - "safe-regex-test": "^1.0.3", - "string.prototype.trim": "^1.2.9", - "string.prototype.trimend": "^1.0.8", - "string.prototype.trimstart": "^1.0.8", - "typed-array-buffer": "^1.0.2", - "typed-array-byte-length": "^1.0.1", - "typed-array-byte-offset": "^1.0.2", - "typed-array-length": "^1.0.6", - "unbox-primitive": "^1.0.2", - "which-typed-array": "^1.1.15" - }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">= 0.6" } }, - "node_modules/es-define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", - "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", + "node_modules/serve-index/node_modules/http-errors": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", + "integrity": "sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A==", "dev": true, "dependencies": { - "get-intrinsic": "^1.2.4" + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.0", + "statuses": ">= 1.4.0 < 2" }, "engines": { - "node": ">= 0.4" + "node": ">= 0.6" } }, - "node_modules/es-errors": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", - "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "node_modules/serve-index/node_modules/inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==", + "dev": true + }, + "node_modules/serve-index/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + }, + "node_modules/serve-index/node_modules/setprototypeof": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", + "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==", + "dev": true + }, + "node_modules/serve-index/node_modules/statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==", "dev": true, "engines": { - "node": ">= 0.4" + "node": ">= 0.6" } }, - "node_modules/es-object-atoms": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.0.0.tgz", - "integrity": "sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==", + "node_modules/serve-static": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", + "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", "dev": true, "dependencies": { - "es-errors": "^1.3.0" + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.18.0" }, "engines": { - "node": ">= 0.4" + "node": ">= 0.8.0" } }, - "node_modules/es-set-tostringtag": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.3.tgz", - "integrity": "sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==", + "node_modules/set-function-length": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.1.1.tgz", + "integrity": "sha512-VoaqjbBJKiWtg4yRcKBQ7g7wnGnLV3M8oLvVWwOk2PdYY6PEFegR1vezXR0tw6fZGF9csVakIRjrJiy2veSBFQ==", "dev": true, "dependencies": { - "get-intrinsic": "^1.2.4", - "has-tostringtag": "^1.0.2", - "hasown": "^2.0.1" + "define-data-property": "^1.1.1", + "get-intrinsic": "^1.2.1", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.0" }, "engines": { "node": ">= 0.4" } }, - "node_modules/es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", + "dev": true + }, + "node_modules/shallow-clone": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", + "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", "dev": true, "dependencies": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" + "kind-of": "^6.0.2" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=8" } }, - "node_modules/escalade": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", - "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", "dev": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, "engines": { - "node": ">=6" + "node": ">=8" } }, - "node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "dev": true, "engines": { - "node": ">=0.8.0" + "node": ">=8" } }, - "node_modules/eslint": { - "version": "4.19.1", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-4.19.1.tgz", - "integrity": "sha512-bT3/1x1EbZB7phzYu7vCr1v3ONuzDtX8WjuM9c0iYxe+cq+pwcKEoQjl7zd3RpC6YOLgnSy3cTN58M2jcoPDIQ==", - "dev": true, - "dependencies": { - "ajv": "^5.3.0", - "babel-code-frame": "^6.22.0", - "chalk": "^2.1.0", - "concat-stream": "^1.6.0", - "cross-spawn": "^5.1.0", - "debug": "^3.1.0", - "doctrine": "^2.1.0", - "eslint-scope": "^3.7.1", - "eslint-visitor-keys": "^1.0.0", - "espree": "^3.5.4", - "esquery": "^1.0.0", - "esutils": "^2.0.2", - "file-entry-cache": "^2.0.0", - "functional-red-black-tree": "^1.0.1", - "glob": "^7.1.2", - "globals": "^11.0.1", - "ignore": "^3.3.3", - "imurmurhash": "^0.1.4", - "inquirer": "^3.0.6", - "is-resolvable": "^1.0.0", - "js-yaml": "^3.9.1", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.3.0", - "lodash": "^4.17.4", - "minimatch": "^3.0.2", - "mkdirp": "^0.5.1", - "natural-compare": "^1.4.0", - "optionator": "^0.8.2", - "path-is-inside": "^1.0.2", - "pluralize": "^7.0.0", - "progress": "^2.0.0", - "regexpp": "^1.0.1", - "require-uncached": "^1.0.3", - "semver": "^5.3.0", - "strip-ansi": "^4.0.0", - "strip-json-comments": "~2.0.1", - "table": "4.0.2", - "text-table": "~0.2.0" - }, - "bin": { - "eslint": "bin/eslint.js" - }, - "engines": { - "node": ">=4" + "node_modules/shell-quote": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.1.tgz", + "integrity": "sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/eslint-scope": { - "version": "3.7.3", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-3.7.3.tgz", - "integrity": "sha512-W+B0SvF4gamyCTmUc+uITPY0989iXVfKvhwtmJocTaYoc/3khEHmEmvfY/Gn9HA9VV75jrQECsHizkNw1b68FA==", + "node_modules/side-channel": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", "dev": true, "dependencies": { - "esrecurse": "^4.1.0", - "estraverse": "^4.1.1" + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" }, - "engines": { - "node": ">=4.0.0" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true + }, + "node_modules/sockjs": { + "version": "0.3.24", + "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.24.tgz", + "integrity": "sha512-GJgLTZ7vYb/JtPSSZ10hsOYIvEYsjbNU+zPdIHcUaWVNUEPivzxku31865sSSud0Da0W4lEeOPlmw93zLQchuQ==", + "dev": true, + "dependencies": { + "faye-websocket": "^0.11.3", + "uuid": "^8.3.2", + "websocket-driver": "^0.7.4" + } + }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true, "engines": { - "node": ">=4" + "node": ">=0.10.0" } }, - "node_modules/eslint/node_modules/ajv": { - "version": "5.5.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz", - "integrity": "sha512-Ajr4IcMXq/2QmMkEmSvxqfLN5zGmJ92gHXAeOXq1OekoH2rfDNsgdDoL2f7QaRCy7G/E6TpxBVdRuNraMztGHw==", + "node_modules/source-map-js": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", + "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", "dev": true, - "dependencies": { - "co": "^4.6.0", - "fast-deep-equal": "^1.0.0", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.3.0" + "engines": { + "node": ">=0.10.0" } }, - "node_modules/eslint/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "node_modules/source-map-loader": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/source-map-loader/-/source-map-loader-4.0.1.tgz", + "integrity": "sha512-oqXpzDIByKONVY8g1NUPOTQhe0UTU5bWUl32GSkqK2LjJj0HmwTMVKxcUip0RgAYhY1mqgOxjbQM48a0mmeNfA==", "dev": true, "dependencies": { - "color-convert": "^1.9.0" + "abab": "^2.0.6", + "iconv-lite": "^0.6.3", + "source-map-js": "^1.0.2" }, "engines": { - "node": ">=4" + "node": ">= 14.15.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.72.1" } }, - "node_modules/eslint/node_modules/argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", "dev": true, "dependencies": { - "sprintf-js": "~1.0.2" + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" } }, - "node_modules/eslint/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "node_modules/spdy": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.2.tgz", + "integrity": "sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA==", "dev": true, "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" + "debug": "^4.1.0", + "handle-thing": "^2.0.0", + "http-deceiver": "^1.2.7", + "select-hose": "^2.0.0", + "spdy-transport": "^3.0.0" }, "engines": { - "node": ">=4" + "node": ">=6.0.0" } }, - "node_modules/eslint/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "node_modules/spdy-transport": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/spdy-transport/-/spdy-transport-3.0.0.tgz", + "integrity": "sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==", "dev": true, "dependencies": { - "color-name": "1.1.3" + "debug": "^4.1.0", + "detect-node": "^2.0.4", + "hpack.js": "^2.1.6", + "obuf": "^1.1.2", + "readable-stream": "^3.0.6", + "wbuf": "^1.7.3" } }, - "node_modules/eslint/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "node_modules/eslint/node_modules/fast-deep-equal": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz", - "integrity": "sha512-fueX787WZKCV0Is4/T2cyAdM4+x1S3MXXOAhavE1ys/W42SHAPacLTQhucja22QBYrfGw50M2sRiXPtTGv9Ymw==", - "dev": true - }, - "node_modules/eslint/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", "dev": true, "engines": { - "node": ">=4" + "node": ">= 0.8" } }, - "node_modules/eslint/node_modules/js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", "dev": true, "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" + "safe-buffer": "~5.2.0" } }, - "node_modules/eslint/node_modules/json-schema-traverse": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz", - "integrity": "sha512-4JD/Ivzg7PoW8NzdrBSr3UFwC9mHgvI7Z6z3QGBsSHgKaRTUDmyZAAKJo2UbG1kUVfS9WS8bi36N49U1xw43DA==", - "dev": true - }, - "node_modules/eslint/node_modules/semver": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "node_modules/strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", "dev": true, - "bin": { - "semver": "bin/semver" + "engines": { + "node": ">=6" } }, - "node_modules/eslint/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", "dev": true, "dependencies": { - "has-flag": "^3.0.0" + "has-flag": "^4.0.0" }, "engines": { - "node": ">=4" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" } }, - "node_modules/espree": { - "version": "3.5.4", - "resolved": "https://registry.npmjs.org/espree/-/espree-3.5.4.tgz", - "integrity": "sha512-yAcIQxtmMiB/jL32dzEp2enBeidsB7xWPLNiw3IIkpVds1P+h7qF9YwJq1yUNzp2OKXgAprs4F61ih66UsoD1A==", + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", "dev": true, - "dependencies": { - "acorn": "^5.5.0", - "acorn-jsx": "^3.0.0" - }, "engines": { - "node": ">=0.10.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "node_modules/symbol-tree": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", + "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==" + }, + "node_modules/tapable": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", + "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", "dev": true, - "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" - }, "engines": { - "node": ">=4" + "node": ">=6" } }, - "node_modules/esquery": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", - "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", + "node_modules/terser": { + "version": "5.26.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.26.0.tgz", + "integrity": "sha512-dytTGoE2oHgbNV9nTzgBEPaqAWvcJNl66VZ0BkJqlvp71IjO8CxdBx/ykCNb47cLnCmCvRZ6ZR0tLkqvZCdVBQ==", "dev": true, "dependencies": { - "estraverse": "^5.1.0" + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.8.2", + "commander": "^2.20.0", + "source-map-support": "~0.5.20" + }, + "bin": { + "terser": "bin/terser" }, "engines": { - "node": ">=0.10" + "node": ">=10" } }, - "node_modules/esquery/node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "node_modules/terser-webpack-plugin": { + "version": "5.3.9", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.9.tgz", + "integrity": "sha512-ZuXsqE07EcggTWQjXUj+Aot/OMcD0bMKGgF63f7UxYcu5/AJF53aIpK1YoP5xR9l6s/Hy2b+t1AM0bLNPRuhwA==", "dev": true, + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.17", + "jest-worker": "^27.4.5", + "schema-utils": "^3.1.1", + "serialize-javascript": "^6.0.1", + "terser": "^5.16.8" + }, "engines": { - "node": ">=4.0" + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.1.0" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "uglify-js": { + "optional": true + } } }, - "node_modules/esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "node_modules/thunky": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz", + "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==", + "dev": true + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", "dev": true, "dependencies": { - "estraverse": "^5.2.0" + "is-number": "^7.0.0" }, "engines": { - "node": ">=4.0" + "node": ">=8.0" } }, - "node_modules/esrecurse/node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", "dev": true, "engines": { - "node": ">=4.0" + "node": ">=0.6" } }, - "node_modules/estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true, + "node_modules/tough-cookie": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.3.tgz", + "integrity": "sha512-aX/y5pVRkfRnfmuX+OdbSdXvPe6ieKX/G2s7e98f4poJHnqH3281gDPm/metm6E/WRamfx7WC4HUqkWHfQHprw==", + "dependencies": { + "psl": "^1.1.33", + "punycode": "^2.1.1", + "universalify": "^0.2.0", + "url-parse": "^1.5.3" + }, "engines": { - "node": ">=4.0" + "node": ">=6" } }, - "node_modules/esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true, + "node_modules/tr46": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-4.1.1.tgz", + "integrity": "sha512-2lv/66T7e5yNyhAAC4NaKe5nVavzuGJQVVtRYLyQ2OI8tsJ61PMLlelehb0wi2Hx6+hT/OJUWZcw8MjlSRnxvw==", + "dependencies": { + "punycode": "^2.3.0" + }, "engines": { - "node": ">=0.10.0" + "node": ">=14" } }, - "node_modules/event-stream": { - "version": "3.3.5", - "resolved": "https://registry.npmjs.org/event-stream/-/event-stream-3.3.5.tgz", - "integrity": "sha512-vyibDcu5JL20Me1fP734QBH/kenBGLZap2n0+XXM7mvuUPzJ20Ydqj1aKcIeMdri1p+PU+4yAKugjN8KCVst+g==", + "node_modules/type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", "dev": true, "dependencies": { - "duplexer": "^0.1.1", - "from": "^0.1.7", - "map-stream": "0.0.7", - "pause-stream": "^0.0.11", - "split": "^1.0.1", - "stream-combiner": "^0.2.2", - "through": "^2.3.8" + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" } }, - "node_modules/events": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", - "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", - "dev": true, + "node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "dev": true + }, + "node_modules/universalify": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", + "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==", "engines": { - "node": ">=0.8.x" + "node": ">= 4.0.0" } }, - "node_modules/evp_bytestokey": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", - "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", "dev": true, - "dependencies": { - "md5.js": "^1.3.4", - "safe-buffer": "^5.1.1" + "engines": { + "node": ">= 0.8" } }, - "node_modules/execa": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", - "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "node_modules/update-browserslist-db": { + "version": "1.0.13", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", + "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==", "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], "dependencies": { - "cross-spawn": "^7.0.3", - "get-stream": "^6.0.0", - "human-signals": "^2.1.0", - "is-stream": "^2.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.1", - "onetime": "^5.1.2", - "signal-exit": "^3.0.3", - "strip-final-newline": "^2.0.0" + "escalade": "^3.1.1", + "picocolors": "^1.0.0" }, - "engines": { - "node": ">=10" + "bin": { + "update-browserslist-db": "cli.js" }, - "funding": { - "url": "https://github.com/sindresorhus/execa?sponsor=1" + "peerDependencies": { + "browserslist": ">= 4.21.0" } }, - "node_modules/execa/node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", "dev": true, "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" + "punycode": "^2.1.0" } }, - "node_modules/execa/node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, + "node_modules/url-parse": { + "version": "1.5.10", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", + "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" + "querystringify": "^2.1.1", + "requires-port": "^1.0.0" } }, - "node_modules/execa/node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "dev": true + }, + "node_modules/utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", "dev": true, "engines": { - "node": ">=8" + "node": ">= 0.4.0" } }, - "node_modules/execa/node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", "dev": true, - "dependencies": { - "isexe": "^2.0.0" - }, "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" + "uuid": "dist/bin/uuid" } }, - "node_modules/expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha512-w/ozOKR9Obk3qoWeY/WDi6MFta9AoMR+zud60mdnbniMcBxRuFJyDt2LdX/14A1UABeqk+Uk+LDfUpvoGKppZA==", + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", "dev": true, - "dependencies": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/expand-brackets/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "dependencies": { - "ms": "2.0.0" + "node": ">= 0.8" } }, - "node_modules/expand-brackets/node_modules/define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", - "dev": true, + "node_modules/w3c-xmlserializer": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-4.0.0.tgz", + "integrity": "sha512-d+BFHzbiCx6zGfz0HyQ6Rg69w9k19nviJspaj4yNscGjrHu94sVP+aRm75yEbCh+r2/yR+7q6hux9LVtbuTGBw==", "dependencies": { - "is-descriptor": "^0.1.0" + "xml-name-validator": "^4.0.0" }, "engines": { - "node": ">=0.10.0" + "node": ">=14" } }, - "node_modules/expand-brackets/node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", + "node_modules/watchpack": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz", + "integrity": "sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg==", "dev": true, "dependencies": { - "is-extendable": "^0.1.0" + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.1.2" }, "engines": { - "node": ">=0.10.0" + "node": ">=10.13.0" } }, - "node_modules/expand-brackets/node_modules/is-descriptor": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.7.tgz", - "integrity": "sha512-C3grZTvObeN1xud4cRWl366OMXZTj0+HGyk4hvfpx4ZHt1Pb60ANSXqCK7pdOTeUQpRzECBSTphqvD7U+l22Eg==", + "node_modules/wbuf": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/wbuf/-/wbuf-1.7.3.tgz", + "integrity": "sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==", "dev": true, "dependencies": { - "is-accessor-descriptor": "^1.0.1", - "is-data-descriptor": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" + "minimalistic-assert": "^1.0.0" } }, - "node_modules/expand-brackets/node_modules/is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", - "dev": true, + "node_modules/webidl-conversions": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", + "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", "engines": { - "node": ">=0.10.0" + "node": ">=12" } }, - "node_modules/expand-brackets/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true - }, - "node_modules/expand-tilde": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz", - "integrity": "sha512-A5EmesHW6rfnZ9ysHQjPdJRni0SRar0tjtG5MNtm9n5TUvsYU8oozprtRD4AqHxcZWWlVuAmQo2nWKfN9oyjTw==", - "dev": true, - "dependencies": { - "homedir-polyfill": "^1.0.1" + "node_modules/webpack": { + "version": "5.89.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.89.0.tgz", + "integrity": "sha512-qyfIC10pOr70V+jkmud8tMfajraGCZMBWJtrmuBymQKCrLTRejBI8STDp1MCyZu/QTdZSeacCQYpYNQVOzX5kw==", + "dev": true, + "dependencies": { + "@types/eslint-scope": "^3.7.3", + "@types/estree": "^1.0.0", + "@webassemblyjs/ast": "^1.11.5", + "@webassemblyjs/wasm-edit": "^1.11.5", + "@webassemblyjs/wasm-parser": "^1.11.5", + "acorn": "^8.7.1", + "acorn-import-assertions": "^1.9.0", + "browserslist": "^4.14.5", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^5.15.0", + "es-module-lexer": "^1.2.1", + "eslint-scope": "5.1.1", + "events": "^3.2.0", + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.2.9", + "json-parse-even-better-errors": "^2.3.1", + "loader-runner": "^4.2.0", + "mime-types": "^2.1.27", + "neo-async": "^2.6.2", + "schema-utils": "^3.2.0", + "tapable": "^2.1.1", + "terser-webpack-plugin": "^5.3.7", + "watchpack": "^2.4.0", + "webpack-sources": "^3.2.3" }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/exports-loader": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/exports-loader/-/exports-loader-0.7.0.tgz", - "integrity": "sha512-RKwCrO4A6IiKm0pG3c9V46JxIHcDplwwGJn6+JJ1RcVnh/WSGJa0xkmk5cRVtgOPzCAtTMGj2F7nluh9L0vpSA==", - "dependencies": { - "loader-utils": "^1.1.0", - "source-map": "0.5.0" + "bin": { + "webpack": "bin/webpack.js" }, "engines": { - "node": ">= 4" + "node": ">=10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependenciesMeta": { + "webpack-cli": { + "optional": true + } } }, - "node_modules/extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", - "dev": true - }, - "node_modules/extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", + "node_modules/webpack-cli": { + "version": "4.10.0", + "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-4.10.0.tgz", + "integrity": "sha512-NLhDfH/h4O6UOy+0LSso42xvYypClINuMNBVVzX4vX98TmTaTUxwRbXdhucbFMd2qLaCTcLq/PdYrvi8onw90w==", "dev": true, "dependencies": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" + "@discoveryjs/json-ext": "^0.5.0", + "@webpack-cli/configtest": "^1.2.0", + "@webpack-cli/info": "^1.5.0", + "@webpack-cli/serve": "^1.7.0", + "colorette": "^2.0.14", + "commander": "^7.0.0", + "cross-spawn": "^7.0.3", + "fastest-levenshtein": "^1.0.12", + "import-local": "^3.0.2", + "interpret": "^2.2.0", + "rechoir": "^0.7.0", + "webpack-merge": "^5.7.3" + }, + "bin": { + "webpack-cli": "bin/cli.js" }, "engines": { - "node": ">=0.10.0" + "node": ">=10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "4.x.x || 5.x.x" + }, + "peerDependenciesMeta": { + "@webpack-cli/generators": { + "optional": true + }, + "@webpack-cli/migrate": { + "optional": true + }, + "webpack-bundle-analyzer": { + "optional": true + }, + "webpack-dev-server": { + "optional": true + } } }, - "node_modules/external-editor": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-2.2.0.tgz", - "integrity": "sha512-bSn6gvGxKt+b7+6TKEv1ZycHleA7aHhRHyAqJyp5pbUFuYYNIzpZnQDk7AsYckyWdEnTeAnay0aCy2aV6iTk9A==", + "node_modules/webpack-cli/node_modules/commander": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", "dev": true, - "dependencies": { - "chardet": "^0.4.0", - "iconv-lite": "^0.4.17", - "tmp": "^0.0.33" - }, "engines": { - "node": ">=0.12" + "node": ">= 10" } }, - "node_modules/extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", + "node_modules/webpack-dev-middleware": { + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-5.3.3.tgz", + "integrity": "sha512-hj5CYrY0bZLB+eTO+x/j67Pkrquiy7kWepMHmUMoPsmcUaeEnQJqFzHJOyxgWlq746/wUuA64p9ta34Kyb01pA==", "dev": true, "dependencies": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" + "colorette": "^2.0.10", + "memfs": "^3.4.3", + "mime-types": "^2.1.31", + "range-parser": "^1.2.1", + "schema-utils": "^4.0.0" }, "engines": { - "node": ">=0.10.0" + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^4.0.0 || ^5.0.0" } }, - "node_modules/extglob/node_modules/define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==", + "node_modules/webpack-dev-middleware/node_modules/ajv": { + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", + "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", "dev": true, "dependencies": { - "is-descriptor": "^1.0.0" + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" }, - "engines": { - "node": ">=0.10.0" + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/extglob/node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", + "node_modules/webpack-dev-middleware/node_modules/ajv-keywords": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", "dev": true, "dependencies": { - "is-extendable": "^0.1.0" + "fast-deep-equal": "^3.1.3" }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/extglob/node_modules/is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", - "dev": true, - "engines": { - "node": ">=0.10.0" + "peerDependencies": { + "ajv": "^8.8.2" } }, - "node_modules/extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==", - "dev": true, - "engines": [ - "node >=0.6.0" - ] - }, - "node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "node_modules/webpack-dev-middleware/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", "dev": true }, - "node_modules/fast-glob": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", - "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", + "node_modules/webpack-dev-middleware/node_modules/schema-utils": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz", + "integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==", "dev": true, "dependencies": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.4" + "@types/json-schema": "^7.0.9", + "ajv": "^8.9.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.1.0" }, "engines": { - "node": ">=8.6.0" + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" } }, - "node_modules/fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true - }, - "node_modules/fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", - "dev": true - }, - "node_modules/fastq": { - "version": "1.17.1", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", - "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", - "dev": true, - "dependencies": { - "reusify": "^1.0.4" + "node_modules/webpack-dev-server": { + "version": "4.15.1", + "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-4.15.1.tgz", + "integrity": "sha512-5hbAst3h3C3L8w6W4P96L5vaV0PxSmJhxZvWKYIdgxOQm8pNZ5dEOmmSLBVpP85ReeyRt6AS1QJNyo/oFFPeVA==", + "dev": true, + "dependencies": { + "@types/bonjour": "^3.5.9", + "@types/connect-history-api-fallback": "^1.3.5", + "@types/express": "^4.17.13", + "@types/serve-index": "^1.9.1", + "@types/serve-static": "^1.13.10", + "@types/sockjs": "^0.3.33", + "@types/ws": "^8.5.5", + "ansi-html-community": "^0.0.8", + "bonjour-service": "^1.0.11", + "chokidar": "^3.5.3", + "colorette": "^2.0.10", + "compression": "^1.7.4", + "connect-history-api-fallback": "^2.0.0", + "default-gateway": "^6.0.3", + "express": "^4.17.3", + "graceful-fs": "^4.2.6", + "html-entities": "^2.3.2", + "http-proxy-middleware": "^2.0.3", + "ipaddr.js": "^2.0.1", + "launch-editor": "^2.6.0", + "open": "^8.0.9", + "p-retry": "^4.5.0", + "rimraf": "^3.0.2", + "schema-utils": "^4.0.0", + "selfsigned": "^2.1.1", + "serve-index": "^1.9.1", + "sockjs": "^0.3.24", + "spdy": "^4.0.2", + "webpack-dev-middleware": "^5.3.1", + "ws": "^8.13.0" + }, + "bin": { + "webpack-dev-server": "bin/webpack-dev-server.js" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^4.37.0 || ^5.0.0" + }, + "peerDependenciesMeta": { + "webpack": { + "optional": true + }, + "webpack-cli": { + "optional": true + } } }, - "node_modules/figgy-pudding": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.2.tgz", - "integrity": "sha512-0btnI/H8f2pavGMN8w40mlSKOfTK2SVJmBfBeVIj3kNw0swwgzyRq0d5TJVOwodFmtvpPeWPN/MCcfuWF0Ezbw==", - "deprecated": "This module is no longer supported.", - "dev": true - }, - "node_modules/figures": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", - "integrity": "sha512-Oa2M9atig69ZkfwiApY8F2Yy+tzMbazyvqv21R0NsSC8floSOC09BbT1ITWAdoMGQvJ/aZnR1KMwdx9tvHnTNA==", + "node_modules/webpack-dev-server/node_modules/ajv": { + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", + "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", "dev": true, "dependencies": { - "escape-string-regexp": "^1.0.5" + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" }, - "engines": { - "node": ">=4" + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/file-entry-cache": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-2.0.0.tgz", - "integrity": "sha512-uXP/zGzxxFvFfcZGgBIwotm+Tdc55ddPAzF7iHshP4YGaXMww7rSF9peD9D1sui5ebONg5UobsZv+FfgEpGv/w==", + "node_modules/webpack-dev-server/node_modules/ajv-keywords": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", "dev": true, "dependencies": { - "flat-cache": "^1.2.1", - "object-assign": "^4.0.1" + "fast-deep-equal": "^3.1.3" }, - "engines": { - "node": ">=0.10.0" + "peerDependencies": { + "ajv": "^8.8.2" } }, - "node_modules/file-uri-to-path": { + "node_modules/webpack-dev-server/node_modules/json-schema-traverse": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", - "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", - "dev": true, - "optional": true + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true }, - "node_modules/fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "node_modules/webpack-dev-server/node_modules/schema-utils": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz", + "integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==", "dev": true, "dependencies": { - "to-regex-range": "^5.0.1" + "@types/json-schema": "^7.0.9", + "ajv": "^8.9.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.1.0" }, "engines": { - "node": ">=8" + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" } }, - "node_modules/find-cache-dir": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-1.0.0.tgz", - "integrity": "sha512-46TFiBOzX7xq/PcSWfFwkyjpemdRnMe31UQF+os0y+1W3k95f6R4SEt02Hj4p3X0Mir9gfrkmOtshFidS0VPUg==", + "node_modules/webpack-merge": { + "version": "5.10.0", + "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.10.0.tgz", + "integrity": "sha512-+4zXKdx7UnO+1jaN4l2lHVD+mFvnlZQP/6ljaJVb4SZiwIKeUnrT5l0gkT8z+n4hKpC+jpOv6O9R+gLtag7pSA==", "dev": true, "dependencies": { - "commondir": "^1.0.1", - "make-dir": "^1.0.0", - "pkg-dir": "^2.0.0" + "clone-deep": "^4.0.1", + "flat": "^5.0.2", + "wildcard": "^2.0.0" }, "engines": { - "node": ">=4" + "node": ">=10.0.0" } }, - "node_modules/find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "node_modules/webpack-sources": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz", + "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==", "dev": true, - "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - }, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=10.13.0" } }, - "node_modules/find-versions": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/find-versions/-/find-versions-4.0.0.tgz", - "integrity": "sha512-wgpWy002tA+wgmO27buH/9KzyEOQnKsG/R0yrcjPT9BOFm0zRBVQbZ95nRGXWMywS8YR5knRbpohio0bcJABxQ==", + "node_modules/websocket-driver": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", + "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", "dev": true, "dependencies": { - "semver-regex": "^3.1.2" + "http-parser-js": ">=0.5.1", + "safe-buffer": ">=5.1.0", + "websocket-extensions": ">=0.1.1" }, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=0.8.0" } }, - "node_modules/findup-sync": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-3.0.0.tgz", - "integrity": "sha512-YbffarhcicEhOrm4CtrwdKBdCuz576RLdhJDsIfvNtxUuhdRet1qZcsMjqbePtAseKdAnDyM/IyXbu7PRPRLYg==", + "node_modules/websocket-extensions": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", + "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", "dev": true, - "dependencies": { - "detect-file": "^1.0.0", - "is-glob": "^4.0.0", - "micromatch": "^3.0.4", - "resolve-dir": "^1.0.1" - }, "engines": { - "node": ">= 0.10" + "node": ">=0.8.0" } }, - "node_modules/findup-sync/node_modules/braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, + "node_modules/whatwg-encoding": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-2.0.0.tgz", + "integrity": "sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg==", "dependencies": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" + "iconv-lite": "0.6.3" }, "engines": { - "node": ">=0.10.0" + "node": ">=12" } }, - "node_modules/findup-sync/node_modules/braces/node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", - "dev": true, - "dependencies": { - "is-extendable": "^0.1.0" - }, + "node_modules/whatwg-mimetype": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-3.0.0.tgz", + "integrity": "sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q==", "engines": { - "node": ">=0.10.0" + "node": ">=12" } }, - "node_modules/findup-sync/node_modules/fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ==", - "dev": true, + "node_modules/whatwg-url": { + "version": "12.0.1", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-12.0.1.tgz", + "integrity": "sha512-Ed/LrqB8EPlGxjS+TrsXcpUond1mhccS3pchLhzSgPCnTimUCKj3IZE75pAs5m6heB2U2TMerKFUXheyHY+VDQ==", "dependencies": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" + "tr46": "^4.1.1", + "webidl-conversions": "^7.0.0" }, "engines": { - "node": ">=0.10.0" + "node": ">=14" } }, - "node_modules/findup-sync/node_modules/fill-range/node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dev": true, "dependencies": { - "is-extendable": "^0.1.0" + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" }, "engines": { - "node": ">=0.10.0" + "node": ">= 8" } }, - "node_modules/findup-sync/node_modules/is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", - "dev": true, + "node_modules/wildcard": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.1.tgz", + "integrity": "sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==", + "dev": true + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true + }, + "node_modules/ws": { + "version": "8.15.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.15.1.tgz", + "integrity": "sha512-W5OZiCjXEmk0yZ66ZN82beM5Sz7l7coYxpRkzS+p9PP+ToQry8szKh+61eNktr7EA9DOwvFGhfC605jDHbP6QQ==", "engines": { - "node": ">=0.10.0" + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } } }, - "node_modules/findup-sync/node_modules/is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==", - "dev": true, - "dependencies": { - "kind-of": "^3.0.2" - }, + "node_modules/xml-name-validator": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-4.0.0.tgz", + "integrity": "sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==", "engines": { - "node": ">=0.10.0" + "node": ">=12" } }, - "node_modules/findup-sync/node_modules/is-number/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "node_modules/xmlchars": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", + "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==" + } + }, + "dependencies": { + "@discoveryjs/json-ext": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz", + "integrity": "sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==", + "dev": true + }, + "@jridgewell/gen-mapping": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", + "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" + "requires": { + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" } }, - "node_modules/findup-sync/node_modules/micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "@jridgewell/resolve-uri": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", + "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==", + "dev": true + }, + "@jridgewell/set-array": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", + "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", + "dev": true + }, + "@jridgewell/source-map": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.5.tgz", + "integrity": "sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ==", "dev": true, - "dependencies": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" + "requires": { + "@jridgewell/gen-mapping": "^0.3.0", + "@jridgewell/trace-mapping": "^0.3.9" } }, - "node_modules/findup-sync/node_modules/to-regex-range": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha512-ZZWNfCjUokXXDGXFpZehJIkZqq91BcULFq/Pi7M5i4JnxXdhMKAK682z8bCW3o8Hj1wuuzoKcW3DfVzaP6VuNg==", + "@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", + "dev": true + }, + "@jridgewell/trace-mapping": { + "version": "0.3.20", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.20.tgz", + "integrity": "sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q==", "dev": true, - "dependencies": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" - }, - "engines": { - "node": ">=0.10.0" + "requires": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" } }, - "node_modules/flat-cache": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.3.4.tgz", - "integrity": "sha512-VwyB3Lkgacfik2vhqR4uv2rvebqmDvFu4jlN/C1RzWoJEo8I7z4Q404oiqYCkq41mni8EzQnm95emU9seckwtg==", + "@leichtgewicht/ip-codec": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.4.tgz", + "integrity": "sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A==", + "dev": true + }, + "@tootallnate/once": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", + "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==" + }, + "@types/body-parser": { + "version": "1.19.5", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz", + "integrity": "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==", "dev": true, - "dependencies": { - "circular-json": "^0.3.1", - "graceful-fs": "^4.1.2", - "rimraf": "~2.6.2", - "write": "^0.2.1" - }, - "engines": { - "node": ">=0.10.0" + "requires": { + "@types/connect": "*", + "@types/node": "*" } }, - "node_modules/flat-cache/node_modules/rimraf": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", - "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", + "@types/bonjour": { + "version": "3.5.13", + "resolved": "https://registry.npmjs.org/@types/bonjour/-/bonjour-3.5.13.tgz", + "integrity": "sha512-z9fJ5Im06zvUL548KvYNecEVlA7cVDkGUi6kZusb04mpyEFKCIZJvloCcmpmLaIahDpOQGHaHmG6imtPMmPXGQ==", "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" + "requires": { + "@types/node": "*" } }, - "node_modules/flush-write-stream": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.1.tgz", - "integrity": "sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w==", + "@types/connect": { + "version": "3.4.38", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", + "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", "dev": true, - "dependencies": { - "inherits": "^2.0.3", - "readable-stream": "^2.3.6" + "requires": { + "@types/node": "*" } }, - "node_modules/for-each": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", - "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", + "@types/connect-history-api-fallback": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.5.4.tgz", + "integrity": "sha512-n6Cr2xS1h4uAulPRdlw6Jl6s1oG8KrVilPN2yUITEs+K48EzMJJ3W1xy8K5eWuFvjp3R74AOIGSmp2UfBJ8HFw==", "dev": true, - "dependencies": { - "is-callable": "^1.1.3" + "requires": { + "@types/express-serve-static-core": "*", + "@types/node": "*" } }, - "node_modules/for-in": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", - "integrity": "sha512-7EwmXrOjyL+ChxMhmG5lnW9MPt1aIeZEwKhQzoBUdTV0N3zuwWDZYVJatDvZ2OyzPUvdIAZDsCetk3coyMfcnQ==", + "@types/eslint": { + "version": "8.56.0", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.0.tgz", + "integrity": "sha512-FlsN0p4FhuYRjIxpbdXovvHQhtlG05O1GG/RNWvdAxTboR438IOTwmrY/vLA+Xfgg06BTkP045M3vpFwTMv1dg==", "dev": true, - "engines": { - "node": ">=0.10.0" + "requires": { + "@types/estree": "*", + "@types/json-schema": "*" } }, - "node_modules/forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==", + "@types/eslint-scope": { + "version": "3.7.7", + "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz", + "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==", "dev": true, - "engines": { - "node": "*" + "requires": { + "@types/eslint": "*", + "@types/estree": "*" } }, - "node_modules/form-data": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", - "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "@types/estree": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", + "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", + "dev": true + }, + "@types/express": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz", + "integrity": "sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==", "dev": true, - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 0.12" + "requires": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "^4.17.33", + "@types/qs": "*", + "@types/serve-static": "*" } }, - "node_modules/fragment-cache": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", - "integrity": "sha512-GMBAbW9antB8iZRHLoGw0b3HANt57diZYFO/HL1JGIC1MjKrdmhxvrJbupnVvpys0zsz7yBApXdQyfepKly2kA==", + "@types/express-serve-static-core": { + "version": "4.17.41", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.41.tgz", + "integrity": "sha512-OaJ7XLaelTgrvlZD8/aa0vvvxZdUmlCn6MtWeB7TkiKW70BQLc9XEPpDLPdbo52ZhXUCrznlWdCHWxJWtdyajA==", "dev": true, - "dependencies": { - "map-cache": "^0.2.2" - }, - "engines": { - "node": ">=0.10.0" + "requires": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*", + "@types/send": "*" } }, - "node_modules/from": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/from/-/from-0.1.7.tgz", - "integrity": "sha512-twe20eF1OxVxp/ML/kq2p1uc6KvFK/+vs8WjEbeKmV2He22MKm7YF2ANIt+EOqhJ5L3K/SuuPhk0hWQDjOM23g==", + "@types/http-errors": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz", + "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==", "dev": true }, - "node_modules/from2": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", - "integrity": "sha512-OMcX/4IC/uqEPVgGeyfN22LJk6AZrMkRZHxcHBMBvHScDGgwTm2GT2Wkgtocyd3JfZffjj2kYUDXXII0Fk9W0g==", + "@types/http-proxy": { + "version": "1.17.14", + "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.14.tgz", + "integrity": "sha512-SSrD0c1OQzlFX7pGu1eXxSEjemej64aaNPRhhVYUGqXh0BtldAAx37MG8btcumvpgKyZp1F5Gn3JkktdxiFv6w==", "dev": true, - "dependencies": { - "inherits": "^2.0.1", - "readable-stream": "^2.0.0" + "requires": { + "@types/node": "*" } }, - "node_modules/fromentries": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/fromentries/-/fromentries-1.3.2.tgz", - "integrity": "sha512-cHEpEQHUg0f8XdtZCc2ZAhrHzKzT0MrFUTcvx+hfxYu7rGMDc5SKoXFh+n4YigxsHXRzc6OrCshdR1bWH6HHyg==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] + "@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true }, - "node_modules/fs-extra": { - "version": "11.2.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz", - "integrity": "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==", + "@types/mime": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", + "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==", + "dev": true + }, + "@types/node": { + "version": "20.10.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.10.5.tgz", + "integrity": "sha512-nNPsNE65wjMxEKI93yOP+NPGGBJz/PoN3kZsVLee0XMiJolxSekEVD8wRwBUBqkwc7UWop0edW50yrCQW4CyRw==", "dev": true, - "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - }, - "engines": { - "node": ">=14.14" + "requires": { + "undici-types": "~5.26.4" } }, - "node_modules/fs-write-stream-atomic": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz", - "integrity": "sha512-gehEzmPn2nAwr39eay+x3X34Ra+M2QlVUTLhkXPjWdeO8RF9kszk116avgBJM3ZyNHgHXBNx+VmPaFC36k0PzA==", + "@types/node-forge": { + "version": "1.3.10", + "resolved": "https://registry.npmjs.org/@types/node-forge/-/node-forge-1.3.10.tgz", + "integrity": "sha512-y6PJDYN4xYBxwd22l+OVH35N+1fCYWiuC3aiP2SlXVE6Lo7SS+rSx9r89hLxrP4pn6n1lBGhHJ12pj3F3Mpttw==", "dev": true, - "dependencies": { - "graceful-fs": "^4.1.2", - "iferr": "^0.1.5", - "imurmurhash": "^0.1.4", - "readable-stream": "1 || 2" + "requires": { + "@types/node": "*" } }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "@types/qs": { + "version": "6.9.10", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.10.tgz", + "integrity": "sha512-3Gnx08Ns1sEoCrWssEgTSJs/rsT2vhGP+Ja9cnnk9k4ALxinORlQneLXFeFKOTJMOeZUFD1s7w+w2AphTpvzZw==", "dev": true }, - "node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "@types/range-parser": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", + "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==", + "dev": true + }, + "@types/retry": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.0.tgz", + "integrity": "sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==", + "dev": true + }, + "@types/send": { + "version": "0.17.4", + "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz", + "integrity": "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==", "dev": true, - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + "requires": { + "@types/mime": "^1", + "@types/node": "*" } }, - "node_modules/function-bind": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", - "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "@types/serve-index": { + "version": "1.9.4", + "resolved": "https://registry.npmjs.org/@types/serve-index/-/serve-index-1.9.4.tgz", + "integrity": "sha512-qLpGZ/c2fhSs5gnYsQxtDEq3Oy8SXPClIXkW5ghvAvsNuVSA8k+gCONcUCS/UjLEYvYps+e8uBtfgXgvhwfNug==", "dev": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "requires": { + "@types/express": "*" } }, - "node_modules/function.prototype.name": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz", - "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==", + "@types/serve-static": { + "version": "1.15.5", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.5.tgz", + "integrity": "sha512-PDRk21MnK70hja/YF8AHfC7yIsiQHn1rcXx7ijCFBX/k+XQJhQT/gw3xekXKJvx+5SXaMMS8oqQy09Mzvz2TuQ==", "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "functions-have-names": "^1.2.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "requires": { + "@types/http-errors": "*", + "@types/mime": "*", + "@types/node": "*" } }, - "node_modules/functional-red-black-tree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==", - "dev": true - }, - "node_modules/functions-have-names": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", - "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", + "@types/sockjs": { + "version": "0.3.36", + "resolved": "https://registry.npmjs.org/@types/sockjs/-/sockjs-0.3.36.tgz", + "integrity": "sha512-MK9V6NzAS1+Ud7JV9lJLFqW85VbC9dq3LmwZCuBe4wBDgKC0Kj/jd8Xl+nSviU+Qc3+m7umHHyHg//2KSa0a0Q==", "dev": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "requires": { + "@types/node": "*" } }, - "node_modules/get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "@types/ws": { + "version": "8.5.10", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.10.tgz", + "integrity": "sha512-vmQSUcfalpIq0R9q7uTo2lXs6eGIpt9wtnLdMv9LVpIjCA/+ufZRozlVoVelIYixx1ugCBKDhn89vnsEGOCx9A==", "dev": true, - "engines": { - "node": "6.* || 8.* || >= 10.*" + "requires": { + "@types/node": "*" } }, - "node_modules/get-intrinsic": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", - "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", + "@webassemblyjs/ast": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.6.tgz", + "integrity": "sha512-IN1xI7PwOvLPgjcf180gC1bqn3q/QaOCwYUahIOhbYUu8KA/3tw2RT/T0Gidi1l7Hhj5D/INhJxiICObqpMu4Q==", "dev": true, - "dependencies": { - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "has-proto": "^1.0.1", - "has-symbols": "^1.0.3", - "hasown": "^2.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "requires": { + "@webassemblyjs/helper-numbers": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6" } }, - "node_modules/get-stream": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", - "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "@webassemblyjs/floating-point-hex-parser": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz", + "integrity": "sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==", + "dev": true + }, + "@webassemblyjs/helper-api-error": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz", + "integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==", + "dev": true + }, + "@webassemblyjs/helper-buffer": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.6.tgz", + "integrity": "sha512-z3nFzdcp1mb8nEOFFk8DrYLpHvhKC3grJD2ardfKOzmbmJvEf/tPIqCY+sNcwZIY8ZD7IkB2l7/pqhUhqm7hLA==", + "dev": true + }, + "@webassemblyjs/helper-numbers": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz", + "integrity": "sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==", "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "requires": { + "@webassemblyjs/floating-point-hex-parser": "1.11.6", + "@webassemblyjs/helper-api-error": "1.11.6", + "@xtuc/long": "4.2.2" } }, - "node_modules/get-symbol-description": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.2.tgz", - "integrity": "sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==", + "@webassemblyjs/helper-wasm-bytecode": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz", + "integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==", + "dev": true + }, + "@webassemblyjs/helper-wasm-section": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.6.tgz", + "integrity": "sha512-LPpZbSOwTpEC2cgn4hTydySy1Ke+XEu+ETXuoyvuyezHO3Kjdu90KK95Sh9xTbmjrCsUwvWwCOQQNta37VrS9g==", "dev": true, - "dependencies": { - "call-bind": "^1.0.5", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.4" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "requires": { + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-buffer": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/wasm-gen": "1.11.6" } }, - "node_modules/get-value": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", - "integrity": "sha512-Ln0UQDlxH1BapMu3GPtf7CuYNwRZf2gwCuPqbyG6pB8WfmFpzqcy4xtAaAMUhnNqjMKTiCPZG2oMT3YSx8U2NA==", + "@webassemblyjs/ieee754": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz", + "integrity": "sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==", "dev": true, - "engines": { - "node": ">=0.10.0" + "requires": { + "@xtuc/ieee754": "^1.2.0" } }, - "node_modules/getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==", + "@webassemblyjs/leb128": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.6.tgz", + "integrity": "sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==", "dev": true, - "dependencies": { - "assert-plus": "^1.0.0" + "requires": { + "@xtuc/long": "4.2.2" } }, - "node_modules/gh-pages": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/gh-pages/-/gh-pages-0.12.0.tgz", - "integrity": "sha512-dsSujljaK8VOdFDssfL8dNFC1uATjXqOVpberiE6pr3XT+kyIHDjpBpMteFw+dD59jFdg64d3vloQl/jbYUKDA==", + "@webassemblyjs/utf8": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.6.tgz", + "integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==", + "dev": true + }, + "@webassemblyjs/wasm-edit": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.6.tgz", + "integrity": "sha512-Ybn2I6fnfIGuCR+Faaz7YcvtBKxvoLV3Lebn1tM4o/IAJzmi9AWYIPWpyBfU8cC+JxAO57bk4+zdsTjJR+VTOw==", "dev": true, - "dependencies": { - "async": "2.1.2", - "commander": "2.9.0", - "globby": "^6.1.0", - "graceful-fs": "4.1.10", - "q": "1.4.1", - "q-io": "1.13.2", - "rimraf": "^2.5.4" - }, - "bin": { - "gh-pages": "bin/gh-pages" + "requires": { + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-buffer": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/helper-wasm-section": "1.11.6", + "@webassemblyjs/wasm-gen": "1.11.6", + "@webassemblyjs/wasm-opt": "1.11.6", + "@webassemblyjs/wasm-parser": "1.11.6", + "@webassemblyjs/wast-printer": "1.11.6" } }, - "node_modules/gh-pages/node_modules/async": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/async/-/async-2.1.2.tgz", - "integrity": "sha512-i0Jx7SEZNG5i+F9hrUILpfDkuVJxf+UqmsS6LVn3UdUegQryKplU5t5opYYkDPW0eKBeJUSiiuphgkUZagx5ZQ==", + "@webassemblyjs/wasm-gen": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.6.tgz", + "integrity": "sha512-3XOqkZP/y6B4F0PBAXvI1/bky7GryoogUtfwExeP/v7Nzwo1QLcq5oQmpKlftZLbT+ERUOAZVQjuNVak6UXjPA==", "dev": true, - "dependencies": { - "lodash": "^4.14.0" + "requires": { + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/ieee754": "1.11.6", + "@webassemblyjs/leb128": "1.11.6", + "@webassemblyjs/utf8": "1.11.6" } }, - "node_modules/gh-pages/node_modules/globby": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", - "integrity": "sha512-KVbFv2TQtbzCoxAnfD6JcHZTYCzyliEaaeM/gH8qQdkKr5s0OP9scEgvdcngyk7AVdY6YVW/TJHd+lQ/Df3Daw==", + "@webassemblyjs/wasm-opt": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.6.tgz", + "integrity": "sha512-cOrKuLRE7PCe6AsOVl7WasYf3wbSo4CeOk6PkrjS7g57MFfVUF9u6ysQBBODX0LdgSvQqRiGz3CXvIDKcPNy4g==", "dev": true, - "dependencies": { - "array-union": "^1.0.1", - "glob": "^7.0.3", - "object-assign": "^4.0.1", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" + "requires": { + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-buffer": "1.11.6", + "@webassemblyjs/wasm-gen": "1.11.6", + "@webassemblyjs/wasm-parser": "1.11.6" } }, - "node_modules/gh-pages/node_modules/graceful-fs": { - "version": "4.1.10", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.10.tgz", - "integrity": "sha512-fUSlmTortW+/Fr7OuwVfhHAK3/8Q3J2BxjdHKD2pw9b7fSTEtUmf1Dxc+yByw7r/BDVJT1iWKoLXdAN+qpAKFw==", + "@webassemblyjs/wasm-parser": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.6.tgz", + "integrity": "sha512-6ZwPeGzMJM3Dqp3hCsLgESxBGtT/OeCvCZ4TA1JUPYgmhAx38tTPR9JaKy0S5H3evQpO/h2uWs2j6Yc/fjkpTQ==", "dev": true, - "engines": { - "node": ">=0.4.0" + "requires": { + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-api-error": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/ieee754": "1.11.6", + "@webassemblyjs/leb128": "1.11.6", + "@webassemblyjs/utf8": "1.11.6" } }, - "node_modules/gh-pages/node_modules/pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", + "@webassemblyjs/wast-printer": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.6.tgz", + "integrity": "sha512-JM7AhRcE+yW2GWYaKeHL5vt4xqee5N2WcezptmgyhNS+ScggqcT1OtXykhAb13Sn5Yas0j2uv9tHgrjwvzAP4A==", "dev": true, - "engines": { - "node": ">=0.10.0" + "requires": { + "@webassemblyjs/ast": "1.11.6", + "@xtuc/long": "4.2.2" } }, - "node_modules/git-log-parser": { + "@webpack-cli/configtest": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/git-log-parser/-/git-log-parser-1.2.0.tgz", - "integrity": "sha512-rnCVNfkTL8tdNryFuaY0fYiBWEBcgF748O6ZI61rslBvr2o7U65c2/6npCRqH40vuAhtgtDiqLTJjBVdrejCzA==", + "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-1.2.0.tgz", + "integrity": "sha512-4FB8Tj6xyVkyqjj1OaTqCjXYULB9FMkqQ8yGrZjRDrYh0nOE+7Lhs45WioWQQMV+ceFlE368Ukhe6xdvJM9Egg==", "dev": true, - "dependencies": { - "argv-formatter": "~1.0.0", - "spawn-error-forwarder": "~1.0.0", - "split2": "~1.0.0", - "stream-combiner2": "~1.1.1", - "through2": "~2.0.0", - "traverse": "~0.6.6" - } + "requires": {} }, - "node_modules/git-log-parser/node_modules/split2": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/split2/-/split2-1.0.0.tgz", - "integrity": "sha512-NKywug4u4pX/AZBB1FCPzZ6/7O+Xhz1qMVbzTvvKvikjO99oPN87SkK08mEY9P63/5lWjK+wgOOgApnTg5r6qg==", + "@webpack-cli/info": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-1.5.0.tgz", + "integrity": "sha512-e8tSXZpw2hPl2uMJY6fsMswaok5FdlGNRTktvFk2sD8RjH0hE2+XistawJx1vmKteh4NmGmNUrp+Tb2w+udPcQ==", "dev": true, - "dependencies": { - "through2": "~2.0.0" + "requires": { + "envinfo": "^7.7.3" } }, - "node_modules/git-log-parser/node_modules/through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "@webpack-cli/serve": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-1.7.0.tgz", + "integrity": "sha512-oxnCNGj88fL+xzV+dacXs44HcDwf1ovs3AuEzvP7mqXw7fQntqIhQ1BRmynh4qEKQSSSRSWVyXRjmTbZIX9V2Q==", "dev": true, - "dependencies": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } + "requires": {} }, - "node_modules/git-raw-commits": { - "version": "2.0.11", - "resolved": "https://registry.npmjs.org/git-raw-commits/-/git-raw-commits-2.0.11.tgz", - "integrity": "sha512-VnctFhw+xfj8Va1xtfEqCUD2XDrbAPSJx+hSrE5K7fGdjZruW7XV+QOrN7LF/RJyvspRiD2I0asWsxFp0ya26A==", - "dev": true, - "dependencies": { - "dargs": "^7.0.0", - "lodash": "^4.17.15", - "meow": "^8.0.0", - "split2": "^3.0.0", - "through2": "^4.0.0" - }, - "bin": { - "git-raw-commits": "cli.js" - }, - "engines": { - "node": ">=10" - } + "@xtuc/ieee754": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", + "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", + "dev": true }, - "node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "@xtuc/long": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", + "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", + "dev": true + }, + "abab": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz", + "integrity": "sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==" + }, + "accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", "dev": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "requires": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" } }, - "node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "acorn": { + "version": "8.11.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.2.tgz", + "integrity": "sha512-nc0Axzp/0FILLEVsm4fNwLCwMttvhEI263QtVPQcbpfZZ3ts0hLsZGOpE6czNlid7CJ9MlyH8reXkpsf3YUY4w==", + "dev": true + }, + "acorn-import-assertions": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz", + "integrity": "sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==", "dev": true, - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" + "requires": {} + }, + "agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "requires": { + "debug": "4" } }, - "node_modules/global-dirs": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-0.1.1.tgz", - "integrity": "sha512-NknMLn7F2J7aflwFOlGdNIuCDpN3VGoSoB+aap3KABFWbHVn1TCgFC+np23J8W2BiZbjfEw3BFBycSMv1AFblg==", + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, - "dependencies": { - "ini": "^1.3.4" - }, - "engines": { - "node": ">=4" + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" } }, - "node_modules/global-modules": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz", - "integrity": "sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==", - "dev": true, - "dependencies": { - "global-prefix": "^3.0.0" - }, - "engines": { - "node": ">=6" + "ajv-formats": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", + "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", + "dev": true, + "requires": { + "ajv": "^8.0.0" + }, + "dependencies": { + "ajv": { + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", + "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + } + }, + "json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true + } } }, - "node_modules/global-prefix": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz", - "integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==", + "ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", "dev": true, - "dependencies": { - "ini": "^1.3.5", - "kind-of": "^6.0.2", - "which": "^1.3.1" - }, - "engines": { - "node": ">=6" - } + "requires": {} }, - "node_modules/globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "ansi-html-community": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/ansi-html-community/-/ansi-html-community-0.0.8.tgz", + "integrity": "sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw==", + "dev": true + }, + "anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", "dev": true, - "engines": { - "node": ">=4" + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" } }, - "node_modules/globalthis": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz", - "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==", - "dev": true, - "dependencies": { - "define-properties": "^1.1.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "array-flatten": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-2.1.2.tgz", + "integrity": "sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ==", + "dev": true + }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + }, + "balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "batch": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", + "integrity": "sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==", + "dev": true + }, + "binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "dev": true + }, + "blockly": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/blockly/-/blockly-10.3.0.tgz", + "integrity": "sha512-+95241EVK5o80F3b/iDP61+LfwKwueqscRyh/JfGKPRA4Tlcg8nngu1DdMhOyVCy8Z58AyXuFJ+96+QlCFx5MQ==", + "requires": { + "jsdom": "22.1.0" + } + }, + "body-parser": { + "version": "1.20.1", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", + "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", + "dev": true, + "requires": { + "bytes": "3.1.2", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.11.0", + "raw-body": "2.5.1", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + }, + "dependencies": { + "bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "dev": true + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + } } }, - "node_modules/globby": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/globby/-/globby-7.1.1.tgz", - "integrity": "sha512-yANWAN2DUcBtuus5Cpd+SKROzXHs2iVXFZt/Ykrfz6SAXqacLX25NZpltE+39ceMexYF4TtEadjuSTw8+3wX4g==", + "bonjour-service": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/bonjour-service/-/bonjour-service-1.1.1.tgz", + "integrity": "sha512-Z/5lQRMOG9k7W+FkeGTNjh7htqn/2LMnfOvBZ8pynNZCM9MwkQkI3zeI4oz09uWdcgmgHugVvBqxGg4VQJ5PCg==", "dev": true, - "dependencies": { - "array-union": "^1.0.1", - "dir-glob": "^2.0.0", - "glob": "^7.1.2", - "ignore": "^3.3.5", - "pify": "^3.0.0", - "slash": "^1.0.0" - }, - "engines": { - "node": ">=4" + "requires": { + "array-flatten": "^2.1.2", + "dns-equal": "^1.0.0", + "fast-deep-equal": "^3.1.3", + "multicast-dns": "^7.2.5" } }, - "node_modules/google-closure-compiler": { - "version": "20180402.0.0", - "resolved": "https://registry.npmjs.org/google-closure-compiler/-/google-closure-compiler-20180402.0.0.tgz", - "integrity": "sha512-ZsbRpSBn8SdQ2yQndon6emVfZSr6MTH2lwdZDm6sz5JYX8gSEa3FuuMs3tOtTfsTZElPdYePf2B0I1+EejcdHw==", + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, - "dependencies": { - "chalk": "^1.0.0", - "vinyl": "^2.0.1", - "vinyl-sourcemaps-apply": "^0.2.0" - }, - "bin": { - "google-closure-compiler": "cli.js" - }, - "engines": { - "node": ">=4" + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" } }, - "node_modules/google-closure-compiler/node_modules/ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", "dev": true, - "engines": { - "node": ">=0.10.0" + "requires": { + "fill-range": "^7.0.1" } }, - "node_modules/google-closure-compiler/node_modules/ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha512-kmCevFghRiWM7HB5zTPULl4r9bVFSWjz62MhqizDGUrq2NWuNMQyuv4tHHoKJHs69M/MF64lEcHdYIocrdWQYA==", + "browserslist": { + "version": "4.22.2", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.2.tgz", + "integrity": "sha512-0UgcrvQmBDvZHFGdYUehrCNIazki7/lUP3kkoi/r3YB2amZbFM9J43ZRkJTXBUZK4gmx56+Sqk9+Vs9mwZx9+A==", "dev": true, - "engines": { - "node": ">=0.10.0" + "requires": { + "caniuse-lite": "^1.0.30001565", + "electron-to-chromium": "^1.4.601", + "node-releases": "^2.0.14", + "update-browserslist-db": "^1.0.13" } }, - "node_modules/google-closure-compiler/node_modules/chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha512-U3lRVLMSlsCfjqYPbLyVv11M9CPW4I728d6TCKMAOJueEeB9/8o+eSsMnxPJD+Q+K909sdESg7C+tIkoH6on1A==", - "dev": true, - "dependencies": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } + "buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true }, - "node_modules/google-closure-compiler/node_modules/strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==", + "bytes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", + "integrity": "sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==", + "dev": true + }, + "call-bind": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.5.tgz", + "integrity": "sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ==", "dev": true, - "dependencies": { - "ansi-regex": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" + "requires": { + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.1", + "set-function-length": "^1.1.1" } }, - "node_modules/google-closure-compiler/node_modules/supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha512-KKNVtd6pCYgPIKU4cp2733HWYCpplQhddZLBUryaAHou723x+FRzQ5Df824Fj+IyyuiQTRoub4SnIFfIcrp70g==", + "caniuse-lite": { + "version": "1.0.30001570", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001570.tgz", + "integrity": "sha512-+3e0ASu4sw1SWaoCtvPeyXp+5PsjigkSt8OXZbF9StH5pQWbxEjLAZE3n8Aup5udop1uRiKA7a4utUk/uoSpUw==", + "dev": true + }, + "chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", "dev": true, - "engines": { - "node": ">=0.8.0" + "requires": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "fsevents": "~2.3.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" } }, - "node_modules/google-closure-library": { - "version": "20190301.0.0", - "resolved": "https://registry.npmjs.org/google-closure-library/-/google-closure-library-20190301.0.0.tgz", - "integrity": "sha512-mpeszbnXpRhXZ0sPqUxBgUmk0RtmzrJRy3KFygp0Ih9JuRUjQTCLhwYQeIlK2vB2lShhY/KUo9E1Z1gvxDFxOQ==" + "chrome-trace-event": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", + "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==", + "dev": true }, - "node_modules/gopd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", - "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "clone-deep": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", + "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", "dev": true, - "dependencies": { - "get-intrinsic": "^1.1.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "requires": { + "is-plain-object": "^2.0.4", + "kind-of": "^6.0.2", + "shallow-clone": "^3.0.0" } }, - "node_modules/graceful-fs": { - "version": "4.2.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "colorette": { + "version": "2.0.20", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", + "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", "dev": true }, - "node_modules/graceful-readlink": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz", - "integrity": "sha512-8tLu60LgxF6XpdbK8OW3FA+IfTNBn1ZHGHKF4KQbEeSkajYw5PlYJcKluntgegDPTg8UkHjpet1T82vk6TQ68w==", + "combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "requires": { + "delayed-stream": "~1.0.0" + } + }, + "commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", "dev": true }, - "node_modules/growl": { - "version": "1.10.3", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.3.tgz", - "integrity": "sha512-hKlsbA5Vu3xsh1Cg3J7jSmX/WaW6A5oBeqzM88oNbCRQFz+zUaXm6yxS4RVytp1scBoJzSYl4YAEOQIt6O8V1Q==", + "compressible": { + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", + "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", "dev": true, - "engines": { - "node": ">=4.x" + "requires": { + "mime-db": ">= 1.43.0 < 2" } }, - "node_modules/handlebars": { - "version": "4.7.8", - "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.8.tgz", - "integrity": "sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==", + "compression": { + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz", + "integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==", "dev": true, - "dependencies": { - "minimist": "^1.2.5", - "neo-async": "^2.6.2", - "source-map": "^0.6.1", - "wordwrap": "^1.0.0" - }, - "bin": { - "handlebars": "bin/handlebars" - }, - "engines": { - "node": ">=0.4.7" + "requires": { + "accepts": "~1.3.5", + "bytes": "3.0.0", + "compressible": "~2.0.16", + "debug": "2.6.9", + "on-headers": "~1.0.2", + "safe-buffer": "5.1.2", + "vary": "~1.1.2" }, - "optionalDependencies": { - "uglify-js": "^3.1.4" + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + } } }, - "node_modules/handlebars/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true }, - "node_modules/har-schema": { + "connect-history-api-fallback": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q==", - "dev": true, - "engines": { - "node": ">=4" - } + "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-2.0.0.tgz", + "integrity": "sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA==", + "dev": true }, - "node_modules/har-validator": { - "version": "5.1.5", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", - "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", - "deprecated": "this library is no longer supported", + "content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", "dev": true, - "dependencies": { - "ajv": "^6.12.3", - "har-schema": "^2.0.0" - }, - "engines": { - "node": ">=6" + "requires": { + "safe-buffer": "5.2.1" } }, - "node_modules/har-validator/node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } + "content-type": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "dev": true }, - "node_modules/har-validator/node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "cookie": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", + "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", "dev": true }, - "node_modules/hard-rejection": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz", - "integrity": "sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==", - "dev": true, - "engines": { - "node": ">=6" - } + "cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", + "dev": true }, - "node_modules/has-ansi": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", - "integrity": "sha512-C8vBJ8DwUCx19vhm7urhTuUsr4/IyP6l4VzNQDv+ryHQObW3TTTp9yB68WpYgRe2bbaGuZ/se74IqFeVnMnLZg==", - "dev": true, - "dependencies": { - "ansi-regex": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } + "core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", + "dev": true }, - "node_modules/has-ansi/node_modules/ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", + "cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", "dev": true, - "engines": { - "node": ">=0.10.0" + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" } }, - "node_modules/has-bigints": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", - "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", - "dev": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "cssstyle": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-3.0.0.tgz", + "integrity": "sha512-N4u2ABATi3Qplzf0hWbVCdjenim8F3ojEXpBDF5hBpjzW182MjNGLqfmQ0SkSPeQ+V86ZXgeH8aXj6kayd4jgg==", + "requires": { + "rrweb-cssom": "^0.6.0" } }, - "node_modules/has-flag": { + "data-urls": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-4.0.0.tgz", + "integrity": "sha512-/mMTei/JXPqvFqQtfyTowxmJVwr2PVAeCcDxyFf6LhoOu/09TX2OX3kb2wzi4DMXcfj4OItwDOnhl5oziPnT6g==", + "requires": { + "abab": "^2.0.6", + "whatwg-mimetype": "^3.0.0", + "whatwg-url": "^12.0.0" } }, - "node_modules/has-property-descriptors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", - "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", - "dev": true, - "dependencies": { - "es-define-property": "^1.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "requires": { + "ms": "2.1.2" } }, - "node_modules/has-proto": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", - "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", - "dev": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } + "decimal.js": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.3.tgz", + "integrity": "sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==" }, - "node_modules/has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "default-gateway": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-6.0.3.tgz", + "integrity": "sha512-fwSOJsbbNzZ/CUFpqFBqYfYNLj1NbMPm8MMCIzHjC83iSJRBEGmDUxU+WP661BaBQImeC2yHwXtz+P/O9o+XEg==", "dev": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "requires": { + "execa": "^5.0.0" } }, - "node_modules/has-tostringtag": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", - "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "define-data-property": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.1.tgz", + "integrity": "sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==", "dev": true, - "dependencies": { - "has-symbols": "^1.0.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "requires": { + "get-intrinsic": "^1.2.1", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.0" } }, - "node_modules/has-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", - "integrity": "sha512-IBXk4GTsLYdQ7Rvt+GRBrFSVEkmuOUy4re0Xjd9kJSUQpnTrWR4/y9RpfexN9vkAPMFuQoeWKwqzPozRTlasGw==", - "dev": true, - "dependencies": { - "get-value": "^2.0.6", - "has-values": "^1.0.0", - "isobject": "^3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } + "define-lazy-prop": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", + "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==", + "dev": true }, - "node_modules/has-values": { + "delayed-stream": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", - "integrity": "sha512-ODYZC64uqzmtfGMEAX/FvZiRyWLpAC3vYnNunURUnkGVTS+mI0smVsWaPydRBsE3g+ok7h960jChO8mFcWlHaQ==", - "dev": true, - "dependencies": { - "is-number": "^3.0.0", - "kind-of": "^4.0.0" - }, - "engines": { - "node": ">=0.10.0" - } + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==" }, - "node_modules/has-values/node_modules/is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==", - "dev": true, - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } + "depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "dev": true + }, + "destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "dev": true }, - "node_modules/has-values/node_modules/is-number/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "detect-node": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", + "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==", + "dev": true + }, + "dns-equal": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/dns-equal/-/dns-equal-1.0.0.tgz", + "integrity": "sha512-z+paD6YUQsk+AbGCEM4PrOXSss5gd66QfcVBFTKR/HpFL9jCqikS94HYwKww6fQyO7IxrIIyUu+g0Ka9tUS2Cg==", + "dev": true + }, + "dns-packet": { + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-5.6.1.tgz", + "integrity": "sha512-l4gcSouhcgIKRvyy99RNVOgxXiicE+2jZoNmaNmZ6JXiGajBOJAesk1OBlJuM5k2c+eudGdLxDqXuPCKIj6kpw==", "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" + "requires": { + "@leichtgewicht/ip-codec": "^2.0.1" } }, - "node_modules/has-values/node_modules/kind-of": { + "domexception": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", - "integrity": "sha512-24XsCxmEbRwEDbz/qz3stgin8TTzZ1ESR56OMCN0ujYg+vRutNSiOj9bHH9u85DKgXguraugV5sFuvbD4FW/hw==", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" + "resolved": "https://registry.npmjs.org/domexception/-/domexception-4.0.0.tgz", + "integrity": "sha512-A2is4PLG+eeSfoTMA95/s4pvAoSo2mKtiM5jlHkAVewmiO8ISFTFKZjH7UAM1Atli/OT/7JHOrJRJiMKUZKYBw==", + "requires": { + "webidl-conversions": "^7.0.0" } }, - "node_modules/hash-base": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz", - "integrity": "sha512-EeeoJKjTyt868liAlVmcv2ZsUfGHlE3Q+BICOXcZiwN3osr5Q/zFGYmTJpoIzuaSTAwndFy+GqhEwlU4L3j4Ow==", - "dev": true, - "dependencies": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - }, - "engines": { - "node": ">=4" - } + "ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", + "dev": true }, - "node_modules/hash.js": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", - "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", - "dev": true, - "dependencies": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.1" - } + "electron-to-chromium": { + "version": "1.4.615", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.615.tgz", + "integrity": "sha512-/bKPPcgZVUziECqDc+0HkT87+0zhaWSZHNXqF8FLd2lQcptpmUFwoCSWjCdOng9Gdq+afKArPdEg/0ZW461Eng==", + "dev": true }, - "node_modules/hasown": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", - "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "dev": true + }, + "enhanced-resolve": { + "version": "5.15.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.15.0.tgz", + "integrity": "sha512-LXYT42KJ7lpIKECr2mAXIaMldcNCh/7E0KBKOu4KSfkHmP+mZmSs+8V5gBAqisWBy0OO4W5Oyys0GO1Y8KtdKg==", "dev": true, - "dependencies": { - "function-bind": "^1.1.2" - }, - "engines": { - "node": ">= 0.4" + "requires": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" } }, - "node_modules/he": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", - "integrity": "sha512-z/GDPjlRMNOa2XJiB4em8wJpuuBfrFOlYKTZxtpkdr1uPdibHI8rYA3MY0KDObpVyaes0e/aunid/t88ZI2EKA==", - "dev": true, - "bin": { - "he": "bin/he" - } + "entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==" }, - "node_modules/hmac-drbg": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", - "integrity": "sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==", - "dev": true, - "dependencies": { - "hash.js": "^1.0.3", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.1" - } + "envinfo": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.11.0.tgz", + "integrity": "sha512-G9/6xF1FPbIw0TtalAMaVPpiq2aDEuKLXM314jPVAO9r2fo2a4BLqMNkmRS7O/xPPZ+COAhGIz3ETvHEV3eUcg==", + "dev": true + }, + "es-module-lexer": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.4.1.tgz", + "integrity": "sha512-cXLGjP0c4T3flZJKQSuziYoq7MlT+rnvfZjfp7h+I7K9BNX54kP9nyWvdbwjQ4u1iWbOL4u96fgeZLToQlZC7w==", + "dev": true + }, + "escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true }, - "node_modules/homedir-polyfill": { + "escape-html": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz", - "integrity": "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==", - "dev": true, - "dependencies": { - "parse-passwd": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", + "dev": true }, - "node_modules/hook-std": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/hook-std/-/hook-std-2.0.0.tgz", - "integrity": "sha512-zZ6T5WcuBMIUVh49iPQS9t977t7C0l7OtHrpeMb5uk48JdflRX0NSFvCekfYNmGQETnLq9W/isMyHl69kxGi8g==", + "eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", "dev": true, - "engines": { - "node": ">=8" + "requires": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" } }, - "node_modules/hosted-git-info": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz", - "integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==", + "esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" + "requires": { + "estraverse": "^5.2.0" }, - "engines": { - "node": ">=10" - } - }, - "node_modules/hosted-git-info/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" + "estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true + } } }, - "node_modules/hosted-git-info/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", "dev": true }, - "node_modules/http-proxy-agent": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", - "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", + "etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "dev": true + }, + "eventemitter3": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", + "dev": true + }, + "events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "dev": true + }, + "execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", "dev": true, - "dependencies": { - "agent-base": "^7.1.0", - "debug": "^4.3.4" - }, - "engines": { - "node": ">= 14" + "requires": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" } }, - "node_modules/http-proxy-agent/node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true + "express": { + "version": "4.18.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", + "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", + "dev": true, + "requires": { + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "1.20.1", + "content-disposition": "0.5.4", + "content-type": "~1.0.4", + "cookie": "0.5.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "2.0.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "1.2.0", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.7", + "qs": "6.11.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "0.18.0", + "serve-static": "1.15.0", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "dependencies": { + "array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", + "dev": true + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true } } }, - "node_modules/http-proxy-agent/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", "dev": true }, - "node_modules/http-signature": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ==", - "dev": true, - "dependencies": { - "assert-plus": "^1.0.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" - }, - "engines": { - "node": ">=0.8", - "npm": ">=1.3.7" - } + "fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true }, - "node_modules/https-browserify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", - "integrity": "sha512-J+FkSdyD+0mA0N+81tMotaRMfSL9SGi+xpD3T6YApKsc3bGSXJlfXri3VyFOeYkfLRQisDk1W+jIFFKBeUBbBg==", + "fastest-levenshtein": { + "version": "1.0.16", + "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz", + "integrity": "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==", "dev": true }, - "node_modules/https-proxy-agent": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.4.tgz", - "integrity": "sha512-wlwpilI7YdjSkWaQ/7omYBMTliDcmCN8OLihO6I9B86g06lMyAoqgoDpV0XqoaPOKj+0DIdAvnsWfyAAhmimcg==", + "faye-websocket": { + "version": "0.11.4", + "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz", + "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==", "dev": true, - "dependencies": { - "agent-base": "^7.0.2", - "debug": "4" - }, - "engines": { - "node": ">= 14" + "requires": { + "websocket-driver": ">=0.5.1" } }, - "node_modules/https-proxy-agent/node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", "dev": true, - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } + "requires": { + "to-regex-range": "^5.0.1" } }, - "node_modules/https-proxy-agent/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "node_modules/human-signals": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", - "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", - "dev": true, - "engines": { - "node": ">=10.17.0" + "finalhandler": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", + "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", + "dev": true, + "requires": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "statuses": "2.0.1", + "unpipe": "~1.0.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + } } }, - "node_modules/husky": { - "version": "8.0.3", - "resolved": "https://registry.npmjs.org/husky/-/husky-8.0.3.tgz", - "integrity": "sha512-+dQSyqPh4x1hlO1swXBiNb2HzTDN1I2IGLQx1GrBuiqFJfoMrnZWwVmatvSiO+Iz8fBUnf+lekwNo4c2LlXItg==", + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", "dev": true, - "bin": { - "husky": "lib/bin.js" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/typicode" + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" } }, - "node_modules/iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dev": true, - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3" - }, - "engines": { - "node": ">=0.10.0" + "flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "dev": true + }, + "follow-redirects": { + "version": "1.15.3", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.3.tgz", + "integrity": "sha512-1VzOtuEM8pC9SFU1E+8KfTjZyMztRsgEfwQl44z8A25uy13jSzTj6dyK2Df52iV0vgHCfBwLhDWevLn95w5v6Q==", + "dev": true + }, + "form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" } }, - "node_modules/ieee754": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] + "forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "dev": true }, - "node_modules/iferr": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/iferr/-/iferr-0.1.5.tgz", - "integrity": "sha512-DUNFN5j7Tln0D+TxzloUjKB+CtVu6myn0JEFak6dG18mNt9YkQ6lzGCdafwofISZ1lLF3xRHJ98VKy9ynkcFaA==", + "fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", "dev": true }, - "node_modules/ignore": { - "version": "3.3.10", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.10.tgz", - "integrity": "sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug==", + "fs-monkey": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.0.5.tgz", + "integrity": "sha512-8uMbBjrhzW76TYgEV27Y5E//W2f/lTFmx78P2w19FZSxarhI/798APGQyuGCwmkNxgwGRhrLfvWyLBvNtuOmew==", "dev": true }, - "node_modules/immediate": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz", - "integrity": "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==", + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", "dev": true }, - "node_modules/import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", "dev": true, - "dependencies": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } + "optional": true }, - "node_modules/import-fresh/node_modules/resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true, - "engines": { - "node": ">=4" - } + "function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true }, - "node_modules/import-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/import-from/-/import-from-4.0.0.tgz", - "integrity": "sha512-P9J71vT5nLlDeV8FHs5nNxaLbrpfAV5cF5srvbZfpwpcJoM/xZR3hiv+q+SAnuSmuGbXMWud063iIMx/V/EWZQ==", + "get-intrinsic": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.2.tgz", + "integrity": "sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA==", "dev": true, - "engines": { - "node": ">=12.2" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "requires": { + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" } }, - "node_modules/import-local": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/import-local/-/import-local-2.0.0.tgz", - "integrity": "sha512-b6s04m3O+s3CGSbqDIyP4R6aAwAeYlVq9+WUWep6iHa8ETRf9yei1U48C5MmfJmV9AiLYYBKPMq/W+/WRpQmCQ==", + "get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "dev": true + }, + "glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", "dev": true, - "dependencies": { - "pkg-dir": "^3.0.0", - "resolve-cwd": "^2.0.0" - }, - "bin": { - "import-local-fixture": "fixtures/cli.js" - }, - "engines": { - "node": ">=6" + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" } }, - "node_modules/import-local/node_modules/find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "dev": true, - "dependencies": { - "locate-path": "^3.0.0" - }, - "engines": { - "node": ">=6" + "requires": { + "is-glob": "^4.0.1" } }, - "node_modules/import-local/node_modules/locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "glob-to-regexp": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", + "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", + "dev": true + }, + "gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", "dev": true, - "dependencies": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - }, - "engines": { - "node": ">=6" + "requires": { + "get-intrinsic": "^1.1.3" } }, - "node_modules/import-local/node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true + }, + "handle-thing": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz", + "integrity": "sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "has-property-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz", + "integrity": "sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg==", "dev": true, - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "requires": { + "get-intrinsic": "^1.2.2" } }, - "node_modules/import-local/node_modules/p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "has-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", + "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", + "dev": true + }, + "has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "dev": true + }, + "hasown": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz", + "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==", "dev": true, - "dependencies": { - "p-limit": "^2.0.0" - }, - "engines": { - "node": ">=6" + "requires": { + "function-bind": "^1.1.2" } }, - "node_modules/import-local/node_modules/p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "hpack.js": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz", + "integrity": "sha512-zJxVehUdMGIKsRaNt7apO2Gqp0BdqW5yaiGHXXmbpvxgBYVZnAql+BJb4RO5ad2MgpbZKn5G6nMnegrH1FcNYQ==", "dev": true, - "engines": { - "node": ">=6" + "requires": { + "inherits": "^2.0.1", + "obuf": "^1.0.0", + "readable-stream": "^2.0.1", + "wbuf": "^1.1.0" + }, + "dependencies": { + "readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + } } }, - "node_modules/import-local/node_modules/path-exists": { + "html-encoding-sniffer": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", - "dev": true, - "engines": { - "node": ">=4" + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-3.0.0.tgz", + "integrity": "sha512-oWv4T4yJ52iKrufjnyZPkrN0CH3QnrUqdB6In1g5Fe1mia8GmF36gnfNySxoZtxD5+NmYw1EElVXiBk93UeskA==", + "requires": { + "whatwg-encoding": "^2.0.0" } }, - "node_modules/import-local/node_modules/pkg-dir": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", - "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", + "html-entities": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.4.0.tgz", + "integrity": "sha512-igBTJcNNNhvZFRtm8uA6xMY6xYleeDwn3PeBCkDz7tHttv4F2hsDI2aPgNERWzvRcNYHNT3ymRaQzllmXj4YsQ==", + "dev": true + }, + "http-deceiver": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz", + "integrity": "sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw==", + "dev": true + }, + "http-errors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", "dev": true, - "dependencies": { - "find-up": "^3.0.0" - }, - "engines": { - "node": ">=6" + "requires": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" } }, - "node_modules/imports-loader": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/imports-loader/-/imports-loader-0.8.0.tgz", - "integrity": "sha512-kXWL7Scp8KQ4552ZcdVTeaQCZSLW+e6nJfp3cwUMB673T7Hr98Xjx5JK+ql7ADlJUvj1JS5O01RLbKoutN5QDQ==", - "dependencies": { - "loader-utils": "^1.0.2", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">= 4" + "http-parser-js": { + "version": "0.5.8", + "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.8.tgz", + "integrity": "sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q==", + "dev": true + }, + "http-proxy": { + "version": "1.18.1", + "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", + "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", + "dev": true, + "requires": { + "eventemitter3": "^4.0.0", + "follow-redirects": "^1.0.0", + "requires-port": "^1.0.0" } }, - "node_modules/imports-loader/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" + "http-proxy-agent": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", + "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==", + "requires": { + "@tootallnate/once": "2", + "agent-base": "6", + "debug": "4" } }, - "node_modules/imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "http-proxy-middleware": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.6.tgz", + "integrity": "sha512-ya/UeJ6HVBYxrgYotAZo1KvPWlgB48kUJLDePFeneHsVujFaW5WNj2NgWCAE//B1Dl02BIfYlpNgBy8Kf8Rjmw==", "dev": true, - "engines": { - "node": ">=0.8.19" + "requires": { + "@types/http-proxy": "^1.17.8", + "http-proxy": "^1.18.1", + "is-glob": "^4.0.1", + "is-plain-obj": "^3.0.0", + "micromatch": "^4.0.2" } }, - "node_modules/indent-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", - "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", - "dev": true, - "engines": { - "node": ">=8" + "https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "requires": { + "agent-base": "6", + "debug": "4" } }, - "node_modules/infer-owner": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", - "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==", + "human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", "dev": true }, - "node_modules/inflight": { + "iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "requires": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + } + }, + "import-local": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", + "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==", + "dev": true, + "requires": { + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.0.0" + } + }, + "inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", "dev": true, - "dependencies": { + "requires": { "once": "^1.3.0", "wrappy": "1" } }, - "node_modules/inherits": { + "inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true }, - "node_modules/ini": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "interpret": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-2.2.0.tgz", + "integrity": "sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw==", "dev": true }, - "node_modules/inquirer": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-3.3.0.tgz", - "integrity": "sha512-h+xtnyk4EwKvFWHrUYsWErEVR+igKtLdchu+o0Z1RL7VU/jVMFbYir2bp6bAj8efFNxWqHX0dIss6fJQ+/+qeQ==", - "dev": true, - "dependencies": { - "ansi-escapes": "^3.0.0", - "chalk": "^2.0.0", - "cli-cursor": "^2.1.0", - "cli-width": "^2.0.0", - "external-editor": "^2.0.4", - "figures": "^2.0.0", - "lodash": "^4.3.0", - "mute-stream": "0.0.7", - "run-async": "^2.2.0", - "rx-lite": "^4.0.8", - "rx-lite-aggregates": "^4.0.8", - "string-width": "^2.1.0", - "strip-ansi": "^4.0.0", - "through": "^2.3.6" - } + "ipaddr.js": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.1.0.tgz", + "integrity": "sha512-LlbxQ7xKzfBusov6UMi4MFpEg0m+mAm9xyNGEduwXMEDuf4WfzB/RZwMVYEd7IKGvh4IUkEXYxtAVu9T3OelJQ==", + "dev": true }, - "node_modules/inquirer/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", "dev": true, - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" + "requires": { + "binary-extensions": "^2.0.0" } }, - "node_modules/inquirer/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "is-core-module": { + "version": "2.13.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", + "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", "dev": true, - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" + "requires": { + "hasown": "^2.0.0" } }, - "node_modules/inquirer/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "is-docker": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", + "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", + "dev": true + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true + }, + "is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", "dev": true, - "dependencies": { - "color-name": "1.1.3" + "requires": { + "is-extglob": "^2.1.1" } }, - "node_modules/inquirer/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "dev": true }, - "node_modules/inquirer/node_modules/has-flag": { + "is-plain-obj": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, - "engines": { - "node": ">=4" - } + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-3.0.0.tgz", + "integrity": "sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==", + "dev": true }, - "node_modules/inquirer/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", "dev": true, - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" + "requires": { + "isobject": "^3.0.1" } }, - "node_modules/internal-slot": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.7.tgz", - "integrity": "sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==", + "is-potential-custom-element-name": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", + "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==" + }, + "is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "dev": true + }, + "is-wsl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", "dev": true, - "dependencies": { - "es-errors": "^1.3.0", - "hasown": "^2.0.0", - "side-channel": "^1.0.4" - }, - "engines": { - "node": ">= 0.4" + "requires": { + "is-docker": "^2.0.0" } }, - "node_modules/interpret": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", - "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==", + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "dev": true + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", + "dev": true + }, + "jest-worker": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", + "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", "dev": true, - "engines": { - "node": ">= 0.10" - } + "requires": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + } + }, + "jsdom": { + "version": "22.1.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-22.1.0.tgz", + "integrity": "sha512-/9AVW7xNbsBv6GfWho4TTNjEo9fe6Zhf9O7s0Fhhr3u+awPwAJMKwAMXnkk5vBxflqLW9hTHX/0cs+P3gW+cQw==", + "requires": { + "abab": "^2.0.6", + "cssstyle": "^3.0.0", + "data-urls": "^4.0.0", + "decimal.js": "^10.4.3", + "domexception": "^4.0.0", + "form-data": "^4.0.0", + "html-encoding-sniffer": "^3.0.0", + "http-proxy-agent": "^5.0.0", + "https-proxy-agent": "^5.0.1", + "is-potential-custom-element-name": "^1.0.1", + "nwsapi": "^2.2.4", + "parse5": "^7.1.2", + "rrweb-cssom": "^0.6.0", + "saxes": "^6.0.0", + "symbol-tree": "^3.2.4", + "tough-cookie": "^4.1.2", + "w3c-xmlserializer": "^4.0.0", + "webidl-conversions": "^7.0.0", + "whatwg-encoding": "^2.0.0", + "whatwg-mimetype": "^3.0.0", + "whatwg-url": "^12.0.1", + "ws": "^8.13.0", + "xml-name-validator": "^4.0.0" + } + }, + "json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true }, - "node_modules/into-stream": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/into-stream/-/into-stream-6.0.0.tgz", - "integrity": "sha512-XHbaOAvP+uFKUFsOgoNPRjLkwB+I22JFPFe5OjTkQ0nwgj6+pSjb4NmB6VMxaPshLiOf+zcpOCBQuLwC1KHhZA==", + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true + }, + "launch-editor": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.6.1.tgz", + "integrity": "sha512-eB/uXmFVpY4zezmGp5XtU21kwo7GBbKB+EQ+UZeWtGb9yAM5xt/Evk+lYH3eRNAtId+ej4u7TYPFZ07w4s7rRw==", "dev": true, - "dependencies": { - "from2": "^2.3.0", - "p-is-promise": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "requires": { + "picocolors": "^1.0.0", + "shell-quote": "^1.8.1" } }, - "node_modules/is-accessor-descriptor": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.1.tgz", - "integrity": "sha512-YBUanLI8Yoihw923YeFUS5fs0fF2f5TSFTNiYAAzhhDscDa3lEqYuz1pDOEP5KvX94I9ey3vsqjJcLVFVU+3QA==", + "loader-runner": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", + "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==", + "dev": true + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", "dev": true, - "dependencies": { - "hasown": "^2.0.0" - }, - "engines": { - "node": ">= 0.10" + "requires": { + "p-locate": "^4.1.0" } }, - "node_modules/is-array-buffer": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.4.tgz", - "integrity": "sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==", + "media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "dev": true + }, + "memfs": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.5.3.tgz", + "integrity": "sha512-UERzLsxzllchadvbPs5aolHh65ISpKpM+ccLbOJ8/vvpBKmAWf+la7dXFy7Mr0ySHbdHrFv5kGFCUHHe6GFEmw==", "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.2.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "requires": { + "fs-monkey": "^1.0.4" } }, - "node_modules/is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==", "dev": true }, - "node_modules/is-bigint": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", - "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", - "dev": true, - "dependencies": { - "has-bigints": "^1.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, - "optional": true, - "dependencies": { - "binary-extensions": "^2.0.0" - }, - "engines": { - "node": ">=8" - } + "merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true }, - "node_modules/is-boolean-object": { + "methods": { "version": "1.1.2", - "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", - "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", + "dev": true + }, + "micromatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "requires": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" } }, - "node_modules/is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", "dev": true }, - "node_modules/is-callable": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", - "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", - "dev": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } + "mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==" }, - "node_modules/is-core-module": { - "version": "2.13.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", - "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", - "dev": true, - "dependencies": { - "hasown": "^2.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "requires": { + "mime-db": "1.52.0" } }, - "node_modules/is-data-descriptor": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.1.tgz", - "integrity": "sha512-bc4NlCDiCr28U4aEsQ3Qs2491gVq4V8G7MQyws968ImqjKuYtTJXrl7Vq7jsN7Ly/C3xj5KWFrY7sHNeDkAzXw==", - "dev": true, - "dependencies": { - "hasown": "^2.0.0" - }, - "engines": { - "node": ">= 0.4" - } + "mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true }, - "node_modules/is-data-view": { + "minimalistic-assert": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.1.tgz", - "integrity": "sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w==", - "dev": true, - "dependencies": { - "is-typed-array": "^1.1.13" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", + "dev": true }, - "node_modules/is-date-object": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", - "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, - "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "requires": { + "brace-expansion": "^1.1.7" } }, - "node_modules/is-descriptor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.3.tgz", - "integrity": "sha512-JCNNGbwWZEVaSPtS45mdtrneRWJFp07LLmykxeFV5F6oBvNF8vHSfJuJgoT472pSfk+Mf8VnlrspaFBHWM8JAw==", - "dev": true, - "dependencies": { - "is-accessor-descriptor": "^1.0.1", - "is-data-descriptor": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - } + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, - "node_modules/is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "multicast-dns": { + "version": "7.2.5", + "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-7.2.5.tgz", + "integrity": "sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg==", "dev": true, - "dependencies": { - "is-plain-object": "^2.0.4" - }, - "engines": { - "node": ">=0.10.0" + "requires": { + "dns-packet": "^5.2.2", + "thunky": "^1.0.2" } }, - "node_modules/is-extendable/node_modules/is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "dependencies": { - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } + "negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "dev": true }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } + "neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "dev": true }, - "node_modules/is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", - "dev": true, - "engines": { - "node": ">=4" - } + "node-forge": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz", + "integrity": "sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==", + "dev": true }, - "node_modules/is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, - "dependencies": { - "is-extglob": "^2.1.1" - }, - "engines": { - "node": ">=0.10.0" - } + "node-releases": { + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", + "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==", + "dev": true }, - "node_modules/is-negative-zero": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", - "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", - "dev": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true }, - "node_modules/is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", "dev": true, - "engines": { - "node": ">=0.12.0" + "requires": { + "path-key": "^3.0.0" } }, - "node_modules/is-number-object": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", - "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", + "nwsapi": { + "version": "2.2.7", + "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.7.tgz", + "integrity": "sha512-ub5E4+FBPKwAZx0UwIQOjYWGHTEq5sPqHQNRN8Z9e4A7u3Tj1weLJsL59yH9vmvqEtBHaOmT6cYQKIZOxp35FQ==" + }, + "object-inspect": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", + "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", + "dev": true + }, + "obuf": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", + "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==", + "dev": true + }, + "on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", "dev": true, - "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "requires": { + "ee-first": "1.1.1" } }, - "node_modules/is-obj": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", - "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", + "on-headers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", + "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", + "dev": true + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", "dev": true, - "engines": { - "node": ">=8" + "requires": { + "wrappy": "1" } }, - "node_modules/is-path-cwd": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz", - "integrity": "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==", + "onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", "dev": true, - "engines": { - "node": ">=6" + "requires": { + "mimic-fn": "^2.1.0" } }, - "node_modules/is-path-inside": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", - "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "open": { + "version": "8.4.2", + "resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz", + "integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==", "dev": true, - "engines": { - "node": ">=8" + "requires": { + "define-lazy-prop": "^2.0.0", + "is-docker": "^2.1.1", + "is-wsl": "^2.2.0" } }, - "node_modules/is-plain-obj": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", - "integrity": "sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==", + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", "dev": true, - "engines": { - "node": ">=0.10.0" + "requires": { + "p-try": "^2.0.0" } }, - "node_modules/is-plain-object": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", - "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", "dev": true, - "engines": { - "node": ">=0.10.0" + "requires": { + "p-limit": "^2.2.0" } }, - "node_modules/is-regex": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", - "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", + "p-retry": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-4.6.2.tgz", + "integrity": "sha512-312Id396EbJdvRONlngUx0NydfrIQ5lsYu0znKVUzVvArzEIt08V1qhtyESbGVd1FGX7UKtiFp5uwKZdM8wIuQ==", "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "requires": { + "@types/retry": "0.12.0", + "retry": "^0.13.1" } }, - "node_modules/is-resolvable": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz", - "integrity": "sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==", + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", "dev": true }, - "node_modules/is-shared-array-buffer": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.3.tgz", - "integrity": "sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.7" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "parse5": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz", + "integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==", + "requires": { + "entities": "^4.4.0" } }, - "node_modules/is-stream": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", - "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-string": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", - "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", - "dev": true, - "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-symbol": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", - "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", - "dev": true, - "dependencies": { - "has-symbols": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-text-path": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-text-path/-/is-text-path-1.0.1.tgz", - "integrity": "sha512-xFuJpne9oFz5qDaodwmmG08e3CawH/2ZV8Qqza1Ko7Sk8POWbkRdwIoAWVhqvq0XeUzANEhKo2n0IXUGBm7A/w==", - "dev": true, - "dependencies": { - "text-extensions": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-typed-array": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz", - "integrity": "sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==", - "dev": true, - "dependencies": { - "which-typed-array": "^1.1.14" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==", - "dev": true - }, - "node_modules/is-weakref": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", - "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-windows": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", - "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-wsl": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", - "integrity": "sha512-gfygJYZ2gLTDlmbWMI0CE2MwnFzSN/2SZfkMlItC4K/JBlsWVDB0bO6XhqcY13YXE7iMcAJnzTCJjPiTeJJ0Mw==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", - "dev": true - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true - }, - "node_modules/isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==", - "dev": true - }, - "node_modules/issue-parser": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/issue-parser/-/issue-parser-6.0.0.tgz", - "integrity": "sha512-zKa/Dxq2lGsBIXQ7CUZWTHfvxPC2ej0KfO7fIPqLlHB9J2hJ7rGhZ5rilhuufylr4RXYPzJUeFjKxz305OsNlA==", - "dev": true, - "dependencies": { - "lodash.capitalize": "^4.2.1", - "lodash.escaperegexp": "^4.1.2", - "lodash.isplainobject": "^4.0.6", - "lodash.isstring": "^4.0.1", - "lodash.uniqby": "^4.7.0" - }, - "engines": { - "node": ">=10.13" - } - }, - "node_modules/java-properties": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/java-properties/-/java-properties-1.0.2.tgz", - "integrity": "sha512-qjdpeo2yKlYTH7nFdK0vbZWuTCesk4o63v5iVOlhMQPfuIZQfW/HI35SjfhA+4qpg36rnFSvUK5b1m+ckIblQQ==", - "dev": true, - "engines": { - "node": ">= 0.6.0" - } - }, - "node_modules/js-tokens": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", - "integrity": "sha512-RjTcuD4xjtthQkaWH7dFlH85L+QaVtSoOyGdZ3g6HFhS9dFNDfLyqgm2NFe2X6cQpeFmt0452FJjFG5UameExg==", - "dev": true - }, - "node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==", - "dev": true - }, - "node_modules/json": { - "version": "9.0.6", - "resolved": "https://registry.npmjs.org/json/-/json-9.0.6.tgz", - "integrity": "sha512-Nx+4WwMM1xadgqjjteOVEyjoIVq7fGH1hAlRDoxoq2tFzYsBYZDIKwYbyxolkTYwxsSOgAZD2ACLkeGjhFW2Jw==", - "dev": true, - "bin": { - "json": "lib/json.js" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/json-parse-better-errors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", + "parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", "dev": true }, - "node_modules/json-parse-even-better-errors": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", - "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", - "dev": true - }, - "node_modules/json-schema": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", - "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==", - "dev": true - }, - "node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "dev": true }, - "node_modules/json-stable-stringify-without-jsonify": { + "path-is-absolute": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", - "dev": true - }, - "node_modules/json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", "dev": true }, - "node_modules/json5": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", - "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", - "dependencies": { - "minimist": "^1.2.0" - }, - "bin": { - "json5": "lib/cli.js" - } - }, - "node_modules/jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", - "dev": true, - "dependencies": { - "universalify": "^2.0.0" - }, - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/jsonparse": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", - "integrity": "sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==", - "dev": true, - "engines": [ - "node >= 0.2.0" - ] - }, - "node_modules/JSONStream": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz", - "integrity": "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==", - "dev": true, - "dependencies": { - "jsonparse": "^1.2.0", - "through": ">=2.2.7 <3" - }, - "bin": { - "JSONStream": "bin.js" - }, - "engines": { - "node": "*" - } - }, - "node_modules/jsprim": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz", - "integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==", - "dev": true, - "dependencies": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.4.0", - "verror": "1.10.0" - }, - "engines": { - "node": ">=0.6.0" - } - }, - "node_modules/jszip": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.10.1.tgz", - "integrity": "sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==", - "dev": true, - "dependencies": { - "lie": "~3.3.0", - "pako": "~1.0.2", - "readable-stream": "~2.3.6", - "setimmediate": "^1.0.5" - } - }, - "node_modules/kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==", - "dev": true, - "dependencies": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/lie": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/lie/-/lie-3.3.0.tgz", - "integrity": "sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==", - "dev": true, - "dependencies": { - "immediate": "~3.0.5" - } - }, - "node_modules/lines-and-columns": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", - "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "dev": true }, - "node_modules/load-json-file": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", - "integrity": "sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.1.2", - "parse-json": "^4.0.0", - "pify": "^3.0.0", - "strip-bom": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/load-json-file/node_modules/parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==", - "dev": true, - "dependencies": { - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/loader-runner": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-2.4.0.tgz", - "integrity": "sha512-Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw==", - "dev": true, - "engines": { - "node": ">=4.3.0 <5.0.0 || >=5.10" - } - }, - "node_modules/loader-utils": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.2.tgz", - "integrity": "sha512-I5d00Pd/jwMD2QCduo657+YM/6L3KZu++pmX9VFncxaxvHcru9jx1lBaFft+r4Mt2jK0Yhp41XlRAihzPxHNCg==", - "dependencies": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^1.0.1" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dev": true, - "dependencies": { - "p-locate": "^5.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", "dev": true }, - "node_modules/lodash.camelcase": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", - "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==", - "dev": true - }, - "node_modules/lodash.capitalize": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/lodash.capitalize/-/lodash.capitalize-4.2.1.tgz", - "integrity": "sha512-kZzYOKspf8XVX5AvmQF94gQW0lejFVgb80G85bU4ZWzoJ6C03PQg3coYAUpSTpQWelrZELd3XWgHzw4Ck5kaIw==", - "dev": true - }, - "node_modules/lodash.escaperegexp": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/lodash.escaperegexp/-/lodash.escaperegexp-4.1.2.tgz", - "integrity": "sha512-TM9YBvyC84ZxE3rgfefxUWiQKLilstD6k7PTGt6wfbtXF8ixIJLOL3VYyV/z+ZiPLsVxAsKAFVwWlWeb2Y8Yyw==", - "dev": true - }, - "node_modules/lodash.isfunction": { - "version": "3.0.9", - "resolved": "https://registry.npmjs.org/lodash.isfunction/-/lodash.isfunction-3.0.9.tgz", - "integrity": "sha512-AirXNj15uRIMMPihnkInB4i3NHeb4iBtNg9WRWuK2o31S+ePwwNmDPaTL3o7dTJ+VXNZim7rFs4rxN4YU1oUJw==", - "dev": true - }, - "node_modules/lodash.ismatch": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.ismatch/-/lodash.ismatch-4.4.0.tgz", - "integrity": "sha512-fPMfXjGQEV9Xsq/8MTSgUf255gawYRbjwMyDbcvDhXgV7enSZA0hynz6vMPnpAb5iONEzBHBPsT+0zes5Z301g==", - "dev": true - }, - "node_modules/lodash.isplainobject": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", - "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==", - "dev": true - }, - "node_modules/lodash.isstring": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", - "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==", - "dev": true - }, - "node_modules/lodash.kebabcase": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/lodash.kebabcase/-/lodash.kebabcase-4.1.1.tgz", - "integrity": "sha512-N8XRTIMMqqDgSy4VLKPnJ/+hpGZN+PHQiJnSenYqPaVV/NCqEogTnAdZLQiGKhxX+JCs8waWq2t1XHWKOmlY8g==", - "dev": true - }, - "node_modules/lodash.merge": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true - }, - "node_modules/lodash.mergewith": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.mergewith/-/lodash.mergewith-4.6.2.tgz", - "integrity": "sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ==", - "dev": true - }, - "node_modules/lodash.snakecase": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/lodash.snakecase/-/lodash.snakecase-4.1.1.tgz", - "integrity": "sha512-QZ1d4xoBHYUeuouhEq3lk3Uq7ldgyFXGBhg04+oRLnIz8o9T65Eh+8YdroUwn846zchkA9yDsDl5CVVaV2nqYw==", - "dev": true - }, - "node_modules/lodash.startcase": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.startcase/-/lodash.startcase-4.4.0.tgz", - "integrity": "sha512-+WKqsK294HMSc2jEbNgpHpd0JfIBhp7rEV4aqXWqFr6AlXov+SlcgB1Fv01y2kGe3Gc8nMW7VA0SrGuSkRfIEg==", - "dev": true - }, - "node_modules/lodash.uniq": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", - "integrity": "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==", - "dev": true - }, - "node_modules/lodash.uniqby": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/lodash.uniqby/-/lodash.uniqby-4.7.0.tgz", - "integrity": "sha512-e/zcLx6CSbmaEgFHCA7BnoQKyCtKMxnuWrJygbwPs/AIn+IMKl66L8/s+wBUn5LRw2pZx3bUHibiV1b6aTWIww==", - "dev": true - }, - "node_modules/lodash.upperfirst": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/lodash.upperfirst/-/lodash.upperfirst-4.3.1.tgz", - "integrity": "sha512-sReKOYJIJf74dhJONhU4e0/shzi1trVbSWDOhKYE5XV2O+H7Sb2Dihwuc7xWxVl+DgFPyTqIN3zMfT9cq5iWDg==", - "dev": true - }, - "node_modules/lru-cache": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", - "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", - "dev": true, - "dependencies": { - "pseudomap": "^1.0.2", - "yallist": "^2.1.2" - } - }, - "node_modules/make-dir": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz", - "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==", - "dev": true, - "dependencies": { - "pify": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/make-error": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", - "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", - "dev": true - }, - "node_modules/map-cache": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", - "integrity": "sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/map-obj": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.3.0.tgz", - "integrity": "sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==", - "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/map-stream": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/map-stream/-/map-stream-0.0.7.tgz", - "integrity": "sha512-C0X0KQmGm3N2ftbTGBhSyuydQ+vV1LC3f3zPvT3RXHXNZrvfPZcoXp/N5DOa8vedX/rTMm2CjTtivFg2STJMRQ==", - "dev": true - }, - "node_modules/map-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", - "integrity": "sha512-4y7uGv8bd2WdM9vpQsiQNo41Ln1NvhvDRuVt0k2JZQ+ezN2uaQes7lZeZ+QQUHOLQAtDaBJ+7wCbi+ab/KFs+w==", - "dev": true, - "dependencies": { - "object-visit": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/marked": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/marked/-/marked-4.3.0.tgz", - "integrity": "sha512-PRsaiG84bK+AMvxziE/lCFss8juXjNaWzVbN5tXAm4XjeaS9NAHhop+PjQxz2A9h8Q4M/xGmzP8vqNwy6JeK0A==", - "dev": true, - "bin": { - "marked": "bin/marked.js" - }, - "engines": { - "node": ">= 12" - } - }, - "node_modules/marked-terminal": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/marked-terminal/-/marked-terminal-5.2.0.tgz", - "integrity": "sha512-Piv6yNwAQXGFjZSaiNljyNFw7jKDdGrw70FSbtxEyldLsyeuV5ZHm/1wW++kWbrOF1VPnUgYOhB2oLL0ZpnekA==", - "dev": true, - "dependencies": { - "ansi-escapes": "^6.2.0", - "cardinal": "^2.1.1", - "chalk": "^5.2.0", - "cli-table3": "^0.6.3", - "node-emoji": "^1.11.0", - "supports-hyperlinks": "^2.3.0" - }, - "engines": { - "node": ">=14.13.1 || >=16.0.0" - }, - "peerDependencies": { - "marked": "^1.0.0 || ^2.0.0 || ^3.0.0 || ^4.0.0 || ^5.0.0" - } - }, - "node_modules/marked-terminal/node_modules/ansi-escapes": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-6.2.1.tgz", - "integrity": "sha512-4nJ3yixlEthEJ9Rk4vPcdBRkZvQZlYyu8j4/Mqz5sgIkddmEnH2Yj2ZrnP9S3tQOvSNRUIgVNF/1yPpRAGNRig==", - "dev": true, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/marked-terminal/node_modules/chalk": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", - "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", - "dev": true, - "engines": { - "node": "^12.17.0 || ^14.13 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/md5.js": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", - "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", - "dev": true, - "dependencies": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "node_modules/memory-fs": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz", - "integrity": "sha512-cda4JKCxReDXFXRqOHPQscuIYg1PvxbE2S2GP45rnwfEK+vZaXC8C1OFvdHIbgw0DLzowXGVoxLaAmlgRy14GQ==", - "dev": true, - "dependencies": { - "errno": "^0.1.3", - "readable-stream": "^2.0.1" - } - }, - "node_modules/meow": { - "version": "8.1.2", - "resolved": "https://registry.npmjs.org/meow/-/meow-8.1.2.tgz", - "integrity": "sha512-r85E3NdZ+mpYk1C6RjPFEMSE+s1iZMuHtsHAqY0DT3jZczl0diWUZ8g6oU7h0M9cD2EL+PzaYghhCLzR0ZNn5Q==", - "dev": true, - "dependencies": { - "@types/minimist": "^1.2.0", - "camelcase-keys": "^6.2.2", - "decamelize-keys": "^1.1.0", - "hard-rejection": "^2.1.0", - "minimist-options": "4.1.0", - "normalize-package-data": "^3.0.0", - "read-pkg-up": "^7.0.1", - "redent": "^3.0.0", - "trim-newlines": "^3.0.0", - "type-fest": "^0.18.0", - "yargs-parser": "^20.2.3" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/merge-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", - "dev": true - }, - "node_modules/merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "dev": true, - "engines": { - "node": ">= 8" - } - }, - "node_modules/micromatch": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", - "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", - "dev": true, - "dependencies": { - "braces": "^3.0.2", - "picomatch": "^2.3.1" - }, - "engines": { - "node": ">=8.6" - } - }, - "node_modules/miller-rabin": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", - "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", - "dev": true, - "dependencies": { - "bn.js": "^4.0.0", - "brorand": "^1.0.1" - }, - "bin": { - "miller-rabin": "bin/miller-rabin" - } - }, - "node_modules/miller-rabin/node_modules/bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true - }, - "node_modules/mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", - "dev": true, - "bin": { - "mime": "cli.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "dev": true, - "dependencies": { - "mime-db": "1.52.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mimeparse": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/mimeparse/-/mimeparse-0.1.4.tgz", - "integrity": "sha512-jiuAsJJY4c0oF97oHKic9nva2y1QF2yhYJG3LXLys//f8SNQ89eFuGZ29z62Z29CAY4endJS6zFiKUtURFErog==", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/min-indent": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", - "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/minimalistic-assert": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", - "dev": true - }, - "node_modules/minimalistic-crypto-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", - "integrity": "sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==", - "dev": true - }, - "node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/minimist": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/minimist-options": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-4.1.0.tgz", - "integrity": "sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==", - "dev": true, - "dependencies": { - "arrify": "^1.0.1", - "is-plain-obj": "^1.1.0", - "kind-of": "^6.0.3" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/mississippi": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mississippi/-/mississippi-2.0.0.tgz", - "integrity": "sha512-zHo8v+otD1J10j/tC+VNoGK9keCuByhKovAvdn74dmxJl9+mWHnx6EMsDN4lgRoMI/eYo2nchAxniIbUPb5onw==", - "dev": true, - "dependencies": { - "concat-stream": "^1.5.0", - "duplexify": "^3.4.2", - "end-of-stream": "^1.1.0", - "flush-write-stream": "^1.0.0", - "from2": "^2.1.0", - "parallel-transform": "^1.1.0", - "pump": "^2.0.1", - "pumpify": "^1.3.3", - "stream-each": "^1.1.0", - "through2": "^2.0.0" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/mississippi/node_modules/through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "dependencies": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - }, - "node_modules/mixin-deep": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", - "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", - "dev": true, - "dependencies": { - "for-in": "^1.0.2", - "is-extendable": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/mkdirp": { - "version": "0.5.6", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", - "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", - "dev": true, - "dependencies": { - "minimist": "^1.2.6" - }, - "bin": { - "mkdirp": "bin/cmd.js" - } - }, - "node_modules/mkpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/mkpath/-/mkpath-1.0.0.tgz", - "integrity": "sha512-PbNHr7Y/9Y/2P5pKFv5XOGBfNQqZ+fdiHWcuf7swLACN5ZW5LU7J5tMU8LSBjpluAxAxKYGD9nnaIbdRy9+m1w==", - "dev": true - }, - "node_modules/mocha": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-4.1.0.tgz", - "integrity": "sha512-0RVnjg1HJsXY2YFDoTNzcc1NKhYuXKRrBAG2gDygmJJA136Cs2QlRliZG1mA0ap7cuaT30mw16luAeln+4RiNA==", - "dev": true, - "dependencies": { - "browser-stdout": "1.3.0", - "commander": "2.11.0", - "debug": "3.1.0", - "diff": "3.3.1", - "escape-string-regexp": "1.0.5", - "glob": "7.1.2", - "growl": "1.10.3", - "he": "1.1.1", - "mkdirp": "0.5.1", - "supports-color": "4.4.0" - }, - "bin": { - "_mocha": "bin/_mocha", - "mocha": "bin/mocha" - }, - "engines": { - "node": ">= 4.0.0" - } - }, - "node_modules/mocha/node_modules/commander": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.11.0.tgz", - "integrity": "sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ==", - "dev": true - }, - "node_modules/mocha/node_modules/debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "dev": true, - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/mocha/node_modules/glob": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", - "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", - "dev": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - } - }, - "node_modules/mocha/node_modules/has-flag": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", - "integrity": "sha512-P+1n3MnwjR/Epg9BBo1KT8qbye2g2Ou4sFumihwt6I4tsUX7jnLcX4BTOSKg/B1ZrIYMN9FcEnG4x5a7NB8Eng==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/mocha/node_modules/minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha512-miQKw5Hv4NS1Psg2517mV4e4dYNaO3++hjAvLOAzKqZ61rH8NS1SK+vbfBWZ5PY/Me/bEWhUwqMghEW5Fb9T7Q==", - "dev": true - }, - "node_modules/mocha/node_modules/mkdirp": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha512-SknJC52obPfGQPnjIkXbmA6+5H15E+fR+E4iR2oQ3zzCLbd7/ONua69R/Gw7AgkTLsRG+r5fzksYwWe1AgTyWA==", - "deprecated": "Legacy versions of mkdirp are no longer supported. Please update to mkdirp 1.x. (Note that the API surface has changed to use Promises in 1.x.)", - "dev": true, - "dependencies": { - "minimist": "0.0.8" - }, - "bin": { - "mkdirp": "bin/cmd.js" - } - }, - "node_modules/mocha/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true - }, - "node_modules/mocha/node_modules/supports-color": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", - "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", - "dev": true, - "dependencies": { - "has-flag": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/modify-values": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/modify-values/-/modify-values-1.0.1.tgz", - "integrity": "sha512-xV2bxeN6F7oYjZWTe/YPAy6MN2M+sL4u/Rlm2AHCIVGfo2p1yGmBHQ6vHehl4bRTZBdHu3TSkWdYgkwpYzAGSw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/move-concurrently": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz", - "integrity": "sha512-hdrFxZOycD/g6A6SoI2bB5NA/5NEqD0569+S47WZhPvm46sD50ZHdYaFmnua5lndde9rCHGjmfK7Z8BuCt/PcQ==", - "dev": true, - "dependencies": { - "aproba": "^1.1.1", - "copy-concurrently": "^1.0.0", - "fs-write-stream-atomic": "^1.0.8", - "mkdirp": "^0.5.1", - "rimraf": "^2.5.4", - "run-queue": "^1.0.3" - } - }, - "node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true - }, - "node_modules/mute-stream": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", - "integrity": "sha512-r65nCZhrbXXb6dXOACihYApHw2Q6pV0M3V0PSxd74N0+D8nzAdEAITq2oAjA1jVnKI+tGvEBUpqiMh0+rW6zDQ==", - "dev": true - }, - "node_modules/nan": { - "version": "2.19.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.19.0.tgz", - "integrity": "sha512-nO1xXxfh/RWNxfd/XPfbIfFk5vgLsAxUR9y5O0cHMJu/AW9U95JLXqthYHjEp+8gQ5p96K9jUp8nbVOxCdRbtw==", - "dev": true, - "optional": true - }, - "node_modules/nanomatch": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", - "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", - "dev": true, - "dependencies": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "fragment-cache": "^0.2.1", - "is-windows": "^1.0.2", - "kind-of": "^6.0.2", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", - "dev": true - }, - "node_modules/neo-async": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", - "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", - "dev": true - }, - "node_modules/nerf-dart": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/nerf-dart/-/nerf-dart-1.0.0.tgz", - "integrity": "sha512-EZSPZB70jiVsivaBLYDCyntd5eH8NTSMOn3rB+HxwdmKThGELLdYv8qVIMWvZEFy9w8ZZpW9h9OB32l1rGtj7g==", - "dev": true - }, - "node_modules/nice-try": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", - "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", - "dev": true - }, - "node_modules/node-emoji": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-1.11.0.tgz", - "integrity": "sha512-wo2DpQkQp7Sjm2A0cq+sN7EHKO6Sl0ctXeBdFZrL9T9+UywORbufTcTZxom8YqpLQt/FqNMUkOpkZrJVYSKD3A==", - "dev": true, - "dependencies": { - "lodash": "^4.17.21" - } - }, - "node_modules/node-fetch": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", - "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", - "dev": true, - "dependencies": { - "whatwg-url": "^5.0.0" - }, - "engines": { - "node": "4.x || >=6.0.0" - }, - "peerDependencies": { - "encoding": "^0.1.0" - }, - "peerDependenciesMeta": { - "encoding": { - "optional": true - } - } - }, - "node_modules/node-libs-browser": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.2.1.tgz", - "integrity": "sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q==", - "dev": true, - "dependencies": { - "assert": "^1.1.1", - "browserify-zlib": "^0.2.0", - "buffer": "^4.3.0", - "console-browserify": "^1.1.0", - "constants-browserify": "^1.0.0", - "crypto-browserify": "^3.11.0", - "domain-browser": "^1.1.1", - "events": "^3.0.0", - "https-browserify": "^1.0.0", - "os-browserify": "^0.3.0", - "path-browserify": "0.0.1", - "process": "^0.11.10", - "punycode": "^1.2.4", - "querystring-es3": "^0.2.0", - "readable-stream": "^2.3.3", - "stream-browserify": "^2.0.1", - "stream-http": "^2.7.2", - "string_decoder": "^1.0.0", - "timers-browserify": "^2.0.4", - "tty-browserify": "0.0.0", - "url": "^0.11.0", - "util": "^0.11.0", - "vm-browserify": "^1.0.1" - } - }, - "node_modules/node-libs-browser/node_modules/punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==", - "dev": true - }, - "node_modules/normalize-package-data": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.3.tgz", - "integrity": "sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==", - "dev": true, - "dependencies": { - "hosted-git-info": "^4.0.1", - "is-core-module": "^2.5.0", - "semver": "^7.3.4", - "validate-npm-package-license": "^3.0.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true, - "optional": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/normalize-url": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", - "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/npm": { - "version": "8.19.4", - "resolved": "https://registry.npmjs.org/npm/-/npm-8.19.4.tgz", - "integrity": "sha512-3HANl8i9DKnUA89P4KEgVNN28EjSeDCmvEqbzOAuxCFDzdBZzjUl99zgnGpOUumvW5lvJo2HKcjrsc+tfyv1Hw==", - "bundleDependencies": [ - "@isaacs/string-locale-compare", - "@npmcli/arborist", - "@npmcli/ci-detect", - "@npmcli/config", - "@npmcli/fs", - "@npmcli/map-workspaces", - "@npmcli/package-json", - "@npmcli/run-script", - "abbrev", - "archy", - "cacache", - "chalk", - "chownr", - "cli-columns", - "cli-table3", - "columnify", - "fastest-levenshtein", - "fs-minipass", - "glob", - "graceful-fs", - "hosted-git-info", - "ini", - "init-package-json", - "is-cidr", - "json-parse-even-better-errors", - "libnpmaccess", - "libnpmdiff", - "libnpmexec", - "libnpmfund", - "libnpmhook", - "libnpmorg", - "libnpmpack", - "libnpmpublish", - "libnpmsearch", - "libnpmteam", - "libnpmversion", - "make-fetch-happen", - "minimatch", - "minipass", - "minipass-pipeline", - "mkdirp", - "mkdirp-infer-owner", - "ms", - "node-gyp", - "nopt", - "npm-audit-report", - "npm-install-checks", - "npm-package-arg", - "npm-pick-manifest", - "npm-profile", - "npm-registry-fetch", - "npm-user-validate", - "npmlog", - "opener", - "p-map", - "pacote", - "parse-conflict-json", - "proc-log", - "qrcode-terminal", - "read", - "read-package-json", - "read-package-json-fast", - "readdir-scoped-modules", - "rimraf", - "semver", - "ssri", - "tar", - "text-table", - "tiny-relative-date", - "treeverse", - "validate-npm-package-name", - "which", - "write-file-atomic" - ], - "dev": true, - "workspaces": [ - "docs", - "smoke-tests", - "workspaces/*" - ], - "dependencies": { - "@isaacs/string-locale-compare": "^1.1.0", - "@npmcli/arborist": "^5.6.3", - "@npmcli/ci-detect": "^2.0.0", - "@npmcli/config": "^4.2.1", - "@npmcli/fs": "^2.1.0", - "@npmcli/map-workspaces": "^2.0.3", - "@npmcli/package-json": "^2.0.0", - "@npmcli/run-script": "^4.2.1", - "abbrev": "~1.1.1", - "archy": "~1.0.0", - "cacache": "^16.1.3", - "chalk": "^4.1.2", - "chownr": "^2.0.0", - "cli-columns": "^4.0.0", - "cli-table3": "^0.6.2", - "columnify": "^1.6.0", - "fastest-levenshtein": "^1.0.12", - "fs-minipass": "^2.1.0", - "glob": "^8.0.1", - "graceful-fs": "^4.2.10", - "hosted-git-info": "^5.2.1", - "ini": "^3.0.1", - "init-package-json": "^3.0.2", - "is-cidr": "^4.0.2", - "json-parse-even-better-errors": "^2.3.1", - "libnpmaccess": "^6.0.4", - "libnpmdiff": "^4.0.5", - "libnpmexec": "^4.0.14", - "libnpmfund": "^3.0.5", - "libnpmhook": "^8.0.4", - "libnpmorg": "^4.0.4", - "libnpmpack": "^4.1.3", - "libnpmpublish": "^6.0.5", - "libnpmsearch": "^5.0.4", - "libnpmteam": "^4.0.4", - "libnpmversion": "^3.0.7", - "make-fetch-happen": "^10.2.0", - "minimatch": "^5.1.0", - "minipass": "^3.1.6", - "minipass-pipeline": "^1.2.4", - "mkdirp": "^1.0.4", - "mkdirp-infer-owner": "^2.0.0", - "ms": "^2.1.2", - "node-gyp": "^9.1.0", - "nopt": "^6.0.0", - "npm-audit-report": "^3.0.0", - "npm-install-checks": "^5.0.0", - "npm-package-arg": "^9.1.0", - "npm-pick-manifest": "^7.0.2", - "npm-profile": "^6.2.0", - "npm-registry-fetch": "^13.3.1", - "npm-user-validate": "^1.0.1", - "npmlog": "^6.0.2", - "opener": "^1.5.2", - "p-map": "^4.0.0", - "pacote": "^13.6.2", - "parse-conflict-json": "^2.0.2", - "proc-log": "^2.0.1", - "qrcode-terminal": "^0.12.0", - "read": "~1.0.7", - "read-package-json": "^5.0.2", - "read-package-json-fast": "^2.0.3", - "readdir-scoped-modules": "^1.1.0", - "rimraf": "^3.0.2", - "semver": "^7.3.7", - "ssri": "^9.0.1", - "tar": "^6.1.11", - "text-table": "~0.2.0", - "tiny-relative-date": "^1.3.0", - "treeverse": "^2.0.0", - "validate-npm-package-name": "^4.0.0", - "which": "^2.0.2", - "write-file-atomic": "^4.0.1" - }, - "bin": { - "npm": "bin/npm-cli.js", - "npx": "bin/npx-cli.js" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/npm-run-path": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", - "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", - "dev": true, - "dependencies": { - "path-key": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/npm/node_modules/@colors/colors": { - "version": "1.5.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "optional": true, - "engines": { - "node": ">=0.1.90" - } - }, - "node_modules/npm/node_modules/@gar/promisify": { - "version": "1.1.3", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/npm/node_modules/@isaacs/string-locale-compare": { - "version": "1.1.0", - "dev": true, - "inBundle": true, - "license": "ISC" - }, - "node_modules/npm/node_modules/@npmcli/arborist": { - "version": "5.6.3", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "@isaacs/string-locale-compare": "^1.1.0", - "@npmcli/installed-package-contents": "^1.0.7", - "@npmcli/map-workspaces": "^2.0.3", - "@npmcli/metavuln-calculator": "^3.0.1", - "@npmcli/move-file": "^2.0.0", - "@npmcli/name-from-folder": "^1.0.1", - "@npmcli/node-gyp": "^2.0.0", - "@npmcli/package-json": "^2.0.0", - "@npmcli/query": "^1.2.0", - "@npmcli/run-script": "^4.1.3", - "bin-links": "^3.0.3", - "cacache": "^16.1.3", - "common-ancestor-path": "^1.0.1", - "hosted-git-info": "^5.2.1", - "json-parse-even-better-errors": "^2.3.1", - "json-stringify-nice": "^1.1.4", - "minimatch": "^5.1.0", - "mkdirp": "^1.0.4", - "mkdirp-infer-owner": "^2.0.0", - "nopt": "^6.0.0", - "npm-install-checks": "^5.0.0", - "npm-package-arg": "^9.0.0", - "npm-pick-manifest": "^7.0.2", - "npm-registry-fetch": "^13.0.0", - "npmlog": "^6.0.2", - "pacote": "^13.6.1", - "parse-conflict-json": "^2.0.1", - "proc-log": "^2.0.0", - "promise-all-reject-late": "^1.0.0", - "promise-call-limit": "^1.0.1", - "read-package-json-fast": "^2.0.2", - "readdir-scoped-modules": "^1.1.0", - "rimraf": "^3.0.2", - "semver": "^7.3.7", - "ssri": "^9.0.0", - "treeverse": "^2.0.0", - "walk-up-path": "^1.0.0" - }, - "bin": { - "arborist": "bin/index.js" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/npm/node_modules/@npmcli/ci-detect": { - "version": "2.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16" - } - }, - "node_modules/npm/node_modules/@npmcli/config": { - "version": "4.2.2", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "@npmcli/map-workspaces": "^2.0.2", - "ini": "^3.0.0", - "mkdirp-infer-owner": "^2.0.0", - "nopt": "^6.0.0", - "proc-log": "^2.0.0", - "read-package-json-fast": "^2.0.3", - "semver": "^7.3.5", - "walk-up-path": "^1.0.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/npm/node_modules/@npmcli/disparity-colors": { - "version": "2.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "ansi-styles": "^4.3.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/npm/node_modules/@npmcli/fs": { - "version": "2.1.2", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "@gar/promisify": "^1.1.3", - "semver": "^7.3.5" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/npm/node_modules/@npmcli/git": { - "version": "3.0.2", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "@npmcli/promise-spawn": "^3.0.0", - "lru-cache": "^7.4.4", - "mkdirp": "^1.0.4", - "npm-pick-manifest": "^7.0.0", - "proc-log": "^2.0.0", - "promise-inflight": "^1.0.1", - "promise-retry": "^2.0.1", - "semver": "^7.3.5", - "which": "^2.0.2" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/npm/node_modules/@npmcli/installed-package-contents": { - "version": "1.0.7", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "npm-bundled": "^1.1.1", - "npm-normalize-package-bin": "^1.0.1" - }, - "bin": { - "installed-package-contents": "index.js" - }, - "engines": { - "node": ">= 10" - } - }, - "node_modules/npm/node_modules/@npmcli/installed-package-contents/node_modules/npm-bundled": { - "version": "1.1.2", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "npm-normalize-package-bin": "^1.0.1" - } - }, - "node_modules/npm/node_modules/@npmcli/map-workspaces": { - "version": "2.0.4", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "@npmcli/name-from-folder": "^1.0.1", - "glob": "^8.0.1", - "minimatch": "^5.0.1", - "read-package-json-fast": "^2.0.3" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/npm/node_modules/@npmcli/metavuln-calculator": { - "version": "3.1.1", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "cacache": "^16.0.0", - "json-parse-even-better-errors": "^2.3.1", - "pacote": "^13.0.3", - "semver": "^7.3.5" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/npm/node_modules/@npmcli/move-file": { - "version": "2.0.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "mkdirp": "^1.0.4", - "rimraf": "^3.0.2" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/npm/node_modules/@npmcli/name-from-folder": { - "version": "1.0.1", - "dev": true, - "inBundle": true, - "license": "ISC" - }, - "node_modules/npm/node_modules/@npmcli/node-gyp": { - "version": "2.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/npm/node_modules/@npmcli/package-json": { - "version": "2.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "json-parse-even-better-errors": "^2.3.1" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/npm/node_modules/@npmcli/promise-spawn": { - "version": "3.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "infer-owner": "^1.0.4" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/npm/node_modules/@npmcli/query": { - "version": "1.2.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "npm-package-arg": "^9.1.0", - "postcss-selector-parser": "^6.0.10", - "semver": "^7.3.7" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/npm/node_modules/@npmcli/run-script": { - "version": "4.2.1", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "@npmcli/node-gyp": "^2.0.0", - "@npmcli/promise-spawn": "^3.0.0", - "node-gyp": "^9.0.0", - "read-package-json-fast": "^2.0.3", - "which": "^2.0.2" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/npm/node_modules/@tootallnate/once": { - "version": "2.0.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">= 10" - } - }, - "node_modules/npm/node_modules/abbrev": { - "version": "1.1.1", - "dev": true, - "inBundle": true, - "license": "ISC" - }, - "node_modules/npm/node_modules/agent-base": { - "version": "6.0.2", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "debug": "4" - }, - "engines": { - "node": ">= 6.0.0" - } - }, - "node_modules/npm/node_modules/agentkeepalive": { - "version": "4.2.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "debug": "^4.1.0", - "depd": "^1.1.2", - "humanize-ms": "^1.2.1" - }, - "engines": { - "node": ">= 8.0.0" - } - }, - "node_modules/npm/node_modules/aggregate-error": { - "version": "3.1.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "clean-stack": "^2.0.0", - "indent-string": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/npm/node_modules/ansi-regex": { - "version": "5.0.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/npm/node_modules/ansi-styles": { - "version": "4.3.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/npm/node_modules/aproba": { - "version": "2.0.0", - "dev": true, - "inBundle": true, - "license": "ISC" - }, - "node_modules/npm/node_modules/archy": { - "version": "1.0.0", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/npm/node_modules/are-we-there-yet": { - "version": "3.0.1", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "delegates": "^1.0.0", - "readable-stream": "^3.6.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/npm/node_modules/asap": { - "version": "2.0.6", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/npm/node_modules/balanced-match": { - "version": "1.0.2", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/npm/node_modules/bin-links": { - "version": "3.0.3", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "cmd-shim": "^5.0.0", - "mkdirp-infer-owner": "^2.0.0", - "npm-normalize-package-bin": "^2.0.0", - "read-cmd-shim": "^3.0.0", - "rimraf": "^3.0.0", - "write-file-atomic": "^4.0.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/npm/node_modules/bin-links/node_modules/npm-normalize-package-bin": { - "version": "2.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/npm/node_modules/binary-extensions": { - "version": "2.2.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/npm/node_modules/brace-expansion": { - "version": "2.0.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/npm/node_modules/builtins": { - "version": "5.0.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "semver": "^7.0.0" - } - }, - "node_modules/npm/node_modules/cacache": { - "version": "16.1.3", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "@npmcli/fs": "^2.1.0", - "@npmcli/move-file": "^2.0.0", - "chownr": "^2.0.0", - "fs-minipass": "^2.1.0", - "glob": "^8.0.1", - "infer-owner": "^1.0.4", - "lru-cache": "^7.7.1", - "minipass": "^3.1.6", - "minipass-collect": "^1.0.2", - "minipass-flush": "^1.0.5", - "minipass-pipeline": "^1.2.4", - "mkdirp": "^1.0.4", - "p-map": "^4.0.0", - "promise-inflight": "^1.0.1", - "rimraf": "^3.0.2", - "ssri": "^9.0.0", - "tar": "^6.1.11", - "unique-filename": "^2.0.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/npm/node_modules/chalk": { - "version": "4.1.2", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/npm/node_modules/chownr": { - "version": "2.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "engines": { - "node": ">=10" - } - }, - "node_modules/npm/node_modules/cidr-regex": { - "version": "3.1.1", - "dev": true, - "inBundle": true, - "license": "BSD-2-Clause", - "dependencies": { - "ip-regex": "^4.1.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/npm/node_modules/clean-stack": { - "version": "2.2.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/npm/node_modules/cli-columns": { - "version": "4.0.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "string-width": "^4.2.3", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">= 10" - } - }, - "node_modules/npm/node_modules/cli-table3": { - "version": "0.6.2", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "string-width": "^4.2.0" - }, - "engines": { - "node": "10.* || >= 12.*" - }, - "optionalDependencies": { - "@colors/colors": "1.5.0" - } - }, - "node_modules/npm/node_modules/clone": { - "version": "1.0.4", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=0.8" - } - }, - "node_modules/npm/node_modules/cmd-shim": { - "version": "5.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "mkdirp-infer-owner": "^2.0.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/npm/node_modules/color-convert": { - "version": "2.0.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/npm/node_modules/color-name": { - "version": "1.1.4", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/npm/node_modules/color-support": { - "version": "1.1.3", - "dev": true, - "inBundle": true, - "license": "ISC", - "bin": { - "color-support": "bin.js" - } - }, - "node_modules/npm/node_modules/columnify": { - "version": "1.6.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "strip-ansi": "^6.0.1", - "wcwidth": "^1.0.0" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/npm/node_modules/common-ancestor-path": { - "version": "1.0.1", - "dev": true, - "inBundle": true, - "license": "ISC" - }, - "node_modules/npm/node_modules/concat-map": { - "version": "0.0.1", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/npm/node_modules/console-control-strings": { - "version": "1.1.0", - "dev": true, - "inBundle": true, - "license": "ISC" - }, - "node_modules/npm/node_modules/cssesc": { - "version": "3.0.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "bin": { - "cssesc": "bin/cssesc" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/npm/node_modules/debug": { - "version": "4.3.4", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/npm/node_modules/debug/node_modules/ms": { - "version": "2.1.2", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/npm/node_modules/debuglog": { - "version": "1.0.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": "*" - } - }, - "node_modules/npm/node_modules/defaults": { - "version": "1.0.3", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "clone": "^1.0.2" - } - }, - "node_modules/npm/node_modules/delegates": { - "version": "1.0.0", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/npm/node_modules/depd": { - "version": "1.1.2", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/npm/node_modules/dezalgo": { - "version": "1.0.4", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "asap": "^2.0.0", - "wrappy": "1" - } - }, - "node_modules/npm/node_modules/diff": { - "version": "5.1.0", - "dev": true, - "inBundle": true, - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.3.1" - } - }, - "node_modules/npm/node_modules/emoji-regex": { - "version": "8.0.0", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/npm/node_modules/encoding": { - "version": "0.1.13", - "dev": true, - "inBundle": true, - "license": "MIT", - "optional": true, - "dependencies": { - "iconv-lite": "^0.6.2" - } - }, - "node_modules/npm/node_modules/env-paths": { - "version": "2.2.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/npm/node_modules/err-code": { - "version": "2.0.3", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/npm/node_modules/fastest-levenshtein": { - "version": "1.0.12", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/npm/node_modules/fs-minipass": { - "version": "2.1.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/npm/node_modules/fs.realpath": { - "version": "1.0.0", - "dev": true, - "inBundle": true, - "license": "ISC" - }, - "node_modules/npm/node_modules/function-bind": { - "version": "1.1.1", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/npm/node_modules/gauge": { - "version": "4.0.4", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "aproba": "^1.0.3 || ^2.0.0", - "color-support": "^1.1.3", - "console-control-strings": "^1.1.0", - "has-unicode": "^2.0.1", - "signal-exit": "^3.0.7", - "string-width": "^4.2.3", - "strip-ansi": "^6.0.1", - "wide-align": "^1.1.5" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/npm/node_modules/glob": { - "version": "8.0.3", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^5.0.1", - "once": "^1.3.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/npm/node_modules/graceful-fs": { - "version": "4.2.10", - "dev": true, - "inBundle": true, - "license": "ISC" - }, - "node_modules/npm/node_modules/has": { - "version": "1.0.3", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "function-bind": "^1.1.1" - }, - "engines": { - "node": ">= 0.4.0" - } - }, - "node_modules/npm/node_modules/has-flag": { - "version": "4.0.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/npm/node_modules/has-unicode": { - "version": "2.0.1", - "dev": true, - "inBundle": true, - "license": "ISC" - }, - "node_modules/npm/node_modules/hosted-git-info": { - "version": "5.2.1", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "lru-cache": "^7.5.1" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/npm/node_modules/http-cache-semantics": { - "version": "4.1.1", - "dev": true, - "inBundle": true, - "license": "BSD-2-Clause" - }, - "node_modules/npm/node_modules/http-proxy-agent": { - "version": "5.0.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "@tootallnate/once": "2", - "agent-base": "6", - "debug": "4" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/npm/node_modules/https-proxy-agent": { - "version": "5.0.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "agent-base": "6", - "debug": "4" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/npm/node_modules/humanize-ms": { - "version": "1.2.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "ms": "^2.0.0" - } - }, - "node_modules/npm/node_modules/iconv-lite": { - "version": "0.6.3", - "dev": true, - "inBundle": true, - "license": "MIT", - "optional": true, - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/npm/node_modules/ignore-walk": { - "version": "5.0.1", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "minimatch": "^5.0.1" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/npm/node_modules/imurmurhash": { - "version": "0.1.4", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=0.8.19" - } - }, - "node_modules/npm/node_modules/indent-string": { - "version": "4.0.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/npm/node_modules/infer-owner": { - "version": "1.0.4", - "dev": true, - "inBundle": true, - "license": "ISC" - }, - "node_modules/npm/node_modules/inflight": { - "version": "1.0.6", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "node_modules/npm/node_modules/inherits": { - "version": "2.0.4", - "dev": true, - "inBundle": true, - "license": "ISC" - }, - "node_modules/npm/node_modules/ini": { - "version": "3.0.1", - "dev": true, - "inBundle": true, - "license": "ISC", - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/npm/node_modules/init-package-json": { - "version": "3.0.2", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "npm-package-arg": "^9.0.1", - "promzard": "^0.3.0", - "read": "^1.0.7", - "read-package-json": "^5.0.0", - "semver": "^7.3.5", - "validate-npm-package-license": "^3.0.4", - "validate-npm-package-name": "^4.0.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/npm/node_modules/ip": { - "version": "2.0.0", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/npm/node_modules/ip-regex": { - "version": "4.3.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/npm/node_modules/is-cidr": { - "version": "4.0.2", - "dev": true, - "inBundle": true, - "license": "BSD-2-Clause", - "dependencies": { - "cidr-regex": "^3.1.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/npm/node_modules/is-core-module": { - "version": "2.10.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "has": "^1.0.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/npm/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/npm/node_modules/is-lambda": { - "version": "1.0.1", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/npm/node_modules/isexe": { - "version": "2.0.0", - "dev": true, - "inBundle": true, - "license": "ISC" - }, - "node_modules/npm/node_modules/json-parse-even-better-errors": { - "version": "2.3.1", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/npm/node_modules/json-stringify-nice": { - "version": "1.1.4", - "dev": true, - "inBundle": true, - "license": "ISC", - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/npm/node_modules/jsonparse": { - "version": "1.3.1", - "dev": true, - "engines": [ - "node >= 0.2.0" - ], - "inBundle": true, - "license": "MIT" - }, - "node_modules/npm/node_modules/just-diff": { - "version": "5.1.1", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/npm/node_modules/just-diff-apply": { - "version": "5.4.1", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/npm/node_modules/libnpmaccess": { - "version": "6.0.4", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "aproba": "^2.0.0", - "minipass": "^3.1.1", - "npm-package-arg": "^9.0.1", - "npm-registry-fetch": "^13.0.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/npm/node_modules/libnpmdiff": { - "version": "4.0.5", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "@npmcli/disparity-colors": "^2.0.0", - "@npmcli/installed-package-contents": "^1.0.7", - "binary-extensions": "^2.2.0", - "diff": "^5.1.0", - "minimatch": "^5.0.1", - "npm-package-arg": "^9.0.1", - "pacote": "^13.6.1", - "tar": "^6.1.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/npm/node_modules/libnpmexec": { - "version": "4.0.14", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "@npmcli/arborist": "^5.6.3", - "@npmcli/ci-detect": "^2.0.0", - "@npmcli/fs": "^2.1.1", - "@npmcli/run-script": "^4.2.0", - "chalk": "^4.1.0", - "mkdirp-infer-owner": "^2.0.0", - "npm-package-arg": "^9.0.1", - "npmlog": "^6.0.2", - "pacote": "^13.6.1", - "proc-log": "^2.0.0", - "read": "^1.0.7", - "read-package-json-fast": "^2.0.2", - "semver": "^7.3.7", - "walk-up-path": "^1.0.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/npm/node_modules/libnpmfund": { - "version": "3.0.5", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "@npmcli/arborist": "^5.6.3" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/npm/node_modules/libnpmhook": { - "version": "8.0.4", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "aproba": "^2.0.0", - "npm-registry-fetch": "^13.0.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/npm/node_modules/libnpmorg": { - "version": "4.0.4", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "aproba": "^2.0.0", - "npm-registry-fetch": "^13.0.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/npm/node_modules/libnpmpack": { - "version": "4.1.3", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "@npmcli/run-script": "^4.1.3", - "npm-package-arg": "^9.0.1", - "pacote": "^13.6.1" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/npm/node_modules/libnpmpublish": { - "version": "6.0.5", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "normalize-package-data": "^4.0.0", - "npm-package-arg": "^9.0.1", - "npm-registry-fetch": "^13.0.0", - "semver": "^7.3.7", - "ssri": "^9.0.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/npm/node_modules/libnpmsearch": { - "version": "5.0.4", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "npm-registry-fetch": "^13.0.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/npm/node_modules/libnpmteam": { - "version": "4.0.4", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "aproba": "^2.0.0", - "npm-registry-fetch": "^13.0.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/npm/node_modules/libnpmversion": { - "version": "3.0.7", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "@npmcli/git": "^3.0.0", - "@npmcli/run-script": "^4.1.3", - "json-parse-even-better-errors": "^2.3.1", - "proc-log": "^2.0.0", - "semver": "^7.3.7" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/npm/node_modules/lru-cache": { - "version": "7.13.2", - "dev": true, - "inBundle": true, - "license": "ISC", - "engines": { - "node": ">=12" - } - }, - "node_modules/npm/node_modules/make-fetch-happen": { - "version": "10.2.1", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "agentkeepalive": "^4.2.1", - "cacache": "^16.1.0", - "http-cache-semantics": "^4.1.0", - "http-proxy-agent": "^5.0.0", - "https-proxy-agent": "^5.0.0", - "is-lambda": "^1.0.1", - "lru-cache": "^7.7.1", - "minipass": "^3.1.6", - "minipass-collect": "^1.0.2", - "minipass-fetch": "^2.0.3", - "minipass-flush": "^1.0.5", - "minipass-pipeline": "^1.2.4", - "negotiator": "^0.6.3", - "promise-retry": "^2.0.1", - "socks-proxy-agent": "^7.0.0", - "ssri": "^9.0.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/npm/node_modules/minimatch": { - "version": "5.1.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/npm/node_modules/minipass": { - "version": "3.3.4", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/npm/node_modules/minipass-collect": { - "version": "1.0.2", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/npm/node_modules/minipass-fetch": { - "version": "2.1.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "minipass": "^3.1.6", - "minipass-sized": "^1.0.3", - "minizlib": "^2.1.2" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - }, - "optionalDependencies": { - "encoding": "^0.1.13" - } - }, - "node_modules/npm/node_modules/minipass-flush": { - "version": "1.0.5", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/npm/node_modules/minipass-json-stream": { - "version": "1.0.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "jsonparse": "^1.3.1", - "minipass": "^3.0.0" - } - }, - "node_modules/npm/node_modules/minipass-pipeline": { - "version": "1.2.4", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/npm/node_modules/minipass-sized": { - "version": "1.0.3", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/npm/node_modules/minizlib": { - "version": "2.1.2", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "minipass": "^3.0.0", - "yallist": "^4.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/npm/node_modules/mkdirp": { - "version": "1.0.4", - "dev": true, - "inBundle": true, - "license": "MIT", - "bin": { - "mkdirp": "bin/cmd.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/npm/node_modules/mkdirp-infer-owner": { - "version": "2.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "chownr": "^2.0.0", - "infer-owner": "^1.0.4", - "mkdirp": "^1.0.3" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/npm/node_modules/ms": { - "version": "2.1.3", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/npm/node_modules/mute-stream": { - "version": "0.0.8", - "dev": true, - "inBundle": true, - "license": "ISC" - }, - "node_modules/npm/node_modules/negotiator": { - "version": "0.6.3", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/npm/node_modules/node-gyp": { - "version": "9.1.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "env-paths": "^2.2.0", - "glob": "^7.1.4", - "graceful-fs": "^4.2.6", - "make-fetch-happen": "^10.0.3", - "nopt": "^5.0.0", - "npmlog": "^6.0.0", - "rimraf": "^3.0.2", - "semver": "^7.3.5", - "tar": "^6.1.2", - "which": "^2.0.2" - }, - "bin": { - "node-gyp": "bin/node-gyp.js" - }, - "engines": { - "node": "^12.22 || ^14.13 || >=16" - } - }, - "node_modules/npm/node_modules/node-gyp/node_modules/brace-expansion": { - "version": "1.1.11", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/npm/node_modules/node-gyp/node_modules/glob": { - "version": "7.2.3", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/npm/node_modules/node-gyp/node_modules/minimatch": { - "version": "3.1.2", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/npm/node_modules/node-gyp/node_modules/nopt": { - "version": "5.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "abbrev": "1" - }, - "bin": { - "nopt": "bin/nopt.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/npm/node_modules/nopt": { - "version": "6.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "abbrev": "^1.0.0" - }, - "bin": { - "nopt": "bin/nopt.js" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/npm/node_modules/normalize-package-data": { - "version": "4.0.1", - "dev": true, - "inBundle": true, - "license": "BSD-2-Clause", - "dependencies": { - "hosted-git-info": "^5.0.0", - "is-core-module": "^2.8.1", - "semver": "^7.3.5", - "validate-npm-package-license": "^3.0.4" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/npm/node_modules/npm-audit-report": { - "version": "3.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "chalk": "^4.0.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/npm/node_modules/npm-bundled": { - "version": "2.0.1", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "npm-normalize-package-bin": "^2.0.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/npm/node_modules/npm-bundled/node_modules/npm-normalize-package-bin": { - "version": "2.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/npm/node_modules/npm-install-checks": { - "version": "5.0.0", - "dev": true, - "inBundle": true, - "license": "BSD-2-Clause", - "dependencies": { - "semver": "^7.1.1" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/npm/node_modules/npm-normalize-package-bin": { - "version": "1.0.1", - "dev": true, - "inBundle": true, - "license": "ISC" - }, - "node_modules/npm/node_modules/npm-package-arg": { - "version": "9.1.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "hosted-git-info": "^5.0.0", - "proc-log": "^2.0.1", - "semver": "^7.3.5", - "validate-npm-package-name": "^4.0.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/npm/node_modules/npm-packlist": { - "version": "5.1.3", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "glob": "^8.0.1", - "ignore-walk": "^5.0.1", - "npm-bundled": "^2.0.0", - "npm-normalize-package-bin": "^2.0.0" - }, - "bin": { - "npm-packlist": "bin/index.js" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/npm/node_modules/npm-packlist/node_modules/npm-normalize-package-bin": { - "version": "2.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/npm/node_modules/npm-pick-manifest": { - "version": "7.0.2", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "npm-install-checks": "^5.0.0", - "npm-normalize-package-bin": "^2.0.0", - "npm-package-arg": "^9.0.0", - "semver": "^7.3.5" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/npm/node_modules/npm-pick-manifest/node_modules/npm-normalize-package-bin": { - "version": "2.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/npm/node_modules/npm-profile": { - "version": "6.2.1", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "npm-registry-fetch": "^13.0.1", - "proc-log": "^2.0.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/npm/node_modules/npm-registry-fetch": { - "version": "13.3.1", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "make-fetch-happen": "^10.0.6", - "minipass": "^3.1.6", - "minipass-fetch": "^2.0.3", - "minipass-json-stream": "^1.0.1", - "minizlib": "^2.1.2", - "npm-package-arg": "^9.0.1", - "proc-log": "^2.0.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/npm/node_modules/npm-user-validate": { - "version": "1.0.1", - "dev": true, - "inBundle": true, - "license": "BSD-2-Clause" - }, - "node_modules/npm/node_modules/npmlog": { - "version": "6.0.2", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "are-we-there-yet": "^3.0.0", - "console-control-strings": "^1.1.0", - "gauge": "^4.0.3", - "set-blocking": "^2.0.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/npm/node_modules/once": { - "version": "1.4.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "wrappy": "1" - } - }, - "node_modules/npm/node_modules/opener": { - "version": "1.5.2", - "dev": true, - "inBundle": true, - "license": "(WTFPL OR MIT)", - "bin": { - "opener": "bin/opener-bin.js" - } - }, - "node_modules/npm/node_modules/p-map": { - "version": "4.0.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "aggregate-error": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/npm/node_modules/pacote": { - "version": "13.6.2", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "@npmcli/git": "^3.0.0", - "@npmcli/installed-package-contents": "^1.0.7", - "@npmcli/promise-spawn": "^3.0.0", - "@npmcli/run-script": "^4.1.0", - "cacache": "^16.0.0", - "chownr": "^2.0.0", - "fs-minipass": "^2.1.0", - "infer-owner": "^1.0.4", - "minipass": "^3.1.6", - "mkdirp": "^1.0.4", - "npm-package-arg": "^9.0.0", - "npm-packlist": "^5.1.0", - "npm-pick-manifest": "^7.0.0", - "npm-registry-fetch": "^13.0.1", - "proc-log": "^2.0.0", - "promise-retry": "^2.0.1", - "read-package-json": "^5.0.0", - "read-package-json-fast": "^2.0.3", - "rimraf": "^3.0.2", - "ssri": "^9.0.0", - "tar": "^6.1.11" - }, - "bin": { - "pacote": "lib/bin.js" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/npm/node_modules/parse-conflict-json": { - "version": "2.0.2", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "json-parse-even-better-errors": "^2.3.1", - "just-diff": "^5.0.1", - "just-diff-apply": "^5.2.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/npm/node_modules/path-is-absolute": { - "version": "1.0.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/npm/node_modules/postcss-selector-parser": { - "version": "6.0.10", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "cssesc": "^3.0.0", - "util-deprecate": "^1.0.2" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/npm/node_modules/proc-log": { - "version": "2.0.1", - "dev": true, - "inBundle": true, - "license": "ISC", - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/npm/node_modules/promise-all-reject-late": { - "version": "1.0.1", - "dev": true, - "inBundle": true, - "license": "ISC", - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/npm/node_modules/promise-call-limit": { - "version": "1.0.1", - "dev": true, - "inBundle": true, - "license": "ISC", - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/npm/node_modules/promise-inflight": { - "version": "1.0.1", - "dev": true, - "inBundle": true, - "license": "ISC" - }, - "node_modules/npm/node_modules/promise-retry": { - "version": "2.0.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "err-code": "^2.0.2", - "retry": "^0.12.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/npm/node_modules/promzard": { - "version": "0.3.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "read": "1" - } - }, - "node_modules/npm/node_modules/qrcode-terminal": { - "version": "0.12.0", - "dev": true, - "inBundle": true, - "bin": { - "qrcode-terminal": "bin/qrcode-terminal.js" - } - }, - "node_modules/npm/node_modules/read": { - "version": "1.0.7", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "mute-stream": "~0.0.4" - }, - "engines": { - "node": ">=0.8" - } - }, - "node_modules/npm/node_modules/read-cmd-shim": { - "version": "3.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/npm/node_modules/read-package-json": { - "version": "5.0.2", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "glob": "^8.0.1", - "json-parse-even-better-errors": "^2.3.1", - "normalize-package-data": "^4.0.0", - "npm-normalize-package-bin": "^2.0.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/npm/node_modules/read-package-json-fast": { - "version": "2.0.3", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "json-parse-even-better-errors": "^2.3.0", - "npm-normalize-package-bin": "^1.0.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/npm/node_modules/read-package-json/node_modules/npm-normalize-package-bin": { - "version": "2.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/npm/node_modules/readable-stream": { - "version": "3.6.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/npm/node_modules/readdir-scoped-modules": { - "version": "1.1.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "debuglog": "^1.0.1", - "dezalgo": "^1.0.0", - "graceful-fs": "^4.1.2", - "once": "^1.3.0" - } - }, - "node_modules/npm/node_modules/retry": { - "version": "0.12.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">= 4" - } - }, - "node_modules/npm/node_modules/rimraf": { - "version": "3.0.2", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/npm/node_modules/rimraf/node_modules/brace-expansion": { - "version": "1.1.11", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/npm/node_modules/rimraf/node_modules/glob": { - "version": "7.2.3", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/npm/node_modules/rimraf/node_modules/minimatch": { - "version": "3.1.2", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/npm/node_modules/safe-buffer": { - "version": "5.2.1", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "inBundle": true, - "license": "MIT" - }, - "node_modules/npm/node_modules/safer-buffer": { - "version": "2.1.2", - "dev": true, - "inBundle": true, - "license": "MIT", - "optional": true - }, - "node_modules/npm/node_modules/semver": { - "version": "7.3.7", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/npm/node_modules/semver/node_modules/lru-cache": { - "version": "6.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/npm/node_modules/set-blocking": { - "version": "2.0.0", - "dev": true, - "inBundle": true, - "license": "ISC" - }, - "node_modules/npm/node_modules/signal-exit": { - "version": "3.0.7", - "dev": true, - "inBundle": true, - "license": "ISC" - }, - "node_modules/npm/node_modules/smart-buffer": { - "version": "4.2.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">= 6.0.0", - "npm": ">= 3.0.0" - } - }, - "node_modules/npm/node_modules/socks": { - "version": "2.7.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "ip": "^2.0.0", - "smart-buffer": "^4.2.0" - }, - "engines": { - "node": ">= 10.13.0", - "npm": ">= 3.0.0" - } - }, - "node_modules/npm/node_modules/socks-proxy-agent": { - "version": "7.0.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "agent-base": "^6.0.2", - "debug": "^4.3.3", - "socks": "^2.6.2" - }, - "engines": { - "node": ">= 10" - } - }, - "node_modules/npm/node_modules/spdx-correct": { - "version": "3.1.1", - "dev": true, - "inBundle": true, - "license": "Apache-2.0", - "dependencies": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" - } - }, - "node_modules/npm/node_modules/spdx-exceptions": { - "version": "2.3.0", - "dev": true, - "inBundle": true, - "license": "CC-BY-3.0" - }, - "node_modules/npm/node_modules/spdx-expression-parse": { - "version": "3.0.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" - } - }, - "node_modules/npm/node_modules/spdx-license-ids": { - "version": "3.0.11", - "dev": true, - "inBundle": true, - "license": "CC0-1.0" - }, - "node_modules/npm/node_modules/ssri": { - "version": "9.0.1", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "minipass": "^3.1.1" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/npm/node_modules/string_decoder": { - "version": "1.3.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "safe-buffer": "~5.2.0" - } - }, - "node_modules/npm/node_modules/string-width": { - "version": "4.2.3", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/npm/node_modules/strip-ansi": { - "version": "6.0.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/npm/node_modules/supports-color": { - "version": "7.2.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/npm/node_modules/tar": { - "version": "6.1.11", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "chownr": "^2.0.0", - "fs-minipass": "^2.0.0", - "minipass": "^3.0.0", - "minizlib": "^2.1.1", - "mkdirp": "^1.0.3", - "yallist": "^4.0.0" - }, - "engines": { - "node": ">= 10" - } - }, - "node_modules/npm/node_modules/text-table": { - "version": "0.2.0", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/npm/node_modules/tiny-relative-date": { - "version": "1.3.0", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/npm/node_modules/treeverse": { - "version": "2.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/npm/node_modules/unique-filename": { - "version": "2.0.1", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "unique-slug": "^3.0.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/npm/node_modules/unique-slug": { - "version": "3.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "imurmurhash": "^0.1.4" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/npm/node_modules/util-deprecate": { - "version": "1.0.2", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/npm/node_modules/validate-npm-package-license": { - "version": "3.0.4", - "dev": true, - "inBundle": true, - "license": "Apache-2.0", - "dependencies": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" - } - }, - "node_modules/npm/node_modules/validate-npm-package-name": { - "version": "4.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "builtins": "^5.0.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/npm/node_modules/walk-up-path": { - "version": "1.0.0", - "dev": true, - "inBundle": true, - "license": "ISC" - }, - "node_modules/npm/node_modules/wcwidth": { - "version": "1.0.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "defaults": "^1.0.3" - } - }, - "node_modules/npm/node_modules/which": { - "version": "2.0.2", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/npm/node_modules/wide-align": { - "version": "1.1.5", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "string-width": "^1.0.2 || 2 || 3 || 4" - } - }, - "node_modules/npm/node_modules/wrappy": { - "version": "1.0.2", - "dev": true, - "inBundle": true, - "license": "ISC" - }, - "node_modules/npm/node_modules/write-file-atomic": { - "version": "4.0.2", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "imurmurhash": "^0.1.4", - "signal-exit": "^3.0.7" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/npm/node_modules/yallist": { - "version": "4.0.0", - "dev": true, - "inBundle": true, - "license": "ISC" - }, - "node_modules/oauth-sign": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", - "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-copy": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", - "integrity": "sha512-79LYn6VAb63zgtmAteVOWo9Vdj71ZVBy3Pbse+VqxDpEP83XuujMrGqHIwAXJ5I/aM0zU7dIyIAhifVTPrNItQ==", - "dev": true, - "dependencies": { - "copy-descriptor": "^0.1.0", - "define-property": "^0.2.5", - "kind-of": "^3.0.3" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-copy/node_modules/define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", - "dev": true, - "dependencies": { - "is-descriptor": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-copy/node_modules/is-descriptor": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.7.tgz", - "integrity": "sha512-C3grZTvObeN1xud4cRWl366OMXZTj0+HGyk4hvfpx4ZHt1Pb60ANSXqCK7pdOTeUQpRzECBSTphqvD7U+l22Eg==", - "dev": true, - "dependencies": { - "is-accessor-descriptor": "^1.0.1", - "is-data-descriptor": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/object-copy/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-inspect": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", - "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", - "dev": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/object-visit": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", - "integrity": "sha512-GBaMwwAVK9qbQN3Scdo0OyvgPW7l3lnaVMj84uTOZlswkX0KpF6fyDBJhtTthf7pymztoN36/KEr1DyhF96zEA==", - "dev": true, - "dependencies": { - "isobject": "^3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object.assign": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz", - "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.5", - "define-properties": "^1.2.1", - "has-symbols": "^1.0.3", - "object-keys": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/object.pick": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", - "integrity": "sha512-tqa/UMy/CCoYmj+H5qc07qvSL9dqcs/WZENZ1JbtWBlATP+iVOe778gE6MSijnyCnORzDuX6hU+LA4SZ09YjFQ==", - "dev": true, - "dependencies": { - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dev": true, - "dependencies": { - "wrappy": "1" - } - }, - "node_modules/onetime": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", - "dev": true, - "dependencies": { - "mimic-fn": "^2.1.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/optionator": { - "version": "0.8.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", - "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", - "dev": true, - "dependencies": { - "deep-is": "~0.1.3", - "fast-levenshtein": "~2.0.6", - "levn": "~0.3.0", - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2", - "word-wrap": "~1.2.3" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/os-browserify": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", - "integrity": "sha512-gjcpUc3clBf9+210TRaDWbf+rZZZEshZ+DlXMRCeAjp0xhTrnQsKHypIy1J3d5hKdUzj69t708EHtU8P6bUn0A==", - "dev": true - }, - "node_modules/os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/p-each-series": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-each-series/-/p-each-series-2.2.0.tgz", - "integrity": "sha512-ycIL2+1V32th+8scbpTvyHNaHe02z0sjgh91XXjAk+ZeXoPN4Z46DVUnzdso0aX4KckKw0FNNFHdjZ2UsZvxiA==", - "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-filter": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/p-filter/-/p-filter-2.1.0.tgz", - "integrity": "sha512-ZBxxZ5sL2HghephhpGAQdoskxplTwr7ICaehZwLIlfL6acuVgZPm8yBNuRAFBGEqtD/hmUeq9eqLg2ys9Xr/yw==", - "dev": true, - "dependencies": { - "p-map": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/p-is-promise": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-3.0.0.tgz", - "integrity": "sha512-Wo8VsW4IRQSKVXsJCn7TomUaVtyfjVDn3nUP7kE967BQk0CwFpdbZs0X0uk5sW9mkBa9eNM7hCMaG93WUAwxYQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/p-limit": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", - "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", - "dev": true, - "dependencies": { - "p-try": "^1.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dev": true, - "dependencies": { - "p-limit": "^3.0.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-locate/node_modules/p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, - "dependencies": { - "yocto-queue": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-map": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz", - "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/p-reduce": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/p-reduce/-/p-reduce-2.1.0.tgz", - "integrity": "sha512-2USApvnsutq8uoxZBGbbWM0JIYLiEMJ9RlaN7fAzVNb9OZN0SHjjTTfIcb667XynS5Y1VhwDJVDa72TnPzAYWw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/p-try": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/pako": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", - "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", - "dev": true - }, - "node_modules/parallel-transform": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/parallel-transform/-/parallel-transform-1.2.0.tgz", - "integrity": "sha512-P2vSmIu38uIlvdcU7fDkyrxj33gTUy/ABO5ZUbGowxNCopBq/OoD42bP4UmMrJoPyk4Uqf0mu3mtWBhHCZD8yg==", - "dev": true, - "dependencies": { - "cyclist": "^1.0.1", - "inherits": "^2.0.3", - "readable-stream": "^2.1.5" - } - }, - "node_modules/parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, - "dependencies": { - "callsites": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/parse-asn1": { - "version": "5.1.7", - "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.7.tgz", - "integrity": "sha512-CTM5kuWR3sx9IFamcl5ErfPl6ea/N8IYwiJ+vpeB2g+1iknv7zBl5uPwbMbRVznRVbrNY6lGuDoE5b30grmbqg==", - "dev": true, - "dependencies": { - "asn1.js": "^4.10.1", - "browserify-aes": "^1.2.0", - "evp_bytestokey": "^1.0.3", - "hash-base": "~3.0", - "pbkdf2": "^3.1.2", - "safe-buffer": "^5.2.1" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/parse-asn1/node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/parse-json": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", - "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-even-better-errors": "^2.3.0", - "lines-and-columns": "^1.1.6" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/parse-passwd": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz", - "integrity": "sha512-1Y1A//QUXEZK7YKz+rD9WydcE1+EuPr6ZBgKecAB8tmoW6UFv0NREVJe1p+jRxtThkcbbKkfwIbWJe/IeE6m2Q==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/pascalcase": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", - "integrity": "sha512-XHXfu/yOQRy9vYOtUDVMN60OEJjW013GoObG1o+xwQTpB9eYJX/BjXMsdW13ZDPruFhYYn0AG22w0xgQMwl3Nw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/path-browserify": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.1.tgz", - "integrity": "sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==", - "dev": true - }, - "node_modules/path-dirname": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", - "integrity": "sha512-ALzNPpyNq9AqXMBjeymIjFDAkAFH06mHJH/cSBHAgU0s4vfpBn6b2nf8tiRLvagKD8RbTpq2FKTBg7cl9l3c7Q==", - "dev": true, - "optional": true - }, - "node_modules/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/path-is-inside": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", - "integrity": "sha512-DUWJr3+ULp4zXmol/SZkFf3JGsS9/SIv+Y3Rt93/UjPpDpklB5f1er4O3POIbUuUJ3FXgqte2Q7SrU6zAqwk8w==", - "dev": true - }, - "node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "dev": true - }, - "node_modules/path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/pause-stream": { - "version": "0.0.11", - "resolved": "https://registry.npmjs.org/pause-stream/-/pause-stream-0.0.11.tgz", - "integrity": "sha512-e3FBlXLmN/D1S+zHzanP4E/4Z60oFAa3O051qt1pxa7DEJWKAyil6upYVXCWadEnuoqa4Pkc9oUx9zsxYeRv8A==", - "dev": true, - "dependencies": { - "through": "~2.3" - } - }, - "node_modules/pbkdf2": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz", - "integrity": "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==", - "dev": true, - "dependencies": { - "create-hash": "^1.1.2", - "create-hmac": "^1.1.4", - "ripemd160": "^2.0.1", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - }, - "engines": { - "node": ">=0.12" - } - }, - "node_modules/performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==", - "dev": true - }, - "node_modules/picocolors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", - "dev": true - }, - "node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/pinkie": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/pinkie-promise": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha512-0Gni6D4UcLTbv9c57DfxDGdr41XfgUjqWZu492f0cIGr16zDU06BWP/RAEvOuo7CQ0CNjHaLlM59YJJFm3NWlw==", - "dev": true, - "dependencies": { - "pinkie": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/pkg-conf": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/pkg-conf/-/pkg-conf-2.1.0.tgz", - "integrity": "sha512-C+VUP+8jis7EsQZIhDYmS5qlNtjv2yP4SNtjXK9AP1ZcTRlnSfuumaTnRfYZnYgUUYVIKqL0fRvmUGDV2fmp6g==", - "dev": true, - "dependencies": { - "find-up": "^2.0.0", - "load-json-file": "^4.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/pkg-conf/node_modules/find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==", - "dev": true, - "dependencies": { - "locate-path": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/pkg-conf/node_modules/locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==", - "dev": true, - "dependencies": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/pkg-conf/node_modules/p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==", - "dev": true, - "dependencies": { - "p-limit": "^1.1.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/pkg-conf/node_modules/path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/pkg-dir": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", - "integrity": "sha512-ojakdnUgL5pzJYWw2AIDEupaQCX5OPbM688ZevubICjdIX01PRSYKqm33fJoCOJBRseYCTUlQRnBNX+Pchaejw==", - "dev": true, - "dependencies": { - "find-up": "^2.1.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/pkg-dir/node_modules/find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==", - "dev": true, - "dependencies": { - "locate-path": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/pkg-dir/node_modules/locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==", - "dev": true, - "dependencies": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/pkg-dir/node_modules/p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==", - "dev": true, - "dependencies": { - "p-limit": "^1.1.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/pkg-dir/node_modules/path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/pluralize": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-7.0.0.tgz", - "integrity": "sha512-ARhBOdzS3e41FbkW/XWrTEtukqqLoK5+Z/4UeDaLuSW+39JPeFgs4gCGqsrJHVZX0fUrx//4OF0K1CUGwlIFow==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/posix-character-classes": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", - "integrity": "sha512-xTgYBc3fuo7Yt7JbiuFxSYGToMoz8fLoE6TC9Wx1P/u+LfeThMOAqmuyECnlBaaJb+u1m9hHiXUEtwW4OzfUJg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/possible-typed-array-names": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", - "integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==", - "dev": true, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/prelude-ls": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==", - "dev": true, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/process": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", - "dev": true, - "engines": { - "node": ">= 0.6.0" - } - }, - "node_modules/process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true - }, - "node_modules/progress": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", - "dev": true, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/promise-inflight": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", - "integrity": "sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==", - "dev": true - }, - "node_modules/proto-list": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz", - "integrity": "sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==", - "dev": true - }, - "node_modules/prr": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", - "integrity": "sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==", - "dev": true - }, - "node_modules/pseudomap": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", - "integrity": "sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==", - "dev": true - }, - "node_modules/psl": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", - "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==", - "dev": true - }, - "node_modules/public-encrypt": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", - "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", - "dev": true, - "dependencies": { - "bn.js": "^4.1.0", - "browserify-rsa": "^4.0.0", - "create-hash": "^1.1.0", - "parse-asn1": "^5.0.0", - "randombytes": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "node_modules/public-encrypt/node_modules/bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true - }, - "node_modules/pump": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", - "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", - "dev": true, - "dependencies": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "node_modules/pumpify": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz", - "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==", - "dev": true, - "dependencies": { - "duplexify": "^3.6.0", - "inherits": "^2.0.3", - "pump": "^2.0.0" - } - }, - "node_modules/punycode": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", - "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/q": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/q/-/q-1.4.1.tgz", - "integrity": "sha512-/CdEdaw49VZVmyIDGUQKDDT53c7qBkO6g5CefWz91Ae+l4+cRtcDYwMTXh6me4O8TMldeGHG3N2Bl84V78Ywbg==", - "dev": true, - "engines": { - "node": ">=0.6.0", - "teleport": ">=0.2.0" - } - }, - "node_modules/q-io": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/q-io/-/q-io-1.13.2.tgz", - "integrity": "sha512-5PzgT/jVGwfwgpbN2KxjcaYdaWZyoTPeyQjM1toS5mLwlnRb5BxpnGTCQLUgMIs7b31MuIn14ZJd5pvQlvv8Xw==", - "dev": true, - "dependencies": { - "collections": "^0.2.0", - "mime": "^1.2.11", - "mimeparse": "^0.1.4", - "q": "^1.0.1", - "qs": "^1.2.1", - "url2": "^0.0.0" - }, - "engines": { - "node": ">=0.6.0" - } - }, - "node_modules/qs": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-1.2.2.tgz", - "integrity": "sha512-xEqT+49YIt+BdwQthXKTOkp7atENe6JqrGGerxBPiER6BArOIiVJtpZZYpWOpq2IOkTPVnDM8CgYvppFoJNwyQ==", - "dev": true - }, - "node_modules/querystring-es3": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", - "integrity": "sha512-773xhDQnZBMFobEiztv8LIl70ch5MSF/jUQVlhwFyBILqq96anmoctVIYz+ZRp0qbCKATTn6ev02M3r7Ga5vqA==", - "dev": true, - "engines": { - "node": ">=0.4.x" - } - }, - "node_modules/queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/quick-lru": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz", - "integrity": "sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "dev": true, - "dependencies": { - "safe-buffer": "^5.1.0" - } - }, - "node_modules/randomfill": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", - "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", - "dev": true, - "dependencies": { - "randombytes": "^2.0.5", - "safe-buffer": "^5.1.0" - } - }, - "node_modules/rc": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", - "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", - "dev": true, - "dependencies": { - "deep-extend": "^0.6.0", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" - }, - "bin": { - "rc": "cli.js" - } - }, - "node_modules/read-pkg": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", - "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", - "dev": true, - "dependencies": { - "@types/normalize-package-data": "^2.4.0", - "normalize-package-data": "^2.5.0", - "parse-json": "^5.0.0", - "type-fest": "^0.6.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/read-pkg-up": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", - "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", - "dev": true, - "dependencies": { - "find-up": "^4.1.0", - "read-pkg": "^5.2.0", - "type-fest": "^0.8.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/read-pkg-up/node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/read-pkg-up/node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "dependencies": { - "p-locate": "^4.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/read-pkg-up/node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/read-pkg-up/node_modules/p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "dependencies": { - "p-limit": "^2.2.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/read-pkg-up/node_modules/p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/read-pkg-up/node_modules/type-fest": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", - "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/read-pkg/node_modules/hosted-git-info": { - "version": "2.8.9", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", - "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", - "dev": true - }, - "node_modules/read-pkg/node_modules/normalize-package-data": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", - "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", - "dev": true, - "dependencies": { - "hosted-git-info": "^2.1.4", - "resolve": "^1.10.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" - } - }, - "node_modules/read-pkg/node_modules/semver": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", - "dev": true, - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/read-pkg/node_modules/type-fest": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", - "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/readable-stream": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", - "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", - "dev": true, - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "node_modules/readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dev": true, - "optional": true, - "dependencies": { - "picomatch": "^2.2.1" - }, - "engines": { - "node": ">=8.10.0" - } - }, - "node_modules/redent": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", - "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", - "dev": true, - "dependencies": { - "indent-string": "^4.0.0", - "strip-indent": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/redeyed": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/redeyed/-/redeyed-2.1.1.tgz", - "integrity": "sha512-FNpGGo1DycYAdnrKFxCMmKYgo/mILAqtRYbkdQD8Ep/Hk2PQ5+aEAEx+IU713RTDmuBaH0c8P5ZozurNu5ObRQ==", - "dev": true, - "dependencies": { - "esprima": "~4.0.0" - } - }, - "node_modules/regex-not": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", - "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", - "dev": true, - "dependencies": { - "extend-shallow": "^3.0.2", - "safe-regex": "^1.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/regexp.prototype.flags": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.2.tgz", - "integrity": "sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.6", - "define-properties": "^1.2.1", - "es-errors": "^1.3.0", - "set-function-name": "^2.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/regexpp": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-1.1.0.tgz", - "integrity": "sha512-LOPw8FpgdQF9etWMaAfG/WRthIdXJGYp4mJ2Jgn/2lpkbod9jPn0t9UqN7AxBOKNfzRbYyVfgc7Vk4t/MpnXgw==", - "dev": true, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/registry-auth-token": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-5.0.2.tgz", - "integrity": "sha512-o/3ikDxtXaA59BmZuZrJZDJv8NMDGSj+6j6XaeBmHw8eY1i1qd9+6H+LjVvQXx3HN6aRCGa1cUdJ9RaJZUugnQ==", - "dev": true, - "dependencies": { - "@pnpm/npm-conf": "^2.1.0" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/remove-trailing-separator": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", - "integrity": "sha512-/hS+Y0u3aOfIETiaiirUFwDBDzmXPvO+jAfKTitUngIPzdKc6Z0LoFjM/CK5PL4C+eKwHohlHAb6H0VFfmmUsw==", - "dev": true - }, - "node_modules/repeat-element": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.4.tgz", - "integrity": "sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/repeat-string": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==", - "dev": true, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/replace-ext": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-1.0.1.tgz", - "integrity": "sha512-yD5BHCe7quCgBph4rMQ+0KkIRKwWCrHDOX1p1Gp6HwjPM5kVoCdKGNhN7ydqqsX6lJEnQDKZ/tFMiEdQ1dvPEw==", - "dev": true, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/request": { - "version": "2.88.2", - "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", - "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", - "deprecated": "request has been deprecated, see https://github.com/request/request/issues/3142", - "dev": true, - "dependencies": { - "aws-sign2": "~0.7.0", - "aws4": "^1.8.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.6", - "extend": "~3.0.2", - "forever-agent": "~0.6.1", - "form-data": "~2.3.2", - "har-validator": "~5.1.3", - "http-signature": "~1.2.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.19", - "oauth-sign": "~0.9.0", - "performance-now": "^2.1.0", - "qs": "~6.5.2", - "safe-buffer": "^5.1.2", - "tough-cookie": "~2.5.0", - "tunnel-agent": "^0.6.0", - "uuid": "^3.3.2" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/request/node_modules/qs": { - "version": "6.5.3", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz", - "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==", - "dev": true, - "engines": { - "node": ">=0.6" - } - }, - "node_modules/require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/require-from-string": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", - "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/require-main-filename": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", - "dev": true - }, - "node_modules/require-uncached": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz", - "integrity": "sha512-Xct+41K3twrbBHdxAgMoOS+cNcoqIjfM2/VxBF4LL2hVph7YsF8VSKyQ3BDFZwEVbok9yeDl2le/qo0S77WG2w==", - "dev": true, - "dependencies": { - "caller-path": "^0.1.0", - "resolve-from": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/require-uncached/node_modules/resolve-from": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-1.0.1.tgz", - "integrity": "sha512-kT10v4dhrlLNcnO084hEjvXCI1wUG9qZLoz2RogxqDQQYy7IxjI/iMUkOtQTNEh6rzHxvdQWHsJyel1pKOVCxg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/resolve": { - "version": "1.22.8", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", - "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", - "dev": true, - "dependencies": { - "is-core-module": "^2.13.0", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - }, - "bin": { - "resolve": "bin/resolve" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/resolve-cwd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-2.0.0.tgz", - "integrity": "sha512-ccu8zQTrzVr954472aUVPLEcB3YpKSYR3cg/3lo1okzobPBM+1INXBbBZlDbnI/hbEocnf8j0QVo43hQKrbchg==", - "dev": true, - "dependencies": { - "resolve-from": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/resolve-cwd/node_modules/resolve-from": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", - "integrity": "sha512-GnlH6vxLymXJNMBo7XP1fJIzBFbdYt49CuTwmB/6N53t+kMPRMFKz783LlQ4tv28XoQfMWinAJX6WCGf2IlaIw==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/resolve-dir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz", - "integrity": "sha512-R7uiTjECzvOsWSfdM0QKFNBVFcK27aHOUwdvK53BcW8zqnGdYp0Fbj82cy54+2A4P2tFM22J5kRfe1R+lM/1yg==", - "dev": true, - "dependencies": { - "expand-tilde": "^2.0.0", - "global-modules": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/resolve-dir/node_modules/global-modules": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz", - "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==", - "dev": true, - "dependencies": { - "global-prefix": "^1.0.1", - "is-windows": "^1.0.1", - "resolve-dir": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/resolve-dir/node_modules/global-prefix": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz", - "integrity": "sha512-5lsx1NUDHtSjfg0eHlmYvZKv8/nVqX4ckFbM+FrGcQ+04KWcWFo9P5MxPZYSzUvyzmdTbI7Eix8Q4IbELDqzKg==", - "dev": true, - "dependencies": { - "expand-tilde": "^2.0.2", - "homedir-polyfill": "^1.0.1", - "ini": "^1.3.4", - "is-windows": "^1.0.1", - "which": "^1.2.14" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/resolve-global": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/resolve-global/-/resolve-global-1.0.0.tgz", - "integrity": "sha512-zFa12V4OLtT5XUX/Q4VLvTfBf+Ok0SPc1FNGM/z9ctUdiU618qwKpWnd0CHs3+RqROfyEg/DhuHbMWYqcgljEw==", - "dev": true, - "dependencies": { - "global-dirs": "^0.1.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/resolve-url": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", - "integrity": "sha512-ZuF55hVUQaaczgOIwqWzkEcEidmlD/xl44x1UZnhOXcYuFN2S6+rcxpG+C1N3So0wvNI3DmJICUFfu2SxhBmvg==", - "deprecated": "https://github.com/lydell/resolve-url#deprecated", - "dev": true - }, - "node_modules/restore-cursor": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", - "integrity": "sha512-6IzJLuGi4+R14vwagDHX+JrXmPVtPpn4mffDJ1UdR7/Edm87fl6yi8mMBIVvFtJaNTUvjughmW4hwLhRG7gC1Q==", - "dev": true, - "dependencies": { - "onetime": "^2.0.0", - "signal-exit": "^3.0.2" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/restore-cursor/node_modules/mimic-fn": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", - "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/restore-cursor/node_modules/onetime": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", - "integrity": "sha512-oyyPpiMaKARvvcgip+JV+7zci5L8D1W9RZIz2l1o08AM3pfspitVWnPt3mzHcBPp12oYMTy0pqrFs/C+m3EwsQ==", - "dev": true, - "dependencies": { - "mimic-fn": "^1.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/ret": { - "version": "0.1.15", - "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", - "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", - "dev": true, - "engines": { - "node": ">=0.12" - } - }, - "node_modules/reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "dev": true, - "engines": { - "iojs": ">=1.0.0", - "node": ">=0.10.0" - } - }, - "node_modules/rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - } - }, - "node_modules/ripemd160": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", - "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", - "dev": true, - "dependencies": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1" - } - }, - "node_modules/run-async": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", - "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==", - "dev": true, - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "queue-microtask": "^1.2.2" - } - }, - "node_modules/run-queue": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/run-queue/-/run-queue-1.0.3.tgz", - "integrity": "sha512-ntymy489o0/QQplUDnpYAYUsO50K9SBrIVaKCWDOJzYJts0f9WH9RFJkyagebkw5+y1oi00R7ynNW/d12GBumg==", - "dev": true, - "dependencies": { - "aproba": "^1.1.1" - } - }, - "node_modules/rx-lite": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-4.0.8.tgz", - "integrity": "sha512-Cun9QucwK6MIrp3mry/Y7hqD1oFqTYLQ4pGxaHTjIdaFDWRGGLikqp6u8LcWJnzpoALg9hap+JGk8sFIUuEGNA==", - "dev": true - }, - "node_modules/rx-lite-aggregates": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/rx-lite-aggregates/-/rx-lite-aggregates-4.0.8.tgz", - "integrity": "sha512-3xPNZGW93oCjiO7PtKxRK6iOVYBWBvtf9QHDfU23Oc+dLIQmAV//UnyXV/yihv81VS/UqoQPk4NegS8EFi55Hg==", - "dev": true, - "dependencies": { - "rx-lite": "*" - } - }, - "node_modules/safe-array-concat": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.2.tgz", - "integrity": "sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.7", - "get-intrinsic": "^1.2.4", - "has-symbols": "^1.0.3", - "isarray": "^2.0.5" - }, - "engines": { - "node": ">=0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/safe-array-concat/node_modules/isarray": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", - "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", - "dev": true - }, - "node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "node_modules/safe-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", - "integrity": "sha512-aJXcif4xnaNUzvUuC5gcb46oTS7zvg4jpMTnuqtrEPlR3vFr4pxtdTwaF1Qs3Enjn9HK+ZlwQui+a7z0SywIzg==", - "dev": true, - "dependencies": { - "ret": "~0.1.10" - } - }, - "node_modules/safe-regex-test": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.3.tgz", - "integrity": "sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.6", - "es-errors": "^1.3.0", - "is-regex": "^1.1.4" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true - }, - "node_modules/schema-utils": { - "version": "0.4.7", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-0.4.7.tgz", - "integrity": "sha512-v/iwU6wvwGK8HbU9yi3/nhGzP0yGSuhQMzL6ySiec1FSrZZDkhm4noOSWzrNFo/jEc+SJY6jRTwuwbSXJPDUnQ==", - "dev": true, - "dependencies": { - "ajv": "^6.1.0", - "ajv-keywords": "^3.1.0" - }, - "engines": { - "node": ">= 4" - } - }, - "node_modules/schema-utils/node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/schema-utils/node_modules/ajv-keywords": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", - "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", - "dev": true, - "peerDependencies": { - "ajv": "^6.9.1" - } - }, - "node_modules/schema-utils/node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true - }, - "node_modules/scratch-l10n": { - "version": "3.18.106", - "resolved": "https://registry.npmjs.org/scratch-l10n/-/scratch-l10n-3.18.106.tgz", - "integrity": "sha512-PFhA01EYenlHV0NqYscmb0EunzoBelwwTF+Wpa9nIkd1TycI9DnG5j8ZqmTZKl1ewFn45GY8SRIEvrWeWJJABA==", - "bin": { - "build-i18n-src": "scripts/build-i18n-src.js", - "tx-push-src": "scripts/tx-push-src.js" - } - }, - "node_modules/scratch-semantic-release-config": { - "version": "1.0.14", - "resolved": "https://registry.npmjs.org/scratch-semantic-release-config/-/scratch-semantic-release-config-1.0.14.tgz", - "integrity": "sha512-lEPnAsP614FBcxMrBSrCDxuAdvYlUAGthiiTpqm3rhNBCuPTvVbrNo22yXWVXY3+ZtlrSNfkVKBtBKagDlexJw==", - "dev": true, - "dependencies": { - "@semantic-release/changelog": "^6.0.1", - "@semantic-release/commit-analyzer": "^9.0.2", - "@semantic-release/git": "^10.0.1", - "@semantic-release/github": "^8.0.4", - "@semantic-release/npm": "^9.0.1", - "@semantic-release/release-notes-generator": "^10.0.3" - }, - "peerDependencies": { - "semantic-release": ">=19.0.2" - } - }, - "node_modules/selenium-webdriver": { - "version": "4.16.0", - "resolved": "https://registry.npmjs.org/selenium-webdriver/-/selenium-webdriver-4.16.0.tgz", - "integrity": "sha512-IbqpRpfGE7JDGgXHJeWuCqT/tUqnLvZ14csSwt+S8o4nJo3RtQoE9VR4jB47tP/A8ArkYsh/THuMY6kyRP6kuA==", - "dev": true, - "dependencies": { - "jszip": "^3.10.1", - "tmp": "^0.2.1", - "ws": ">=8.14.2" - }, - "engines": { - "node": ">= 14.20.0" - } - }, - "node_modules/selenium-webdriver/node_modules/tmp": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.3.tgz", - "integrity": "sha512-nZD7m9iCPC5g0pYmcaxogYKggSfLsdxl8of3Q/oIbqCqLLIO9IAF0GWjX1z9NZRHPiXv8Wex4yDCaZsgEw0Y8w==", - "dev": true, - "engines": { - "node": ">=14.14" - } - }, - "node_modules/semantic-release": { - "version": "19.0.5", - "resolved": "https://registry.npmjs.org/semantic-release/-/semantic-release-19.0.5.tgz", - "integrity": "sha512-NMPKdfpXTnPn49FDogMBi36SiBfXkSOJqCkk0E4iWOY1tusvvgBwqUmxTX1kmlT6kIYed9YwNKD1sfPpqa5yaA==", - "dev": true, - "dependencies": { - "@semantic-release/commit-analyzer": "^9.0.2", - "@semantic-release/error": "^3.0.0", - "@semantic-release/github": "^8.0.0", - "@semantic-release/npm": "^9.0.0", - "@semantic-release/release-notes-generator": "^10.0.0", - "aggregate-error": "^3.0.0", - "cosmiconfig": "^7.0.0", - "debug": "^4.0.0", - "env-ci": "^5.0.0", - "execa": "^5.0.0", - "figures": "^3.0.0", - "find-versions": "^4.0.0", - "get-stream": "^6.0.0", - "git-log-parser": "^1.2.0", - "hook-std": "^2.0.0", - "hosted-git-info": "^4.0.0", - "lodash": "^4.17.21", - "marked": "^4.0.10", - "marked-terminal": "^5.0.0", - "micromatch": "^4.0.2", - "p-each-series": "^2.1.0", - "p-reduce": "^2.0.0", - "read-pkg-up": "^7.0.0", - "resolve-from": "^5.0.0", - "semver": "^7.3.2", - "semver-diff": "^3.1.1", - "signale": "^1.2.1", - "yargs": "^16.2.0" - }, - "bin": { - "semantic-release": "bin/semantic-release.js" - }, - "engines": { - "node": ">=16 || ^14.17" - } - }, - "node_modules/semantic-release/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/semantic-release/node_modules/cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "dev": true, - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" - } - }, - "node_modules/semantic-release/node_modules/cosmiconfig": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", - "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", - "dev": true, - "dependencies": { - "@types/parse-json": "^4.0.0", - "import-fresh": "^3.2.1", - "parse-json": "^5.0.0", - "path-type": "^4.0.0", - "yaml": "^1.10.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/semantic-release/node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/semantic-release/node_modules/figures": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", - "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", - "dev": true, - "dependencies": { - "escape-string-regexp": "^1.0.5" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/semantic-release/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/semantic-release/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "node_modules/semantic-release/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/semantic-release/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/semantic-release/node_modules/y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/semantic-release/node_modules/yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "dev": true, - "dependencies": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.0", - "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", - "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/semver-diff": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-3.1.1.tgz", - "integrity": "sha512-GX0Ix/CJcHyB8c4ykpHGIAvLyOwOobtM/8d+TQkAd81/bEjgPHrfba41Vpesr7jX/t8Uh+R3EX9eAS5be+jQYg==", - "dev": true, - "dependencies": { - "semver": "^6.3.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/semver-diff/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/semver-regex": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/semver-regex/-/semver-regex-3.1.4.tgz", - "integrity": "sha512-6IiqeZNgq01qGf0TId0t3NvKzSvUsjcpdEO3AQNeIjR6A2+ckTnQlDpl4qu1bjRv0RzN3FP9hzFmws3lKqRWkA==", - "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/semver/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/semver/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, - "node_modules/serialize-javascript": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-1.9.1.tgz", - "integrity": "sha512-0Vb/54WJ6k5v8sSWN09S0ora+Hnr+cX40r9F170nT+mSkaxltoE/7R3OrIdBSUv1OoiobH1QoWQbCnAO+e8J1A==", - "dev": true - }, - "node_modules/set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", - "dev": true - }, - "node_modules/set-function-length": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", - "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", - "dev": true, - "dependencies": { - "define-data-property": "^1.1.4", - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.4", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/set-function-name": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", - "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", - "dev": true, - "dependencies": { - "define-data-property": "^1.1.4", - "es-errors": "^1.3.0", - "functions-have-names": "^1.2.3", - "has-property-descriptors": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/set-value": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", - "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", - "dev": true, - "dependencies": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.3", - "split-string": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/set-value/node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", - "dev": true, - "dependencies": { - "is-extendable": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/set-value/node_modules/is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/set-value/node_modules/is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "dependencies": { - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/setimmediate": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==", - "dev": true - }, - "node_modules/sha.js": { - "version": "2.4.11", - "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", - "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", - "dev": true, - "dependencies": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - }, - "bin": { - "sha.js": "bin.js" - } - }, - "node_modules/shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==", - "dev": true, - "dependencies": { - "shebang-regex": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/should": { - "version": "13.2.3", - "resolved": "https://registry.npmjs.org/should/-/should-13.2.3.tgz", - "integrity": "sha512-ggLesLtu2xp+ZxI+ysJTmNjh2U0TsC+rQ/pfED9bUZZ4DKefP27D+7YJVVTvKsmjLpIi9jAa7itwDGkDDmt1GQ==", - "dev": true, - "dependencies": { - "should-equal": "^2.0.0", - "should-format": "^3.0.3", - "should-type": "^1.4.0", - "should-type-adaptors": "^1.0.1", - "should-util": "^1.0.0" - } - }, - "node_modules/should-equal": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/should-equal/-/should-equal-2.0.0.tgz", - "integrity": "sha512-ZP36TMrK9euEuWQYBig9W55WPC7uo37qzAEmbjHz4gfyuXrEUgF8cUvQVO+w+d3OMfPvSRQJ22lSm8MQJ43LTA==", - "dev": true, - "dependencies": { - "should-type": "^1.4.0" - } - }, - "node_modules/should-format": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/should-format/-/should-format-3.0.3.tgz", - "integrity": "sha512-hZ58adtulAk0gKtua7QxevgUaXTTXxIi8t41L3zo9AHvjXO1/7sdLECuHeIN2SRtYXpNkmhoUP2pdeWgricQ+Q==", - "dev": true, - "dependencies": { - "should-type": "^1.3.0", - "should-type-adaptors": "^1.0.1" - } - }, - "node_modules/should-type": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/should-type/-/should-type-1.4.0.tgz", - "integrity": "sha512-MdAsTu3n25yDbIe1NeN69G4n6mUnJGtSJHygX3+oN0ZbO3DTiATnf7XnYJdGT42JCXurTb1JI0qOBR65shvhPQ==", - "dev": true - }, - "node_modules/should-type-adaptors": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/should-type-adaptors/-/should-type-adaptors-1.1.0.tgz", - "integrity": "sha512-JA4hdoLnN+kebEp2Vs8eBe9g7uy0zbRo+RMcU0EsNy+R+k049Ki+N5tT5Jagst2g7EAja+euFuoXFCa8vIklfA==", - "dev": true, - "dependencies": { - "should-type": "^1.3.0", - "should-util": "^1.0.0" - } - }, - "node_modules/should-util": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/should-util/-/should-util-1.0.1.tgz", - "integrity": "sha512-oXF8tfxx5cDk8r2kYqlkUJzZpDBqVY/II2WhvU0n9Y3XYvAYRmeaf1PvvIvTgPnv4KJ+ES5M0PyDq5Jp+Ygy2g==", - "dev": true - }, - "node_modules/side-channel": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", - "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.7", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.4", - "object-inspect": "^1.13.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "dev": true - }, - "node_modules/signale": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/signale/-/signale-1.4.0.tgz", - "integrity": "sha512-iuh+gPf28RkltuJC7W5MRi6XAjTDCAPC/prJUpQoG4vIP3MJZ+GTydVnodXA7pwvTKb2cA0m9OFZW/cdWy/I/w==", - "dev": true, - "dependencies": { - "chalk": "^2.3.2", - "figures": "^2.0.0", - "pkg-conf": "^2.1.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/signale/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/signale/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/signale/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/signale/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "node_modules/signale/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/signale/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/slash": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz", - "integrity": "sha512-3TYDR7xWt4dIqV2JauJr+EJeW356RXijHeUlO+8djJ+uBXPn8/2dpzBc8yQhh583sVvc9CvFAeQVgijsH+PNNg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/slice-ansi": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-1.0.0.tgz", - "integrity": "sha512-POqxBK6Lb3q6s047D/XsDVNPnF9Dl8JSaqe9h9lURl0OdNqy/ujDrOiIHtsqXMGbWWTIomRzAMaTyawAU//Reg==", - "dev": true, - "dependencies": { - "is-fullwidth-code-point": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/snapdragon": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", - "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", - "dev": true, - "dependencies": { - "base": "^0.11.1", - "debug": "^2.2.0", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "map-cache": "^0.2.2", - "source-map": "^0.5.6", - "source-map-resolve": "^0.5.0", - "use": "^3.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon-node": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", - "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", - "dev": true, - "dependencies": { - "define-property": "^1.0.0", - "isobject": "^3.0.0", - "snapdragon-util": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon-node/node_modules/define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==", - "dev": true, - "dependencies": { - "is-descriptor": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon-util": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", - "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", - "dev": true, - "dependencies": { - "kind-of": "^3.2.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon-util/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/snapdragon/node_modules/define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", - "dev": true, - "dependencies": { - "is-descriptor": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon/node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", - "dev": true, - "dependencies": { - "is-extendable": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon/node_modules/is-descriptor": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.7.tgz", - "integrity": "sha512-C3grZTvObeN1xud4cRWl366OMXZTj0+HGyk4hvfpx4ZHt1Pb60ANSXqCK7pdOTeUQpRzECBSTphqvD7U+l22Eg==", - "dev": true, - "dependencies": { - "is-accessor-descriptor": "^1.0.1", - "is-data-descriptor": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/snapdragon/node_modules/is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true - }, - "node_modules/snapdragon/node_modules/source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/source-list-map": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", - "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==", - "dev": true - }, - "node_modules/source-map": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.0.tgz", - "integrity": "sha512-gjGnxNN0K+/Pr4Mi4fs/pOtda10dKB6Wn9QvjOrH6v5TWsI7ghHuJUHoIgyM6DkUL5kr2GtPFGererzKpMBWfA==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/source-map-resolve": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", - "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", - "deprecated": "See https://github.com/lydell/source-map-resolve#deprecated", - "dev": true, - "dependencies": { - "atob": "^2.1.2", - "decode-uri-component": "^0.2.0", - "resolve-url": "^0.2.1", - "source-map-url": "^0.4.0", - "urix": "^0.1.0" - } - }, - "node_modules/source-map-support": { - "version": "0.5.21", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", - "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", - "dev": true, - "dependencies": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "node_modules/source-map-support/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/source-map-url": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.1.tgz", - "integrity": "sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==", - "deprecated": "See https://github.com/lydell/source-map-url#deprecated", - "dev": true - }, - "node_modules/spawn-error-forwarder": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/spawn-error-forwarder/-/spawn-error-forwarder-1.0.0.tgz", - "integrity": "sha512-gRjMgK5uFjbCvdibeGJuy3I5OYz6VLoVdsOJdA6wV0WlfQVLFueoqMxwwYD9RODdgb6oUIvlRlsyFSiQkMKu0g==", - "dev": true - }, - "node_modules/spdx-correct": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", - "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", - "dev": true, - "dependencies": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" - } - }, - "node_modules/spdx-exceptions": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz", - "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==", - "dev": true - }, - "node_modules/spdx-expression-parse": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", - "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", - "dev": true, - "dependencies": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" - } - }, - "node_modules/spdx-license-ids": { - "version": "3.0.17", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.17.tgz", - "integrity": "sha512-sh8PWc/ftMqAAdFiBu6Fy6JUOYjqDJBJvIhpfDMyHrr0Rbp5liZqd4TjtQ/RgfLjKFZb+LMx5hpml5qOWy0qvg==", - "dev": true - }, - "node_modules/split": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz", - "integrity": "sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==", - "dev": true, - "dependencies": { - "through": "2" - }, - "engines": { - "node": "*" - } - }, - "node_modules/split-string": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", - "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", - "dev": true, - "dependencies": { - "extend-shallow": "^3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/split2": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/split2/-/split2-3.2.2.tgz", - "integrity": "sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg==", - "dev": true, - "dependencies": { - "readable-stream": "^3.0.0" - } - }, - "node_modules/split2/node_modules/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "dev": true, - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", - "dev": true - }, - "node_modules/sshpk": { - "version": "1.18.0", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.18.0.tgz", - "integrity": "sha512-2p2KJZTSqQ/I3+HX42EpYOa2l3f8Erv8MWKsy2I9uf4wA7yFIkXRffYdsx86y6z4vHtV8u7g+pPlr8/4ouAxsQ==", - "dev": true, - "dependencies": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "safer-buffer": "^2.0.2", - "tweetnacl": "~0.14.0" - }, - "bin": { - "sshpk-conv": "bin/sshpk-conv", - "sshpk-sign": "bin/sshpk-sign", - "sshpk-verify": "bin/sshpk-verify" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ssri": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-5.3.0.tgz", - "integrity": "sha512-XRSIPqLij52MtgoQavH/x/dU1qVKtWUAAZeOHsR9c2Ddi4XerFy3mc1alf+dLJKl9EUIm/Ht+EowFkTUOA6GAQ==", - "dev": true, - "dependencies": { - "safe-buffer": "^5.1.1" - } - }, - "node_modules/static-extend": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", - "integrity": "sha512-72E9+uLc27Mt718pMHt9VMNiAL4LMsmDbBva8mxWUCkT07fSzEGMYUCk0XWY6lp0j6RBAG4cJ3mWuZv2OE3s0g==", - "dev": true, - "dependencies": { - "define-property": "^0.2.5", - "object-copy": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/static-extend/node_modules/define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", - "dev": true, - "dependencies": { - "is-descriptor": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/static-extend/node_modules/is-descriptor": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.7.tgz", - "integrity": "sha512-C3grZTvObeN1xud4cRWl366OMXZTj0+HGyk4hvfpx4ZHt1Pb60ANSXqCK7pdOTeUQpRzECBSTphqvD7U+l22Eg==", - "dev": true, - "dependencies": { - "is-accessor-descriptor": "^1.0.1", - "is-data-descriptor": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/stream-browserify": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz", - "integrity": "sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg==", - "dev": true, - "dependencies": { - "inherits": "~2.0.1", - "readable-stream": "^2.0.2" - } - }, - "node_modules/stream-combiner": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/stream-combiner/-/stream-combiner-0.2.2.tgz", - "integrity": "sha512-6yHMqgLYDzQDcAkL+tjJDC5nSNuNIx0vZtRZeiPh7Saef7VHX9H5Ijn9l2VIol2zaNYlYEX6KyuT/237A58qEQ==", - "dev": true, - "dependencies": { - "duplexer": "~0.1.1", - "through": "~2.3.4" - } - }, - "node_modules/stream-combiner2": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/stream-combiner2/-/stream-combiner2-1.1.1.tgz", - "integrity": "sha512-3PnJbYgS56AeWgtKF5jtJRT6uFJe56Z0Hc5Ngg/6sI6rIt8iiMBTa9cvdyFfpMQjaVHr8dusbNeFGIIonxOvKw==", - "dev": true, - "dependencies": { - "duplexer2": "~0.1.0", - "readable-stream": "^2.0.2" - } - }, - "node_modules/stream-each": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/stream-each/-/stream-each-1.2.3.tgz", - "integrity": "sha512-vlMC2f8I2u/bZGqkdfLQW/13Zihpej/7PmSiMQsbYddxuTsJp8vRe2x2FvVExZg7FaOds43ROAuFJwPR4MTZLw==", - "dev": true, - "dependencies": { - "end-of-stream": "^1.1.0", - "stream-shift": "^1.0.0" - } - }, - "node_modules/stream-http": { - "version": "2.8.3", - "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.3.tgz", - "integrity": "sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==", - "dev": true, - "dependencies": { - "builtin-status-codes": "^3.0.0", - "inherits": "^2.0.1", - "readable-stream": "^2.3.6", - "to-arraybuffer": "^1.0.0", - "xtend": "^4.0.0" - } - }, - "node_modules/stream-shift": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.3.tgz", - "integrity": "sha512-76ORR0DO1o1hlKwTbi/DM3EXWGf3ZJYO8cXX5RJwnul2DEg2oyoZyjLNoQM8WsvZiFKCRfC1O0J7iCvie3RZmQ==", - "dev": true - }, - "node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, - "node_modules/string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "dependencies": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/string.prototype.trim": { - "version": "1.2.9", - "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.9.tgz", - "integrity": "sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.0", - "es-object-atoms": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/string.prototype.trimend": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.8.tgz", - "integrity": "sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-object-atoms": "^1.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/string.prototype.trimstart": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", - "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-object-atoms": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==", - "dev": true, - "dependencies": { - "ansi-regex": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/strip-final-newline": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", - "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/strip-indent": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", - "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", - "dev": true, - "dependencies": { - "min-indent": "^1.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/supports-hyperlinks": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.3.0.tgz", - "integrity": "sha512-RpsAZlpWcDwOPQA22aCH4J0t7L8JmAvsCxfOSEwm7cQs3LshN36QaTkwd70DnBOXDWGssw2eUoc8CaRWT0XunA==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0", - "supports-color": "^7.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/supports-preserve-symlinks-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", - "dev": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/table": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/table/-/table-4.0.2.tgz", - "integrity": "sha512-UUkEAPdSGxtRpiV9ozJ5cMTtYiqz7Ni1OGqLXRCynrvzdtR1p+cfOWe2RJLwvUG8hNanaSRjecIqwOjqeatDsA==", - "dev": true, - "dependencies": { - "ajv": "^5.2.3", - "ajv-keywords": "^2.1.0", - "chalk": "^2.1.0", - "lodash": "^4.17.4", - "slice-ansi": "1.0.0", - "string-width": "^2.1.1" - } - }, - "node_modules/table/node_modules/ajv": { - "version": "5.5.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz", - "integrity": "sha512-Ajr4IcMXq/2QmMkEmSvxqfLN5zGmJ92gHXAeOXq1OekoH2rfDNsgdDoL2f7QaRCy7G/E6TpxBVdRuNraMztGHw==", - "dev": true, - "dependencies": { - "co": "^4.6.0", - "fast-deep-equal": "^1.0.0", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.3.0" - } - }, - "node_modules/table/node_modules/ajv-keywords": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-2.1.1.tgz", - "integrity": "sha512-ZFztHzVRdGLAzJmpUT9LNFLe1YiVOEylcaNpEutM26PVTCtOD919IMfD01CgbRouB42Dd9atjx1HseC15DgOZA==", - "dev": true, - "peerDependencies": { - "ajv": "^5.0.0" - } - }, - "node_modules/table/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/table/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/table/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/table/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "node_modules/table/node_modules/fast-deep-equal": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz", - "integrity": "sha512-fueX787WZKCV0Is4/T2cyAdM4+x1S3MXXOAhavE1ys/W42SHAPacLTQhucja22QBYrfGw50M2sRiXPtTGv9Ymw==", - "dev": true - }, - "node_modules/table/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/table/node_modules/json-schema-traverse": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz", - "integrity": "sha512-4JD/Ivzg7PoW8NzdrBSr3UFwC9mHgvI7Z6z3QGBsSHgKaRTUDmyZAAKJo2UbG1kUVfS9WS8bi36N49U1xw43DA==", - "dev": true - }, - "node_modules/table/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/tapable": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz", - "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/temp-dir": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/temp-dir/-/temp-dir-2.0.0.tgz", - "integrity": "sha512-aoBAniQmmwtcKp/7BzsH8Cxzv8OL736p7v1ihGb5e9DJ9kTwGWHrQrVB5+lfVDzfGrdRzXch+ig7LHaY1JTOrg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/tempy": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/tempy/-/tempy-1.0.1.tgz", - "integrity": "sha512-biM9brNqxSc04Ee71hzFbryD11nX7VPhQQY32AdDmjFvodsRFz/3ufeoTZ6uYkRFfGo188tENcASNs3vTdsM0w==", - "dev": true, - "dependencies": { - "del": "^6.0.0", - "is-stream": "^2.0.0", - "temp-dir": "^2.0.0", - "type-fest": "^0.16.0", - "unique-string": "^2.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/tempy/node_modules/type-fest": { - "version": "0.16.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.16.0.tgz", - "integrity": "sha512-eaBzG6MxNzEn9kiwvtre90cXaNLkmadMWa1zQMs3XORCXNbsH/OewwbxC5ia9dCxIxnTAsSxXJaa/p5y8DlvJg==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/terser": { - "version": "4.8.1", - "resolved": "https://registry.npmjs.org/terser/-/terser-4.8.1.tgz", - "integrity": "sha512-4GnLC0x667eJG0ewJTa6z/yXrbLGv80D9Ru6HIpCQmO+Q4PfEtBFi0ObSckqwL6VyQv/7ENJieXHo2ANmdQwgw==", - "dev": true, - "dependencies": { - "commander": "^2.20.0", - "source-map": "~0.6.1", - "source-map-support": "~0.5.12" - }, - "bin": { - "terser": "bin/terser" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/terser-webpack-plugin": { - "version": "1.4.5", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.4.5.tgz", - "integrity": "sha512-04Rfe496lN8EYruwi6oPQkG0vo8C+HT49X687FZnpPF0qMAIHONI6HEXYPKDOE8e5HjXTyKfqRd/agHtH0kOtw==", - "dev": true, - "dependencies": { - "cacache": "^12.0.2", - "find-cache-dir": "^2.1.0", - "is-wsl": "^1.1.0", - "schema-utils": "^1.0.0", - "serialize-javascript": "^4.0.0", - "source-map": "^0.6.1", - "terser": "^4.1.2", - "webpack-sources": "^1.4.0", - "worker-farm": "^1.7.0" - }, - "engines": { - "node": ">= 6.9.0" - }, - "peerDependencies": { - "webpack": "^4.0.0" - } - }, - "node_modules/terser-webpack-plugin/node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/terser-webpack-plugin/node_modules/ajv-keywords": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", - "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", - "dev": true, - "peerDependencies": { - "ajv": "^6.9.1" - } - }, - "node_modules/terser-webpack-plugin/node_modules/cacache": { - "version": "12.0.4", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-12.0.4.tgz", - "integrity": "sha512-a0tMB40oefvuInr4Cwb3GerbL9xTj1D5yg0T5xrjGCGyfvbxseIXX7BAO/u/hIXdafzOI5JC3wDwHyf24buOAQ==", - "dev": true, - "dependencies": { - "bluebird": "^3.5.5", - "chownr": "^1.1.1", - "figgy-pudding": "^3.5.1", - "glob": "^7.1.4", - "graceful-fs": "^4.1.15", - "infer-owner": "^1.0.3", - "lru-cache": "^5.1.1", - "mississippi": "^3.0.0", - "mkdirp": "^0.5.1", - "move-concurrently": "^1.0.1", - "promise-inflight": "^1.0.1", - "rimraf": "^2.6.3", - "ssri": "^6.0.1", - "unique-filename": "^1.1.1", - "y18n": "^4.0.0" - } - }, - "node_modules/terser-webpack-plugin/node_modules/find-cache-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", - "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", - "dev": true, - "dependencies": { - "commondir": "^1.0.1", - "make-dir": "^2.0.0", - "pkg-dir": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/terser-webpack-plugin/node_modules/find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, - "dependencies": { - "locate-path": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/terser-webpack-plugin/node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true - }, - "node_modules/terser-webpack-plugin/node_modules/locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dev": true, - "dependencies": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/terser-webpack-plugin/node_modules/lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "dev": true, - "dependencies": { - "yallist": "^3.0.2" - } - }, - "node_modules/terser-webpack-plugin/node_modules/make-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", - "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", - "dev": true, - "dependencies": { - "pify": "^4.0.1", - "semver": "^5.6.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/terser-webpack-plugin/node_modules/mississippi": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/mississippi/-/mississippi-3.0.0.tgz", - "integrity": "sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA==", - "dev": true, - "dependencies": { - "concat-stream": "^1.5.0", - "duplexify": "^3.4.2", - "end-of-stream": "^1.1.0", - "flush-write-stream": "^1.0.0", - "from2": "^2.1.0", - "parallel-transform": "^1.1.0", - "pump": "^3.0.0", - "pumpify": "^1.3.3", - "stream-each": "^1.1.0", - "through2": "^2.0.0" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/terser-webpack-plugin/node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/terser-webpack-plugin/node_modules/p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dev": true, - "dependencies": { - "p-limit": "^2.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/terser-webpack-plugin/node_modules/p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/terser-webpack-plugin/node_modules/path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/terser-webpack-plugin/node_modules/pify": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/terser-webpack-plugin/node_modules/pkg-dir": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", - "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", - "dev": true, - "dependencies": { - "find-up": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/terser-webpack-plugin/node_modules/pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "dev": true, - "dependencies": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "node_modules/terser-webpack-plugin/node_modules/schema-utils": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", - "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", - "dev": true, - "dependencies": { - "ajv": "^6.1.0", - "ajv-errors": "^1.0.0", - "ajv-keywords": "^3.1.0" - }, - "engines": { - "node": ">= 4" - } - }, - "node_modules/terser-webpack-plugin/node_modules/semver": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", - "dev": true, - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/terser-webpack-plugin/node_modules/serialize-javascript": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-4.0.0.tgz", - "integrity": "sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw==", - "dev": true, - "dependencies": { - "randombytes": "^2.1.0" - } - }, - "node_modules/terser-webpack-plugin/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/terser-webpack-plugin/node_modules/ssri": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.2.tgz", - "integrity": "sha512-cepbSq/neFK7xB6A50KHN0xHDotYzq58wWCa5LeWqnPrHG8GzfEjO/4O8kpmcGW+oaxkvhEJCWgbgNk4/ZV93Q==", - "dev": true, - "dependencies": { - "figgy-pudding": "^3.5.1" - } - }, - "node_modules/terser-webpack-plugin/node_modules/through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "dependencies": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - }, - "node_modules/terser-webpack-plugin/node_modules/yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true - }, - "node_modules/terser/node_modules/commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true - }, - "node_modules/terser/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/text-extensions": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/text-extensions/-/text-extensions-1.9.0.tgz", - "integrity": "sha512-wiBrwC1EhBelW12Zy26JeOUkQ5mRu+5o8rpsJk5+2t+Y5vE7e842qtZDQ2g1NpX/29HdyFeJ4nSIhI47ENSxlQ==", - "dev": true, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", - "dev": true - }, - "node_modules/through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", - "dev": true - }, - "node_modules/through2": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/through2/-/through2-4.0.2.tgz", - "integrity": "sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==", - "dev": true, - "dependencies": { - "readable-stream": "3" - } - }, - "node_modules/through2/node_modules/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "dev": true, - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/timers-browserify": { - "version": "2.0.12", - "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.12.tgz", - "integrity": "sha512-9phl76Cqm6FhSX9Xe1ZUAMLtm1BLkKj2Qd5ApyWkXzsMRaA7dgr81kf4wJmQf/hAvg8EEyJxDo3du/0KlhPiKQ==", - "dev": true, - "dependencies": { - "setimmediate": "^1.0.4" - }, - "engines": { - "node": ">=0.6.0" - } - }, - "node_modules/tmp": { - "version": "0.0.33", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", - "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", - "dev": true, - "dependencies": { - "os-tmpdir": "~1.0.2" - }, - "engines": { - "node": ">=0.6.0" - } - }, - "node_modules/to-arraybuffer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", - "integrity": "sha512-okFlQcoGTi4LQBG/PgSYblw9VOyptsz2KJZqc6qtgGdes8VktzUQkj4BI2blit072iS8VODNcMA+tvnS9dnuMA==", - "dev": true - }, - "node_modules/to-object-path": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", - "integrity": "sha512-9mWHdnGRuh3onocaHzukyvCZhzvr6tiflAy/JRFXcJX0TjgfWA9pk9t8CMbzmBE4Jfw58pXbkngtBtqYxzNEyg==", - "dev": true, - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/to-object-path/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/to-regex": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", - "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", - "dev": true, - "dependencies": { - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "regex-not": "^1.0.2", - "safe-regex": "^1.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "dependencies": { - "is-number": "^7.0.0" - }, - "engines": { - "node": ">=8.0" - } - }, - "node_modules/tough-cookie": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", - "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", - "dev": true, - "dependencies": { - "psl": "^1.1.28", - "punycode": "^2.1.1" - }, - "engines": { - "node": ">=0.8" - } - }, - "node_modules/tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", - "dev": true - }, - "node_modules/transifex": { - "version": "1.6.6", - "resolved": "https://registry.npmjs.org/transifex/-/transifex-1.6.6.tgz", - "integrity": "sha512-uHeRvhfLfZN+JdH+X0zR1jkQAbMGkgExZgcXm31CzaVVd4kq98YaPr4MCgCU0LwA7cgOuB97d2HZQ/WikOAxlg==", - "dev": true, - "dependencies": { - "commander": "^2.9.0", - "lodash": "^4.17.1", - "mkpath": "^1.0.0", - "mocha": "^4.0.0", - "request": "^2.34.0", - "should": "^13.0.0" - }, - "bin": { - "transifex": "bin/index.js" - }, - "engines": { - "node": ">=8.9.0" - } - }, - "node_modules/traverse": { - "version": "0.6.9", - "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.6.9.tgz", - "integrity": "sha512-7bBrcF+/LQzSgFmT0X5YclVqQxtv7TDJ1f8Wj7ibBu/U6BMLeOpUxuZjV7rMc44UtKxlnMFigdhFAIszSX1DMg==", - "dev": true, - "dependencies": { - "gopd": "^1.0.1", - "typedarray.prototype.slice": "^1.0.3", - "which-typed-array": "^1.1.15" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/trim-newlines": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.1.tgz", - "integrity": "sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/ts-node": { - "version": "10.9.2", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", - "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", - "dev": true, - "dependencies": { - "@cspotcode/source-map-support": "^0.8.0", - "@tsconfig/node10": "^1.0.7", - "@tsconfig/node12": "^1.0.7", - "@tsconfig/node14": "^1.0.0", - "@tsconfig/node16": "^1.0.2", - "acorn": "^8.4.1", - "acorn-walk": "^8.1.1", - "arg": "^4.1.0", - "create-require": "^1.1.0", - "diff": "^4.0.1", - "make-error": "^1.1.1", - "v8-compile-cache-lib": "^3.0.1", - "yn": "3.1.1" - }, - "bin": { - "ts-node": "dist/bin.js", - "ts-node-cwd": "dist/bin-cwd.js", - "ts-node-esm": "dist/bin-esm.js", - "ts-node-script": "dist/bin-script.js", - "ts-node-transpile-only": "dist/bin-transpile.js", - "ts-script": "dist/bin-script-deprecated.js" - }, - "peerDependencies": { - "@swc/core": ">=1.2.50", - "@swc/wasm": ">=1.2.50", - "@types/node": "*", - "typescript": ">=2.7" - }, - "peerDependenciesMeta": { - "@swc/core": { - "optional": true - }, - "@swc/wasm": { - "optional": true - } - } - }, - "node_modules/ts-node/node_modules/acorn": { - "version": "8.11.3", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", - "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", - "dev": true, - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/ts-node/node_modules/diff": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", - "dev": true, - "engines": { - "node": ">=0.3.1" - } - }, - "node_modules/tty-browserify": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", - "integrity": "sha512-JVa5ijo+j/sOoHGjw0sxw734b1LhBkQ3bvUGNdxnVXDCX81Yx7TFgnZygxrIIWn23hbfTaMYLwRmAxFyDuFmIw==", - "dev": true - }, - "node_modules/tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", - "dev": true, - "dependencies": { - "safe-buffer": "^5.0.1" - }, - "engines": { - "node": "*" - } - }, - "node_modules/tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==", - "dev": true - }, - "node_modules/type-check": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==", - "dev": true, - "dependencies": { - "prelude-ls": "~1.1.2" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/type-fest": { - "version": "0.18.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.18.1.tgz", - "integrity": "sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/typed-array-buffer": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.2.tgz", - "integrity": "sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.7", - "es-errors": "^1.3.0", - "is-typed-array": "^1.1.13" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/typed-array-byte-length": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.1.tgz", - "integrity": "sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.7", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-proto": "^1.0.3", - "is-typed-array": "^1.1.13" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/typed-array-byte-offset": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.2.tgz", - "integrity": "sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==", - "dev": true, - "dependencies": { - "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.7", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-proto": "^1.0.3", - "is-typed-array": "^1.1.13" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/typed-array-length": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.6.tgz", - "integrity": "sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.7", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-proto": "^1.0.3", - "is-typed-array": "^1.1.13", - "possible-typed-array-names": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==", - "dev": true - }, - "node_modules/typedarray.prototype.slice": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/typedarray.prototype.slice/-/typedarray.prototype.slice-1.0.3.tgz", - "integrity": "sha512-8WbVAQAUlENo1q3c3zZYuy5k9VzBQvp8AX9WOtbvyWlLM1v5JaSRmjubLjzHF4JFtptjH/5c/i95yaElvcjC0A==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.0", - "es-errors": "^1.3.0", - "typed-array-buffer": "^1.0.2", - "typed-array-byte-offset": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/typescript": { - "version": "5.4.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz", - "integrity": "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==", - "dev": true, - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=14.17" - } - }, - "node_modules/uglify-es": { - "version": "3.3.9", - "resolved": "https://registry.npmjs.org/uglify-es/-/uglify-es-3.3.9.tgz", - "integrity": "sha512-r+MU0rfv4L/0eeW3xZrd16t4NZfK8Ld4SWVglYBb7ez5uXFWHuVRs6xCTrf1yirs9a4j4Y27nn7SRfO6v67XsQ==", - "deprecated": "support for ECMAScript is superseded by `uglify-js` as of v3.13.0", - "dev": true, - "dependencies": { - "commander": "~2.13.0", - "source-map": "~0.6.1" - }, - "bin": { - "uglifyjs": "bin/uglifyjs" - }, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/uglify-es/node_modules/commander": { - "version": "2.13.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.13.0.tgz", - "integrity": "sha512-MVuS359B+YzaWqjCL/c+22gfryv+mCBPHAv3zyVI2GN8EY6IRP8VwtasXn8jyyhvvq84R4ImN1OKRtcbIasjYA==", - "dev": true - }, - "node_modules/uglify-es/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/uglify-js": { - "version": "3.17.4", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.17.4.tgz", - "integrity": "sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g==", - "dev": true, - "optional": true, - "bin": { - "uglifyjs": "bin/uglifyjs" - }, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/uglifyjs-webpack-plugin": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/uglifyjs-webpack-plugin/-/uglifyjs-webpack-plugin-1.3.0.tgz", - "integrity": "sha512-ovHIch0AMlxjD/97j9AYovZxG5wnHOPkL7T1GKochBADp/Zwc44pEWNqpKl1Loupp1WhFg7SlYmHZRUfdAacgw==", - "dev": true, - "dependencies": { - "cacache": "^10.0.4", - "find-cache-dir": "^1.0.0", - "schema-utils": "^0.4.5", - "serialize-javascript": "^1.4.0", - "source-map": "^0.6.1", - "uglify-es": "^3.3.4", - "webpack-sources": "^1.1.0", - "worker-farm": "^1.5.2" - }, - "engines": { - "node": ">= 4.8 < 5.0.0 || >= 5.10" - }, - "peerDependencies": { - "webpack": "^2.0.0 || ^3.0.0 || ^4.0.0" - } - }, - "node_modules/uglifyjs-webpack-plugin/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/unbox-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", - "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "has-bigints": "^1.0.2", - "has-symbols": "^1.0.3", - "which-boxed-primitive": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/union-value": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", - "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", - "dev": true, - "dependencies": { - "arr-union": "^3.1.0", - "get-value": "^2.0.6", - "is-extendable": "^0.1.1", - "set-value": "^2.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/union-value/node_modules/is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/unique-filename": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz", - "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==", - "dev": true, - "dependencies": { - "unique-slug": "^2.0.0" - } - }, - "node_modules/unique-slug": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.2.tgz", - "integrity": "sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==", - "dev": true, - "dependencies": { - "imurmurhash": "^0.1.4" - } - }, - "node_modules/unique-string": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz", - "integrity": "sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==", - "dev": true, - "dependencies": { - "crypto-random-string": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/universal-user-agent": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.1.tgz", - "integrity": "sha512-yCzhz6FN2wU1NiiQRogkTQszlQSlpWaw8SvVegAc+bDxbzHgh1vX8uIe8OYyMH6DwH+sdTJsgMl36+mSMdRJIQ==", - "dev": true - }, - "node_modules/universalify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", - "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", - "dev": true, - "engines": { - "node": ">= 10.0.0" - } - }, - "node_modules/unset-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", - "integrity": "sha512-PcA2tsuGSF9cnySLHTLSh2qrQiJ70mn+r+Glzxv2TWZblxsxCC52BDlZoPCsz7STd9pN7EZetkWZBAvk4cgZdQ==", - "dev": true, - "dependencies": { - "has-value": "^0.3.1", - "isobject": "^3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/unset-value/node_modules/has-value": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", - "integrity": "sha512-gpG936j8/MzaeID5Yif+577c17TxaDmhuyVgSwtnL/q8UUTySg8Mecb+8Cf1otgLoD7DDH75axp86ER7LFsf3Q==", - "dev": true, - "dependencies": { - "get-value": "^2.0.3", - "has-values": "^0.1.4", - "isobject": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/unset-value/node_modules/has-value/node_modules/isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha512-+OUdGJlgjOBZDfxnDjYYG6zp487z0JGNQq3cYQYg5f5hKR+syHMsaztzGeml/4kGG55CSpKSpWTY+jYGgsHLgA==", - "dev": true, - "dependencies": { - "isarray": "1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/unset-value/node_modules/has-values": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", - "integrity": "sha512-J8S0cEdWuQbqD9//tlZxiMuMNmxB8PlEwvYwuxsTmR1G5RXUePEX/SJn7aD0GMLieuZYSwNH0cQuJGwnYunXRQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/upath": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", - "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==", - "dev": true, - "optional": true, - "engines": { - "node": ">=4", - "yarn": "*" - } - }, - "node_modules/uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dev": true, - "dependencies": { - "punycode": "^2.1.0" - } - }, - "node_modules/urix": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", - "integrity": "sha512-Am1ousAhSLBeB9cG/7k7r2R0zj50uDRlZHPGbazid5s9rlF1F/QKYObEKSIunSjIOkJZqwRRLpvewjEkM7pSqg==", - "deprecated": "Please see https://github.com/lydell/urix#deprecated", - "dev": true - }, - "node_modules/url": { - "version": "0.11.3", - "resolved": "https://registry.npmjs.org/url/-/url-0.11.3.tgz", - "integrity": "sha512-6hxOLGfZASQK/cijlZnZJTq8OXAkt/3YGfQX45vvMYXpZoo8NdWZcY73K108Jf759lS1Bv/8wXnHDTSz17dSRw==", - "dev": true, - "dependencies": { - "punycode": "^1.4.1", - "qs": "^6.11.2" - } - }, - "node_modules/url-join": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/url-join/-/url-join-4.0.1.tgz", - "integrity": "sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA==", - "dev": true - }, - "node_modules/url/node_modules/punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==", - "dev": true - }, - "node_modules/url/node_modules/qs": { - "version": "6.12.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.12.0.tgz", - "integrity": "sha512-trVZiI6RMOkO476zLGaBIzszOdFPnCCXHPG9kn0yuS1uz6xdVxPfZdB3vUig9pxPFDM9BRAgz/YUIVQ1/vuiUg==", - "dev": true, - "dependencies": { - "side-channel": "^1.0.6" - }, - "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/url2": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/url2/-/url2-0.0.0.tgz", - "integrity": "sha512-gb/XT1m2mnWOIbQwa5V9Dq2O07fkZbtu1K0WAAKuaNSX0c8psp2jovJTbbvPKCpimutdoK9jXOejDCtvQOoKOA==", - "dev": true - }, - "node_modules/use": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", - "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/util": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/util/-/util-0.11.1.tgz", - "integrity": "sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ==", - "dev": true, - "dependencies": { - "inherits": "2.0.3" - } - }, - "node_modules/util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", - "dev": true - }, - "node_modules/util/node_modules/inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==", - "dev": true - }, - "node_modules/uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", - "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", - "dev": true, - "bin": { - "uuid": "bin/uuid" - } - }, - "node_modules/v8-compile-cache": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.4.0.tgz", - "integrity": "sha512-ocyWc3bAHBB/guyqJQVI5o4BZkPhznPYUG2ea80Gond/BgNWpap8TOmLSeeQG7bnh2KMISxskdADG59j7zruhw==", - "dev": true - }, - "node_modules/v8-compile-cache-lib": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", - "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", - "dev": true - }, - "node_modules/validate-npm-package-license": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", - "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", - "dev": true, - "dependencies": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" - } - }, - "node_modules/verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==", - "dev": true, - "engines": [ - "node >=0.6.0" - ], - "dependencies": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" - } - }, - "node_modules/verror/node_modules/core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==", - "dev": true - }, - "node_modules/vinyl": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-2.2.1.tgz", - "integrity": "sha512-LII3bXRFBZLlezoG5FfZVcXflZgWP/4dCwKtxd5ky9+LOtM4CS3bIRQsmR1KMnMW07jpE8fqR2lcxPZ+8sJIcw==", - "dev": true, - "dependencies": { - "clone": "^2.1.1", - "clone-buffer": "^1.0.0", - "clone-stats": "^1.0.0", - "cloneable-readable": "^1.0.0", - "remove-trailing-separator": "^1.0.1", - "replace-ext": "^1.0.0" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/vinyl-sourcemaps-apply": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/vinyl-sourcemaps-apply/-/vinyl-sourcemaps-apply-0.2.1.tgz", - "integrity": "sha512-+oDh3KYZBoZC8hfocrbrxbLUeaYtQK7J5WU5Br9VqWqmCll3tFJqKp97GC9GmMsVIL0qnx2DgEDVxdo5EZ5sSw==", - "dev": true, - "dependencies": { - "source-map": "^0.5.1" - } - }, - "node_modules/vinyl-sourcemaps-apply/node_modules/source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/vm-browserify": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz", - "integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==", - "dev": true - }, - "node_modules/watchpack": { - "version": "1.7.5", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.7.5.tgz", - "integrity": "sha512-9P3MWk6SrKjHsGkLT2KHXdQ/9SNkyoJbabxnKOoJepsvJjJG8uYTR3yTPxPQvNDI3w4Nz1xnE0TLHK4RIVe/MQ==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.1.2", - "neo-async": "^2.5.0" - }, - "optionalDependencies": { - "chokidar": "^3.4.1", - "watchpack-chokidar2": "^2.0.1" - } - }, - "node_modules/watchpack-chokidar2": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/watchpack-chokidar2/-/watchpack-chokidar2-2.0.1.tgz", - "integrity": "sha512-nCFfBIPKr5Sh61s4LPpy1Wtfi0HE8isJ3d2Yb5/Ppw2P2B/3eVSEBjKfN0fmHJSK14+31KwMKmcrzs2GM4P0Ww==", - "dev": true, - "optional": true, - "dependencies": { - "chokidar": "^2.1.8" - } - }, - "node_modules/watchpack-chokidar2/node_modules/anymatch": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", - "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", - "dev": true, - "optional": true, - "dependencies": { - "micromatch": "^3.1.4", - "normalize-path": "^2.1.1" - } - }, - "node_modules/watchpack-chokidar2/node_modules/anymatch/node_modules/normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha512-3pKJwH184Xo/lnH6oyP1q2pMd7HcypqqmRs91/6/i2CGtWwIKGCkOOMTm/zXbgTEWHw1uNpNi/igc3ePOYHb6w==", - "dev": true, - "optional": true, - "dependencies": { - "remove-trailing-separator": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/watchpack-chokidar2/node_modules/binary-extensions": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", - "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", - "dev": true, - "optional": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/watchpack-chokidar2/node_modules/braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "optional": true, - "dependencies": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/watchpack-chokidar2/node_modules/braces/node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", - "dev": true, - "optional": true, - "dependencies": { - "is-extendable": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/watchpack-chokidar2/node_modules/chokidar": { - "version": "2.1.8", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", - "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", - "deprecated": "Chokidar 2 does not receive security updates since 2019. Upgrade to chokidar 3 with 15x fewer dependencies", - "dev": true, - "optional": true, - "dependencies": { - "anymatch": "^2.0.0", - "async-each": "^1.0.1", - "braces": "^2.3.2", - "glob-parent": "^3.1.0", - "inherits": "^2.0.3", - "is-binary-path": "^1.0.0", - "is-glob": "^4.0.0", - "normalize-path": "^3.0.0", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.2.1", - "upath": "^1.1.1" - }, - "optionalDependencies": { - "fsevents": "^1.2.7" - } - }, - "node_modules/watchpack-chokidar2/node_modules/fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ==", - "dev": true, - "optional": true, - "dependencies": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/watchpack-chokidar2/node_modules/fill-range/node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", - "dev": true, - "optional": true, - "dependencies": { - "is-extendable": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/watchpack-chokidar2/node_modules/fsevents": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", - "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", - "deprecated": "The v1 package contains DANGEROUS / INSECURE binaries. Upgrade to safe fsevents v2", - "dev": true, - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], - "dependencies": { - "bindings": "^1.5.0", - "nan": "^2.12.1" - }, - "engines": { - "node": ">= 4.0" - } - }, - "node_modules/watchpack-chokidar2/node_modules/glob-parent": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha512-E8Ak/2+dZY6fnzlR7+ueWvhsH1SjHr4jjss4YS/h4py44jY9MhK/VFdaZJAWDz6BbL21KeteKxFSFpq8OS5gVA==", - "dev": true, - "optional": true, - "dependencies": { - "is-glob": "^3.1.0", - "path-dirname": "^1.0.0" - } - }, - "node_modules/watchpack-chokidar2/node_modules/glob-parent/node_modules/is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha512-UFpDDrPgM6qpnFNI+rh/p3bUaq9hKLZN8bMUWzxmcnZVS3omf4IPK+BrewlnWjO1WmUsMYuSjKh4UJuV4+Lqmw==", - "dev": true, - "optional": true, - "dependencies": { - "is-extglob": "^2.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/watchpack-chokidar2/node_modules/is-binary-path": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", - "integrity": "sha512-9fRVlXc0uCxEDj1nQzaWONSpbTfx0FmJfzHF7pwlI8DkWGoHBBea4Pg5Ky0ojwwxQmnSifgbKkI06Qv0Ljgj+Q==", - "dev": true, - "optional": true, - "dependencies": { - "binary-extensions": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/watchpack-chokidar2/node_modules/is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", - "dev": true, - "optional": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/watchpack-chokidar2/node_modules/is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==", - "dev": true, - "optional": true, - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/watchpack-chokidar2/node_modules/is-number/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "optional": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/watchpack-chokidar2/node_modules/micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "optional": true, - "dependencies": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/watchpack-chokidar2/node_modules/readdirp": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", - "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", - "dev": true, - "optional": true, - "dependencies": { - "graceful-fs": "^4.1.11", - "micromatch": "^3.1.10", - "readable-stream": "^2.0.2" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/watchpack-chokidar2/node_modules/to-regex-range": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha512-ZZWNfCjUokXXDGXFpZehJIkZqq91BcULFq/Pi7M5i4JnxXdhMKAK682z8bCW3o8Hj1wuuzoKcW3DfVzaP6VuNg==", - "dev": true, - "optional": true, - "dependencies": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/weak-map": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/weak-map/-/weak-map-1.0.0.tgz", - "integrity": "sha512-Vb13TbgdvUEmzBA5mpsMqtPqcZGJPE2gj+b8wzxsevC7WkmL3c7YZg9H0pV1Jo8C1Sa1ykk3DU08hFRGLNWvLQ==", - "dev": true - }, - "node_modules/webidl-conversions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", - "dev": true - }, - "node_modules/webpack": { - "version": "4.47.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.47.0.tgz", - "integrity": "sha512-td7fYwgLSrky3fI1EuU5cneU4+pbH6GgOfuKNS1tNPcfdGinGELAqsb/BP4nnvZyKSG2i/xFGU7+n2PvZA8HJQ==", - "dev": true, - "dependencies": { - "@webassemblyjs/ast": "1.9.0", - "@webassemblyjs/helper-module-context": "1.9.0", - "@webassemblyjs/wasm-edit": "1.9.0", - "@webassemblyjs/wasm-parser": "1.9.0", - "acorn": "^6.4.1", - "ajv": "^6.10.2", - "ajv-keywords": "^3.4.1", - "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^4.5.0", - "eslint-scope": "^4.0.3", - "json-parse-better-errors": "^1.0.2", - "loader-runner": "^2.4.0", - "loader-utils": "^1.2.3", - "memory-fs": "^0.4.1", - "micromatch": "^3.1.10", - "mkdirp": "^0.5.3", - "neo-async": "^2.6.1", - "node-libs-browser": "^2.2.1", - "schema-utils": "^1.0.0", - "tapable": "^1.1.3", - "terser-webpack-plugin": "^1.4.3", - "watchpack": "^1.7.4", - "webpack-sources": "^1.4.1" - }, - "bin": { - "webpack": "bin/webpack.js" - }, - "engines": { - "node": ">=6.11.5" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependenciesMeta": { - "webpack-cli": { - "optional": true - }, - "webpack-command": { - "optional": true - } - } - }, - "node_modules/webpack-cli": { - "version": "3.3.12", - "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-3.3.12.tgz", - "integrity": "sha512-NVWBaz9k839ZH/sinurM+HcDvJOTXwSjYp1ku+5XKeOC03z8v5QitnK/x+lAxGXFyhdayoIf/GOpv85z3/xPag==", - "dev": true, - "dependencies": { - "chalk": "^2.4.2", - "cross-spawn": "^6.0.5", - "enhanced-resolve": "^4.1.1", - "findup-sync": "^3.0.0", - "global-modules": "^2.0.0", - "import-local": "^2.0.0", - "interpret": "^1.4.0", - "loader-utils": "^1.4.0", - "supports-color": "^6.1.0", - "v8-compile-cache": "^2.1.1", - "yargs": "^13.3.2" - }, - "bin": { - "webpack-cli": "bin/cli.js" - }, - "engines": { - "node": ">=6.11.5" - }, - "peerDependencies": { - "webpack": "4.x.x" - } - }, - "node_modules/webpack-cli/node_modules/ansi-regex": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", - "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/webpack-cli/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/webpack-cli/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/webpack-cli/node_modules/chalk/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/webpack-cli/node_modules/cliui": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", - "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", - "dev": true, - "dependencies": { - "string-width": "^3.1.0", - "strip-ansi": "^5.2.0", - "wrap-ansi": "^5.1.0" - } - }, - "node_modules/webpack-cli/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "dependencies": { - "color-name": "1.1.3" - } + "path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==", + "dev": true + }, + "picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "dev": true }, - "node_modules/webpack-cli/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "dev": true }, - "node_modules/webpack-cli/node_modules/cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", "dev": true, - "dependencies": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - }, - "engines": { - "node": ">=4.8" + "requires": { + "find-up": "^4.0.0" } }, - "node_modules/webpack-cli/node_modules/emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", "dev": true }, - "node_modules/webpack-cli/node_modules/find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", "dev": true, - "dependencies": { - "locate-path": "^3.0.0" + "requires": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" }, - "engines": { - "node": ">=6" + "dependencies": { + "ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "dev": true + } } }, - "node_modules/webpack-cli/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, - "engines": { - "node": ">=4" - } + "psl": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", + "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==" }, - "node_modules/webpack-cli/node_modules/locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==" + }, + "qs": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", + "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", "dev": true, - "dependencies": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - }, - "engines": { - "node": ">=6" + "requires": { + "side-channel": "^1.0.4" } }, - "node_modules/webpack-cli/node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "querystringify": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", + "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==" + }, + "randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", "dev": true, - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "requires": { + "safe-buffer": "^5.1.0" } }, - "node_modules/webpack-cli/node_modules/p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "dev": true + }, + "raw-body": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", + "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", "dev": true, - "dependencies": { - "p-limit": "^2.0.0" + "requires": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" }, - "engines": { - "node": ">=6" + "dependencies": { + "bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "dev": true + }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + } } }, - "node_modules/webpack-cli/node_modules/p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", "dev": true, - "engines": { - "node": ">=6" + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" } }, - "node_modules/webpack-cli/node_modules/path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", + "readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", "dev": true, - "engines": { - "node": ">=4" + "requires": { + "picomatch": "^2.2.1" } }, - "node_modules/webpack-cli/node_modules/path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==", + "rechoir": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.7.1.tgz", + "integrity": "sha512-/njmZ8s1wVeR6pjTZ+0nCnv8SpZNRMT2D1RLOJQESlYFDBvwpTA4KWJpZ+sBJ4+vhjILRcK7JIFdGCdxEAAitg==", "dev": true, - "engines": { - "node": ">=4" + "requires": { + "resolve": "^1.9.0" } }, - "node_modules/webpack-cli/node_modules/semver": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", - "dev": true, - "bin": { - "semver": "bin/semver" - } + "require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true }, - "node_modules/webpack-cli/node_modules/string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "dependencies": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - }, - "engines": { - "node": ">=6" - } + "requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==" }, - "node_modules/webpack-cli/node_modules/strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "resolve": { + "version": "1.22.8", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", + "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", "dev": true, - "dependencies": { - "ansi-regex": "^4.1.0" - }, - "engines": { - "node": ">=6" + "requires": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" } }, - "node_modules/webpack-cli/node_modules/supports-color": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", - "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "resolve-cwd": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", + "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", "dev": true, - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=6" + "requires": { + "resolve-from": "^5.0.0" } }, - "node_modules/webpack-cli/node_modules/wrap-ansi": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", - "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", - "dev": true, - "dependencies": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.0" - }, - "engines": { - "node": ">=6" - } + "resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true }, - "node_modules/webpack-cli/node_modules/yargs": { - "version": "13.3.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", - "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", - "dev": true, - "dependencies": { - "cliui": "^5.0.0", - "find-up": "^3.0.0", - "get-caller-file": "^2.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^3.0.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^13.1.2" - } + "retry": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", + "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", + "dev": true }, - "node_modules/webpack-cli/node_modules/yargs-parser": { - "version": "13.1.2", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", - "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", + "rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", "dev": true, - "dependencies": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" + "requires": { + "glob": "^7.1.3" } }, - "node_modules/webpack-sources": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz", - "integrity": "sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==", - "dev": true, - "dependencies": { - "source-list-map": "^2.0.0", - "source-map": "~0.6.1" - } + "rrweb-cssom": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.6.0.tgz", + "integrity": "sha512-APM0Gt1KoXBz0iIkkdB/kfvGOwC4UuJFeG/c+yV7wSc7q96cG/kJ0HiYCnzivD9SB53cLV1MlHFNfOuPaadYSw==" }, - "node_modules/webpack-sources/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true }, - "node_modules/webpack/node_modules/acorn": { - "version": "6.4.2", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.2.tgz", - "integrity": "sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ==", - "dev": true, - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, - "node_modules/webpack/node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" + "saxes": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz", + "integrity": "sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==", + "requires": { + "xmlchars": "^2.2.0" } }, - "node_modules/webpack/node_modules/ajv-keywords": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", - "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "schema-utils": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", + "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", "dev": true, - "peerDependencies": { - "ajv": "^6.9.1" + "requires": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" } }, - "node_modules/webpack/node_modules/braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "dependencies": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } + "select-hose": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", + "integrity": "sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg==", + "dev": true }, - "node_modules/webpack/node_modules/braces/node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", - "dev": true, - "dependencies": { - "is-extendable": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" + "selfsigned": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-2.4.1.tgz", + "integrity": "sha512-th5B4L2U+eGLq1TVh7zNRGBapioSORUeymIydxgFpwww9d2qyKvtuPU2jJuHvYAwwqi2Y596QBL3eEqcPEYL8Q==", + "dev": true, + "requires": { + "@types/node-forge": "^1.3.0", + "node-forge": "^1" + } + }, + "send": { + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", + "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", + "dev": true, + "requires": { + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "2.4.1", + "range-parser": "~1.2.1", + "statuses": "2.0.1" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + }, + "dependencies": { + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + } + } + }, + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + } } }, - "node_modules/webpack/node_modules/eslint-scope": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz", - "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==", + "serialize-javascript": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.1.tgz", + "integrity": "sha512-owoXEFjWRllis8/M1Q+Cw5k8ZH40e3zhp/ovX+Xr/vi1qj6QesbyXXViFbpNvWvPNAD62SutwEXavefrLJWj7w==", "dev": true, - "dependencies": { - "esrecurse": "^4.1.0", - "estraverse": "^4.1.1" - }, - "engines": { - "node": ">=4.0.0" + "requires": { + "randombytes": "^2.1.0" } }, - "node_modules/webpack/node_modules/fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ==", - "dev": true, - "dependencies": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "engines": { - "node": ">=0.10.0" + "serve-index": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz", + "integrity": "sha512-pXHfKNP4qujrtteMrSBb0rc8HJ9Ms/GrXwcUtUtD5s4ewDJI8bT3Cz2zTVRMKtri49pLx2e0Ya8ziP5Ya2pZZw==", + "dev": true, + "requires": { + "accepts": "~1.3.4", + "batch": "0.6.1", + "debug": "2.6.9", + "escape-html": "~1.0.3", + "http-errors": "~1.6.2", + "mime-types": "~2.1.17", + "parseurl": "~1.3.2" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==", + "dev": true + }, + "http-errors": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", + "integrity": "sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A==", + "dev": true, + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.0", + "statuses": ">= 1.4.0 < 2" + } + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==", + "dev": true + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + }, + "setprototypeof": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", + "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==", + "dev": true + }, + "statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==", + "dev": true + } } }, - "node_modules/webpack/node_modules/fill-range/node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", + "serve-static": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", + "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", "dev": true, - "dependencies": { - "is-extendable": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" + "requires": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.18.0" } }, - "node_modules/webpack/node_modules/is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", + "set-function-length": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.1.1.tgz", + "integrity": "sha512-VoaqjbBJKiWtg4yRcKBQ7g7wnGnLV3M8oLvVWwOk2PdYY6PEFegR1vezXR0tw6fZGF9csVakIRjrJiy2veSBFQ==", "dev": true, - "engines": { - "node": ">=0.10.0" + "requires": { + "define-data-property": "^1.1.1", + "get-intrinsic": "^1.2.1", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.0" } }, - "node_modules/webpack/node_modules/is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==", + "setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", + "dev": true + }, + "shallow-clone": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", + "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", "dev": true, - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" + "requires": { + "kind-of": "^6.0.2" } }, - "node_modules/webpack/node_modules/is-number/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" + "requires": { + "shebang-regex": "^3.0.0" } }, - "node_modules/webpack/node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true + }, + "shell-quote": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.1.tgz", + "integrity": "sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==", "dev": true }, - "node_modules/webpack/node_modules/micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "side-channel": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", "dev": true, - "dependencies": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" + "requires": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" } }, - "node_modules/webpack/node_modules/schema-utils": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", - "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", + "signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true + }, + "sockjs": { + "version": "0.3.24", + "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.24.tgz", + "integrity": "sha512-GJgLTZ7vYb/JtPSSZ10hsOYIvEYsjbNU+zPdIHcUaWVNUEPivzxku31865sSSud0Da0W4lEeOPlmw93zLQchuQ==", "dev": true, - "dependencies": { - "ajv": "^6.1.0", - "ajv-errors": "^1.0.0", - "ajv-keywords": "^3.1.0" - }, - "engines": { - "node": ">= 4" + "requires": { + "faye-websocket": "^0.11.3", + "uuid": "^8.3.2", + "websocket-driver": "^0.7.4" } }, - "node_modules/webpack/node_modules/to-regex-range": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha512-ZZWNfCjUokXXDGXFpZehJIkZqq91BcULFq/Pi7M5i4JnxXdhMKAK682z8bCW3o8Hj1wuuzoKcW3DfVzaP6VuNg==", + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "source-map-js": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", + "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", + "dev": true + }, + "source-map-loader": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/source-map-loader/-/source-map-loader-4.0.1.tgz", + "integrity": "sha512-oqXpzDIByKONVY8g1NUPOTQhe0UTU5bWUl32GSkqK2LjJj0HmwTMVKxcUip0RgAYhY1mqgOxjbQM48a0mmeNfA==", "dev": true, - "dependencies": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" - }, - "engines": { - "node": ">=0.10.0" + "requires": { + "abab": "^2.0.6", + "iconv-lite": "^0.6.3", + "source-map-js": "^1.0.2" } }, - "node_modules/whatwg-url": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", "dev": true, - "dependencies": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" } }, - "node_modules/which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "spdy": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.2.tgz", + "integrity": "sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA==", "dev": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "which": "bin/which" + "requires": { + "debug": "^4.1.0", + "handle-thing": "^2.0.0", + "http-deceiver": "^1.2.7", + "select-hose": "^2.0.0", + "spdy-transport": "^3.0.0" } }, - "node_modules/which-boxed-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", - "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "spdy-transport": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/spdy-transport/-/spdy-transport-3.0.0.tgz", + "integrity": "sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==", "dev": true, - "dependencies": { - "is-bigint": "^1.0.1", - "is-boolean-object": "^1.1.0", - "is-number-object": "^1.0.4", - "is-string": "^1.0.5", - "is-symbol": "^1.0.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "requires": { + "debug": "^4.1.0", + "detect-node": "^2.0.4", + "hpack.js": "^2.1.6", + "obuf": "^1.1.2", + "readable-stream": "^3.0.6", + "wbuf": "^1.7.3" } }, - "node_modules/which-module": { + "statuses": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.1.tgz", - "integrity": "sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", "dev": true }, - "node_modules/which-typed-array": { - "version": "1.1.15", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.15.tgz", - "integrity": "sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==", + "string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", "dev": true, - "dependencies": { - "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.7", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-tostringtag": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "requires": { + "safe-buffer": "~5.2.0" } }, - "node_modules/word-wrap": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", - "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "dev": true + }, + "supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", "dev": true, - "engines": { - "node": ">=0.10.0" + "requires": { + "has-flag": "^4.0.0" } }, - "node_modules/wordwrap": { + "supports-preserve-symlinks-flag": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", - "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", "dev": true }, - "node_modules/worker-farm": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.7.0.tgz", - "integrity": "sha512-rvw3QTZc8lAxyVrqcSGVm5yP/IJ2UcB3U0graE3LCFoZ0Yn2x4EoVSqJKdB/T5M+FLcRPjz4TDacRf3OCfNUzw==", + "symbol-tree": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", + "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==" + }, + "tapable": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", + "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", + "dev": true + }, + "terser": { + "version": "5.26.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.26.0.tgz", + "integrity": "sha512-dytTGoE2oHgbNV9nTzgBEPaqAWvcJNl66VZ0BkJqlvp71IjO8CxdBx/ykCNb47cLnCmCvRZ6ZR0tLkqvZCdVBQ==", "dev": true, - "dependencies": { - "errno": "~0.1.7" + "requires": { + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.8.2", + "commander": "^2.20.0", + "source-map-support": "~0.5.20" } }, - "node_modules/wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "terser-webpack-plugin": { + "version": "5.3.9", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.9.tgz", + "integrity": "sha512-ZuXsqE07EcggTWQjXUj+Aot/OMcD0bMKGgF63f7UxYcu5/AJF53aIpK1YoP5xR9l6s/Hy2b+t1AM0bLNPRuhwA==", "dev": true, - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + "requires": { + "@jridgewell/trace-mapping": "^0.3.17", + "jest-worker": "^27.4.5", + "schema-utils": "^3.1.1", + "serialize-javascript": "^6.0.1", + "terser": "^5.16.8" } }, - "node_modules/wrap-ansi/node_modules/ansi-regex": { + "thunky": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz", + "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==", + "dev": true + }, + "to-regex-range": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", "dev": true, - "engines": { - "node": ">=8" + "requires": { + "is-number": "^7.0.0" } }, - "node_modules/wrap-ansi/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "engines": { - "node": ">=8" + "toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "dev": true + }, + "tough-cookie": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.3.tgz", + "integrity": "sha512-aX/y5pVRkfRnfmuX+OdbSdXvPe6ieKX/G2s7e98f4poJHnqH3281gDPm/metm6E/WRamfx7WC4HUqkWHfQHprw==", + "requires": { + "psl": "^1.1.33", + "punycode": "^2.1.1", + "universalify": "^0.2.0", + "url-parse": "^1.5.3" } }, - "node_modules/wrap-ansi/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" + "tr46": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-4.1.1.tgz", + "integrity": "sha512-2lv/66T7e5yNyhAAC4NaKe5nVavzuGJQVVtRYLyQ2OI8tsJ61PMLlelehb0wi2Hx6+hT/OJUWZcw8MjlSRnxvw==", + "requires": { + "punycode": "^2.3.0" } }, - "node_modules/wrap-ansi/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", "dev": true, - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" + "requires": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" } }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "dev": true + }, + "universalify": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", + "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==" + }, + "unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", "dev": true }, - "node_modules/write": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/write/-/write-0.2.1.tgz", - "integrity": "sha512-CJ17OoULEKXpA5pef3qLj5AxTJ6mSt7g84he2WIskKwqFO4T97d5V7Tadl0DYDk7qyUOQD5WlUlOMChaYrhxeA==", + "update-browserslist-db": { + "version": "1.0.13", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", + "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==", "dev": true, - "dependencies": { - "mkdirp": "^0.5.1" - }, - "engines": { - "node": ">=0.10.0" + "requires": { + "escalade": "^3.1.1", + "picocolors": "^1.0.0" } }, - "node_modules/ws": { - "version": "8.16.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.16.0.tgz", - "integrity": "sha512-HS0c//TP7Ina87TfiPUz1rQzMhHrl/SG2guqRcTOIUYD2q8uhUdNHZYJUaQ8aTGPzCh+c6oawMKW35nFl1dxyQ==", + "uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", "dev": true, - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": ">=5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } + "requires": { + "punycode": "^2.1.0" } }, - "node_modules/xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", - "dev": true, - "engines": { - "node": ">=0.4" + "url-parse": { + "version": "1.5.10", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", + "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", + "requires": { + "querystringify": "^2.1.1", + "requires-port": "^1.0.0" } }, - "node_modules/y18n": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", - "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", "dev": true }, - "node_modules/yallist": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", - "integrity": "sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==", + "utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", "dev": true }, - "node_modules/yaml": { - "version": "1.10.2", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", - "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", - "dev": true, - "engines": { - "node": ">= 6" + "uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "dev": true + }, + "vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "dev": true + }, + "w3c-xmlserializer": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-4.0.0.tgz", + "integrity": "sha512-d+BFHzbiCx6zGfz0HyQ6Rg69w9k19nviJspaj4yNscGjrHu94sVP+aRm75yEbCh+r2/yR+7q6hux9LVtbuTGBw==", + "requires": { + "xml-name-validator": "^4.0.0" } }, - "node_modules/yargs": { - "version": "17.7.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", - "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "watchpack": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz", + "integrity": "sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg==", "dev": true, - "dependencies": { - "cliui": "^8.0.1", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.3", - "y18n": "^5.0.5", - "yargs-parser": "^21.1.1" - }, - "engines": { - "node": ">=12" + "requires": { + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.1.2" } }, - "node_modules/yargs-parser": { - "version": "20.2.9", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", - "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "wbuf": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/wbuf/-/wbuf-1.7.3.tgz", + "integrity": "sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==", "dev": true, - "engines": { - "node": ">=10" + "requires": { + "minimalistic-assert": "^1.0.0" } }, - "node_modules/yargs/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "engines": { - "node": ">=8" + "webidl-conversions": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", + "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==" + }, + "webpack": { + "version": "5.89.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.89.0.tgz", + "integrity": "sha512-qyfIC10pOr70V+jkmud8tMfajraGCZMBWJtrmuBymQKCrLTRejBI8STDp1MCyZu/QTdZSeacCQYpYNQVOzX5kw==", + "dev": true, + "requires": { + "@types/eslint-scope": "^3.7.3", + "@types/estree": "^1.0.0", + "@webassemblyjs/ast": "^1.11.5", + "@webassemblyjs/wasm-edit": "^1.11.5", + "@webassemblyjs/wasm-parser": "^1.11.5", + "acorn": "^8.7.1", + "acorn-import-assertions": "^1.9.0", + "browserslist": "^4.14.5", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^5.15.0", + "es-module-lexer": "^1.2.1", + "eslint-scope": "5.1.1", + "events": "^3.2.0", + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.2.9", + "json-parse-even-better-errors": "^2.3.1", + "loader-runner": "^4.2.0", + "mime-types": "^2.1.27", + "neo-async": "^2.6.2", + "schema-utils": "^3.2.0", + "tapable": "^2.1.1", + "terser-webpack-plugin": "^5.3.7", + "watchpack": "^2.4.0", + "webpack-sources": "^3.2.3" + } + }, + "webpack-cli": { + "version": "4.10.0", + "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-4.10.0.tgz", + "integrity": "sha512-NLhDfH/h4O6UOy+0LSso42xvYypClINuMNBVVzX4vX98TmTaTUxwRbXdhucbFMd2qLaCTcLq/PdYrvi8onw90w==", + "dev": true, + "requires": { + "@discoveryjs/json-ext": "^0.5.0", + "@webpack-cli/configtest": "^1.2.0", + "@webpack-cli/info": "^1.5.0", + "@webpack-cli/serve": "^1.7.0", + "colorette": "^2.0.14", + "commander": "^7.0.0", + "cross-spawn": "^7.0.3", + "fastest-levenshtein": "^1.0.12", + "import-local": "^3.0.2", + "interpret": "^2.2.0", + "rechoir": "^0.7.0", + "webpack-merge": "^5.7.3" + }, + "dependencies": { + "commander": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "dev": true + } } }, - "node_modules/yargs/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "engines": { - "node": ">=8" + "webpack-dev-middleware": { + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-5.3.3.tgz", + "integrity": "sha512-hj5CYrY0bZLB+eTO+x/j67Pkrquiy7kWepMHmUMoPsmcUaeEnQJqFzHJOyxgWlq746/wUuA64p9ta34Kyb01pA==", + "dev": true, + "requires": { + "colorette": "^2.0.10", + "memfs": "^3.4.3", + "mime-types": "^2.1.31", + "range-parser": "^1.2.1", + "schema-utils": "^4.0.0" + }, + "dependencies": { + "ajv": { + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", + "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + } + }, + "ajv-keywords": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.3" + } + }, + "json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true + }, + "schema-utils": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz", + "integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.9", + "ajv": "^8.9.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.1.0" + } + } } }, - "node_modules/yargs/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" + "webpack-dev-server": { + "version": "4.15.1", + "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-4.15.1.tgz", + "integrity": "sha512-5hbAst3h3C3L8w6W4P96L5vaV0PxSmJhxZvWKYIdgxOQm8pNZ5dEOmmSLBVpP85ReeyRt6AS1QJNyo/oFFPeVA==", + "dev": true, + "requires": { + "@types/bonjour": "^3.5.9", + "@types/connect-history-api-fallback": "^1.3.5", + "@types/express": "^4.17.13", + "@types/serve-index": "^1.9.1", + "@types/serve-static": "^1.13.10", + "@types/sockjs": "^0.3.33", + "@types/ws": "^8.5.5", + "ansi-html-community": "^0.0.8", + "bonjour-service": "^1.0.11", + "chokidar": "^3.5.3", + "colorette": "^2.0.10", + "compression": "^1.7.4", + "connect-history-api-fallback": "^2.0.0", + "default-gateway": "^6.0.3", + "express": "^4.17.3", + "graceful-fs": "^4.2.6", + "html-entities": "^2.3.2", + "http-proxy-middleware": "^2.0.3", + "ipaddr.js": "^2.0.1", + "launch-editor": "^2.6.0", + "open": "^8.0.9", + "p-retry": "^4.5.0", + "rimraf": "^3.0.2", + "schema-utils": "^4.0.0", + "selfsigned": "^2.1.1", + "serve-index": "^1.9.1", + "sockjs": "^0.3.24", + "spdy": "^4.0.2", + "webpack-dev-middleware": "^5.3.1", + "ws": "^8.13.0" + }, + "dependencies": { + "ajv": { + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", + "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + } + }, + "ajv-keywords": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.3" + } + }, + "json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true + }, + "schema-utils": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz", + "integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.9", + "ajv": "^8.9.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.1.0" + } + } } }, - "node_modules/yargs/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "webpack-merge": { + "version": "5.10.0", + "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.10.0.tgz", + "integrity": "sha512-+4zXKdx7UnO+1jaN4l2lHVD+mFvnlZQP/6ljaJVb4SZiwIKeUnrT5l0gkT8z+n4hKpC+jpOv6O9R+gLtag7pSA==", "dev": true, - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" + "requires": { + "clone-deep": "^4.0.1", + "flat": "^5.0.2", + "wildcard": "^2.0.0" } }, - "node_modules/yargs/node_modules/y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "webpack-sources": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz", + "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==", + "dev": true + }, + "websocket-driver": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", + "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", "dev": true, - "engines": { - "node": ">=10" + "requires": { + "http-parser-js": ">=0.5.1", + "safe-buffer": ">=5.1.0", + "websocket-extensions": ">=0.1.1" } }, - "node_modules/yargs/node_modules/yargs-parser": { - "version": "21.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", - "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", - "dev": true, - "engines": { - "node": ">=12" + "websocket-extensions": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", + "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", + "dev": true + }, + "whatwg-encoding": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-2.0.0.tgz", + "integrity": "sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg==", + "requires": { + "iconv-lite": "0.6.3" } }, - "node_modules/yn": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", - "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", - "dev": true, - "engines": { - "node": ">=6" + "whatwg-mimetype": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-3.0.0.tgz", + "integrity": "sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q==" + }, + "whatwg-url": { + "version": "12.0.1", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-12.0.1.tgz", + "integrity": "sha512-Ed/LrqB8EPlGxjS+TrsXcpUond1mhccS3pchLhzSgPCnTimUCKj3IZE75pAs5m6heB2U2TMerKFUXheyHY+VDQ==", + "requires": { + "tr46": "^4.1.1", + "webidl-conversions": "^7.0.0" } }, - "node_modules/yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "requires": { + "isexe": "^2.0.0" } + }, + "wildcard": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.1.tgz", + "integrity": "sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==", + "dev": true + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true + }, + "ws": { + "version": "8.15.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.15.1.tgz", + "integrity": "sha512-W5OZiCjXEmk0yZ66ZN82beM5Sz7l7coYxpRkzS+p9PP+ToQry8szKh+61eNktr7EA9DOwvFGhfC605jDHbP6QQ==", + "requires": {} + }, + "xml-name-validator": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-4.0.0.tgz", + "integrity": "sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==" + }, + "xmlchars": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", + "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==" } } } diff --git a/package.json b/package.json index a821775746..c0e8b1df79 100644 --- a/package.json +++ b/package.json @@ -1,60 +1,28 @@ { "name": "scratch-blocks", - "version": "1.1.86", + "version": "2.0.0", "description": "Scratch Blocks is a library for building creative computing interfaces.", "author": "Massachusetts Institute of Technology", "license": "Apache-2.0", - "homepage": "https://github.com/scratchfoundation/scratch-blocks#readme", + "homepage": "https://github.com/gonfunko/scratch-blocks#readme", "repository": { "type": "git", - "url": "https://github.com/scratchfoundation/scratch-blocks.git" + "url": "https://github.com/gonfunko/scratch-blocks.git" }, - "main": "./dist/vertical.js", - "browser": "./shim/vertical.js", + "main": "./dist/main.js", + "private": true, "scripts": { - "deploy": "rimraf gh-pages/closure-library/scripts/ci/CloseAdobeDialog.exe && gh-pages -t -d gh-pages -m \"Build for $(git log --pretty=format:%H -n1) [skip ci]\"", - "prepare": "husky install", - "prepublish": "python build.py && webpack", - "test": "npm run test:messages && npm run test:unit", - "test:lint": "eslint .", - "test:messages": "npm run translate && node i18n/test_scratch_msgs.js", - "test:unit": "node tests/jsunit/test_runner.js", - "translate": "node i18n/js_to_json.js && node i18n/json_to_js.js", - "translate:sync:src": "tx-push-src scratch-editor blocks msg/json/en.json", - "translate:sync:translations": "node i18n/sync_tx_translations.js", - "translate:update": "npm run translate:sync:src && npm run translate:sync:translations" - }, - "dependencies": { - "exports-loader": "^0.7.0", - "google-closure-library": "^20190301.0.0", - "imports-loader": "^0.8.0", - "scratch-l10n": "^3.18.3" + "test": "echo \"Error: no test specified\" && exit 1", + "build": "webpack --mode production", + "start": "webpack serve --open --mode development" }, "devDependencies": { - "@commitlint/cli": "17.8.1", - "@commitlint/config-conventional": "17.8.1", - "async": "2.6.4", - "copy-webpack-plugin": "4.6.0", - "eslint": "4.19.1", - "event-stream": "3.3.5", - "gh-pages": "0.12.0", - "glob": "7.2.3", - "google-closure-compiler": "20180402.0.0", - "graceful-fs": "4.2.11", - "husky": "8.0.3", - "json": "9.0.6", - "rimraf": "2.7.1", - "scratch-semantic-release-config": "1.0.14", - "selenium-webdriver": "4.16.0", - "semantic-release": "19.0.5", - "transifex": "1.6.6", - "uglifyjs-webpack-plugin": "1.3.0", - "webpack": "4.47.0", - "webpack-cli": "3.3.12" + "source-map-loader": "^4.0.1", + "webpack": "^5.76.0", + "webpack-cli": "^4.10.0", + "webpack-dev-server": "^4.11.1" }, - "config": { - "commitizen": { - "path": "cz-conventional-changelog" - } + "dependencies": { + "blockly": "^10.0.0" } -} +} \ No newline at end of file diff --git a/webpack.config.js b/webpack.config.js index 90ab127931..147cc3122e 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -1,97 +1,41 @@ -// patch 'fs' to fix EMFILE errors, for example on WSL -var realFs = require('fs'); -var gracefulFs = require('graceful-fs'); -gracefulFs.gracefulify(realFs); +const path = require('path'); -var CopyWebpackPlugin = require('copy-webpack-plugin'); -var path = require('path'); -var UglifyJsPlugin = require('uglifyjs-webpack-plugin'); - - - -module.exports = [{ - mode: process.env.NODE_ENV === 'production' ? 'production' : 'development', - entry: { - horizontal: './shim/horizontal.js', - vertical: './shim/vertical.js' - }, +// Base config that applies to either development or production mode. +const config = { + entry: './src/index.js', output: { library: 'ScratchBlocks', libraryTarget: 'commonjs2', path: path.resolve(__dirname, 'dist'), filename: '[name].js' }, - optimization: { - minimize: false + // Enable webpack-dev-server to get hot refresh of the app. + devServer: { + static: './build', }, - performance: { - hints: false +}; + +module.exports = (env, argv) => { + if (argv.mode === 'development') { + // Set the output path to the `build` directory + // so we don't clobber production builds. + config.output.path = path.resolve(__dirname, 'build'); + + // Generate source maps for our code for easier debugging. + // Not suitable for production builds. If you want source maps in + // production, choose a different one from https://webpack.js.org/configuration/devtool + config.devtool = 'eval-cheap-module-source-map'; + + // Include the source maps for Blockly for easier debugging Blockly code. + config.module.rules.push({ + test: /(blockly\/.*\.js)$/, + use: [require.resolve('source-map-loader')], + enforce: 'pre', + }); + + // Ignore spurious warnings from source-map-loader + // It can't find source maps for some Closure modules and that is expected + config.ignoreWarnings = [/Failed to parse source map/]; } -}, { - mode: process.env.NODE_ENV === 'production' ? 'production' : 'development', - entry: { - horizontal: './shim/horizontal.js', - vertical: './shim/vertical.js' - }, - output: { - library: 'Blockly', - libraryTarget: 'umd', - path: path.resolve(__dirname, 'dist', 'web'), - filename: '[name].js' - }, - optimization: { - minimizer: [ - new UglifyJsPlugin({ - uglifyOptions: { - mangle: false - } - }) - ] - }, - plugins: [] -}, -{ - mode: process.env.NODE_ENV === 'production' ? 'production' : 'development', - entry: './shim/gh-pages.js', - output: { - filename: '[name].js', - path: path.resolve(__dirname, 'gh-pages') - }, - optimization: { - minimize: false - }, - performance: { - hints: false - }, - plugins: [ - new CopyWebpackPlugin([{ - from: 'node_modules/google-closure-library', - to: 'closure-library' - }, { - from: 'blocks_common', - to: 'playgrounds/blocks_common', - }, { - from: 'blocks_horizontal', - to: 'playgrounds/blocks_horizontal', - }, { - from: 'blocks_vertical', - to: 'playgrounds/blocks_vertical', - }, { - from: 'core', - to: 'playgrounds/core' - }, { - from: 'media', - to: 'playgrounds/media' - }, { - from: 'msg', - to: 'playgrounds/msg' - }, { - from: 'tests', - to: 'playgrounds/tests' - }, { - from: '*.js', - ignore: 'webpack.config.js', - to: 'playgrounds' - }]) - ] -}]; + return config; +}; From 68d47157799799d2c7319e5b1af40dcbae292beb Mon Sep 17 00:00:00 2001 From: Aaron Dodson Date: Fri, 12 Apr 2024 09:38:46 -0700 Subject: [PATCH 002/130] chore: Add a basic entrypoint that reexports core Blockly. --- src/index.js | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 src/index.js diff --git a/src/index.js b/src/index.js new file mode 100644 index 0000000000..cc2054794f --- /dev/null +++ b/src/index.js @@ -0,0 +1,7 @@ +/** + * @license + * Copyright 2023 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + +export * from 'blockly'; From 7c346fa2424962d7796e42232d9e7db5899dfd5a Mon Sep 17 00:00:00 2001 From: Aaron Dodson Date: Fri, 12 Apr 2024 10:49:46 -0700 Subject: [PATCH 003/130] fix: Export colours. --- core/colours.js | 57 +++++++++++++++++++++---------------------------- src/index.js | 1 + 2 files changed, 25 insertions(+), 33 deletions(-) diff --git a/core/colours.js b/core/colours.js index 78b259c878..ea60b6ec8d 100644 --- a/core/colours.js +++ b/core/colours.js @@ -18,11 +18,7 @@ * limitations under the License. */ -'use strict'; - -goog.provide('Blockly.Colours'); - -Blockly.Colours = { +const Colours = { // SVG colours: these must be specificed in #RRGGBB style // To add an opacity, this must be specified as a separate property (for SVG fill-opacity) "motion": { @@ -123,38 +119,33 @@ Blockly.Colours = { "numPadText": "white", // Do not use hex here, it cannot be inlined with data-uri SVG "valueReportBackground": "#FFFFFF", "valueReportBorder": "#AAAAAA", - "menuHover": "rgba(0, 0, 0, 0.2)" -}; - -/** - * Override the colours in Blockly.Colours with new values basded on the - * given dictionary. - * @param {!Object} colours Dictionary of colour properties and new values. - * @package - */ -Blockly.Colours.overrideColours = function(colours) { - // Colour overrides provided by the injection - if (colours) { - for (var colourProperty in colours) { - if (colours.hasOwnProperty(colourProperty) && - Blockly.Colours.hasOwnProperty(colourProperty)) { - // If a property is in both colours option and Blockly.Colours, - // set the Blockly.Colours value to the override. - // Override Blockly category color object properties with those - // provided. - var colourPropertyValue = colours[colourProperty]; - if (goog.isObject(colourPropertyValue)) { - for (var colourSequence in colourPropertyValue) { - if (colourPropertyValue.hasOwnProperty(colourSequence) && - Blockly.Colours[colourProperty].hasOwnProperty(colourSequence)) { - Blockly.Colours[colourProperty][colourSequence] = - colourPropertyValue[colourSequence]; + "menuHover": "rgba(0, 0, 0, 0.2)", + overrideColours: function(colours) { + // Colour overrides provided by the injection + if (colours) { + for (var colourProperty in colours) { + if (colours.hasOwnProperty(colourProperty) && + this.hasOwnProperty(colourProperty)) { + // If a property is in both colours option and Blockly.Colours, + // set the Blockly.Colours value to the override. + // Override Blockly category color object properties with those + // provided. + var colourPropertyValue = colours[colourProperty]; + if (goog.isObject(colourPropertyValue)) { + for (var colourSequence in colourPropertyValue) { + if (colourPropertyValue.hasOwnProperty(colourSequence) && + this[colourProperty].hasOwnProperty(colourSequence)) { + this[colourProperty][colourSequence] = + colourPropertyValue[colourSequence]; + } } + } else { + this[colourProperty] = colourPropertyValue; } - } else { - Blockly.Colours[colourProperty] = colourPropertyValue; } } } } }; + +export {Colours}; diff --git a/src/index.js b/src/index.js index cc2054794f..a4db731a03 100644 --- a/src/index.js +++ b/src/index.js @@ -5,3 +5,4 @@ */ export * from 'blockly'; +export * from '../core/colours.js'; From 09326a1c82e5dfa4316d426cd745a8f1c52315b9 Mon Sep 17 00:00:00 2001 From: Aaron Dodson Date: Fri, 12 Apr 2024 10:50:01 -0700 Subject: [PATCH 004/130] fix: Export Scratch messages. --- msg/scratch_msgs.js | 192 ++++++++++++++++++++++++-------------------- src/index.js | 1 + 2 files changed, 107 insertions(+), 86 deletions(-) diff --git a/msg/scratch_msgs.js b/msg/scratch_msgs.js index 0a520a4691..12716e7bd5 100644 --- a/msg/scratch_msgs.js +++ b/msg/scratch_msgs.js @@ -1,13 +1,31 @@ -// This file was automatically generated. Do not modify. +import * as Blockly from 'blockly'; -'use strict'; - -goog.provide('Blockly.ScratchMsgs.allLocales'); - -goog.require('Blockly.ScratchMsgs'); +const ScratchMsgs = { + currentLocale_: 'en', + setLocale: function(locale) { + if (Object.keys(this.locales).includes(locale)) { + this.currentLocale_ = locale; + Blockly.Msg = Object.assign({}, Blockly.Msg, this.locales[locale]); + } else { + // keep current locale + console.warn('Ignoring unrecognized locale: ' + locale); + } + }, + translate: function(msgId, defaultMsg, useLocale) { + var locale = useLocale || this.currentLocale_; + if (Object.keys(this.locales).includes(locale)) { + var messages = this.locales[locale]; + if (Object.keys(messages).includes(msgId)) { + return messages[msgId]; + } + } + return defaultMsg; + }, + locales: {}, +}; -Blockly.ScratchMsgs.locales["ab"] = +ScratchMsgs.locales["ab"] = { "CONTROL_FOREVER": "инагӡалатәуп еснагь", "CONTROL_REPEAT": "инагӡалатәуп %1 - нтә", @@ -294,7 +312,7 @@ Blockly.ScratchMsgs.locales["ab"] = "DEFAULT_BROADCAST_MESSAGE_NAME": "ацҳамҭа1" }; -Blockly.ScratchMsgs.locales["af"] = +ScratchMsgs.locales["af"] = { "CONTROL_FOREVER": "vir ewig", "CONTROL_REPEAT": "herhaal %1 keer", @@ -581,7 +599,7 @@ Blockly.ScratchMsgs.locales["af"] = "DEFAULT_BROADCAST_MESSAGE_NAME": "boodskap1" }; -Blockly.ScratchMsgs.locales["ar"] = +ScratchMsgs.locales["ar"] = { "CONTROL_FOREVER": "كرِّر باستمرار", "CONTROL_REPEAT": "كرِّر %1 مرة", @@ -868,7 +886,7 @@ Blockly.ScratchMsgs.locales["ar"] = "DEFAULT_BROADCAST_MESSAGE_NAME": "الرسالة 1" }; -Blockly.ScratchMsgs.locales["am"] = +ScratchMsgs.locales["am"] = { "CONTROL_FOREVER": "ለዘላለም", "CONTROL_REPEAT": "%1ን ድገም", @@ -1155,7 +1173,7 @@ Blockly.ScratchMsgs.locales["am"] = "DEFAULT_BROADCAST_MESSAGE_NAME": "መልእክት1" }; -Blockly.ScratchMsgs.locales["an"] = +ScratchMsgs.locales["an"] = { "CONTROL_FOREVER": "pa cutio", "CONTROL_REPEAT": "repetir %1", @@ -1442,7 +1460,7 @@ Blockly.ScratchMsgs.locales["an"] = "DEFAULT_BROADCAST_MESSAGE_NAME": "mensache1" }; -Blockly.ScratchMsgs.locales["ast"] = +ScratchMsgs.locales["ast"] = { "CONTROL_FOREVER": "pa siempres", "CONTROL_REPEAT": "repetir %1", @@ -1729,7 +1747,7 @@ Blockly.ScratchMsgs.locales["ast"] = "DEFAULT_BROADCAST_MESSAGE_NAME": "mensaxe1" }; -Blockly.ScratchMsgs.locales["az"] = +ScratchMsgs.locales["az"] = { "CONTROL_FOREVER": "həmişə", "CONTROL_REPEAT": "təkrarla %1 dəfə", @@ -2016,7 +2034,7 @@ Blockly.ScratchMsgs.locales["az"] = "DEFAULT_BROADCAST_MESSAGE_NAME": "ismarıc 1" }; -Blockly.ScratchMsgs.locales["id"] = +ScratchMsgs.locales["id"] = { "CONTROL_FOREVER": "selamanya", "CONTROL_REPEAT": "ulangi %1 kali", @@ -2303,7 +2321,7 @@ Blockly.ScratchMsgs.locales["id"] = "DEFAULT_BROADCAST_MESSAGE_NAME": "pesan1" }; -Blockly.ScratchMsgs.locales["bn"] = +ScratchMsgs.locales["bn"] = { "CONTROL_FOREVER": "চিরকালের জন্য", "CONTROL_REPEAT": "পুনরাবৃত্তি %1 বার", @@ -2590,7 +2608,7 @@ Blockly.ScratchMsgs.locales["bn"] = "DEFAULT_BROADCAST_MESSAGE_NAME": "বার্তা1" }; -Blockly.ScratchMsgs.locales["be"] = +ScratchMsgs.locales["be"] = { "CONTROL_FOREVER": "заўжды", "CONTROL_REPEAT": "паўтарыць %1", @@ -2877,7 +2895,7 @@ Blockly.ScratchMsgs.locales["be"] = "DEFAULT_BROADCAST_MESSAGE_NAME": "паведамленне1" }; -Blockly.ScratchMsgs.locales["bg"] = +ScratchMsgs.locales["bg"] = { "CONTROL_FOREVER": "винаги", "CONTROL_REPEAT": "повтори %1", @@ -3164,7 +3182,7 @@ Blockly.ScratchMsgs.locales["bg"] = "DEFAULT_BROADCAST_MESSAGE_NAME": "съобщение1" }; -Blockly.ScratchMsgs.locales["ca"] = +ScratchMsgs.locales["ca"] = { "CONTROL_FOREVER": "per sempre", "CONTROL_REPEAT": "repeteix %1", @@ -3451,7 +3469,7 @@ Blockly.ScratchMsgs.locales["ca"] = "DEFAULT_BROADCAST_MESSAGE_NAME": "missatge1" }; -Blockly.ScratchMsgs.locales["cs"] = +ScratchMsgs.locales["cs"] = { "CONTROL_FOREVER": "opakuj stále", "CONTROL_REPEAT": "opakuj %1 krát", @@ -3738,7 +3756,7 @@ Blockly.ScratchMsgs.locales["cs"] = "DEFAULT_BROADCAST_MESSAGE_NAME": "zpráva1" }; -Blockly.ScratchMsgs.locales["cy"] = +ScratchMsgs.locales["cy"] = { "CONTROL_FOREVER": "am byth", "CONTROL_REPEAT": "ailadrodd %1", @@ -4025,7 +4043,7 @@ Blockly.ScratchMsgs.locales["cy"] = "DEFAULT_BROADCAST_MESSAGE_NAME": "neges1" }; -Blockly.ScratchMsgs.locales["da"] = +ScratchMsgs.locales["da"] = { "CONTROL_FOREVER": "for evigt", "CONTROL_REPEAT": "gentag %1 gange", @@ -4312,7 +4330,7 @@ Blockly.ScratchMsgs.locales["da"] = "DEFAULT_BROADCAST_MESSAGE_NAME": "besked1" }; -Blockly.ScratchMsgs.locales["de"] = +ScratchMsgs.locales["de"] = { "CONTROL_FOREVER": "wiederhole fortlaufend", "CONTROL_REPEAT": "wiederhole %1 mal", @@ -4599,7 +4617,7 @@ Blockly.ScratchMsgs.locales["de"] = "DEFAULT_BROADCAST_MESSAGE_NAME": "Nachricht1" }; -Blockly.ScratchMsgs.locales["et"] = +ScratchMsgs.locales["et"] = { "CONTROL_FOREVER": "korda lõputult", "CONTROL_REPEAT": "korda %1 korda", @@ -4886,7 +4904,7 @@ Blockly.ScratchMsgs.locales["et"] = "DEFAULT_BROADCAST_MESSAGE_NAME": "teade1" }; -Blockly.ScratchMsgs.locales["el"] = +ScratchMsgs.locales["el"] = { "CONTROL_FOREVER": "για πάντα", "CONTROL_REPEAT": "επανάλαβε %1", @@ -5173,7 +5191,7 @@ Blockly.ScratchMsgs.locales["el"] = "DEFAULT_BROADCAST_MESSAGE_NAME": "μήνυμα1" }; -Blockly.ScratchMsgs.locales["en"] = +ScratchMsgs.locales["en"] = { "CONTROL_FOREVER": "forever", "CONTROL_REPEAT": "repeat %1", @@ -5460,7 +5478,7 @@ Blockly.ScratchMsgs.locales["en"] = "DEFAULT_BROADCAST_MESSAGE_NAME": "message1" }; -Blockly.ScratchMsgs.locales["es"] = +ScratchMsgs.locales["es"] = { "CONTROL_FOREVER": "por siempre", "CONTROL_REPEAT": "repetir %1", @@ -5747,7 +5765,7 @@ Blockly.ScratchMsgs.locales["es"] = "DEFAULT_BROADCAST_MESSAGE_NAME": "mensaje1" }; -Blockly.ScratchMsgs.locales["es-419"] = +ScratchMsgs.locales["es-419"] = { "CONTROL_FOREVER": "por siempre", "CONTROL_REPEAT": "repetir %1", @@ -6034,7 +6052,7 @@ Blockly.ScratchMsgs.locales["es-419"] = "DEFAULT_BROADCAST_MESSAGE_NAME": "mensaje1" }; -Blockly.ScratchMsgs.locales["eo"] = +ScratchMsgs.locales["eo"] = { "CONTROL_FOREVER": "ripeti senfine", "CONTROL_REPEAT": "ripeti %1-foje", @@ -6321,7 +6339,7 @@ Blockly.ScratchMsgs.locales["eo"] = "DEFAULT_BROADCAST_MESSAGE_NAME": "mesaĝo1" }; -Blockly.ScratchMsgs.locales["eu"] = +ScratchMsgs.locales["eu"] = { "CONTROL_FOREVER": "etengabe", "CONTROL_REPEAT": "errepikatu %1 aldiz", @@ -6608,7 +6626,7 @@ Blockly.ScratchMsgs.locales["eu"] = "DEFAULT_BROADCAST_MESSAGE_NAME": "mezua1" }; -Blockly.ScratchMsgs.locales["fa"] = +ScratchMsgs.locales["fa"] = { "CONTROL_FOREVER": "برای همیشه", "CONTROL_REPEAT": "تکرار کن %1", @@ -6895,7 +6913,7 @@ Blockly.ScratchMsgs.locales["fa"] = "DEFAULT_BROADCAST_MESSAGE_NAME": "پیام 1" }; -Blockly.ScratchMsgs.locales["fil"] = +ScratchMsgs.locales["fil"] = { "CONTROL_FOREVER": "kailanman", "CONTROL_REPEAT": "ulitin nang %1", @@ -7182,7 +7200,7 @@ Blockly.ScratchMsgs.locales["fil"] = "DEFAULT_BROADCAST_MESSAGE_NAME": "mensahe1" }; -Blockly.ScratchMsgs.locales["fr"] = +ScratchMsgs.locales["fr"] = { "CONTROL_FOREVER": "répéter indéfiniment", "CONTROL_REPEAT": "répéter %1 fois", @@ -7469,7 +7487,7 @@ Blockly.ScratchMsgs.locales["fr"] = "DEFAULT_BROADCAST_MESSAGE_NAME": "message1" }; -Blockly.ScratchMsgs.locales["fy"] = +ScratchMsgs.locales["fy"] = { "CONTROL_FOREVER": "foar altyd", "CONTROL_REPEAT": "werhelje %1", @@ -7756,7 +7774,7 @@ Blockly.ScratchMsgs.locales["fy"] = "DEFAULT_BROADCAST_MESSAGE_NAME": "berjocht1" }; -Blockly.ScratchMsgs.locales["ga"] = +ScratchMsgs.locales["ga"] = { "CONTROL_FOREVER": "go deo", "CONTROL_REPEAT": "déan %1 uair", @@ -8043,7 +8061,7 @@ Blockly.ScratchMsgs.locales["ga"] = "DEFAULT_BROADCAST_MESSAGE_NAME": "teachtaireacht1" }; -Blockly.ScratchMsgs.locales["gd"] = +ScratchMsgs.locales["gd"] = { "CONTROL_FOREVER": "gu buan", "CONTROL_REPEAT": "dèan seo %1 turas", @@ -8330,7 +8348,7 @@ Blockly.ScratchMsgs.locales["gd"] = "DEFAULT_BROADCAST_MESSAGE_NAME": "teachdaireachd1" }; -Blockly.ScratchMsgs.locales["gl"] = +ScratchMsgs.locales["gl"] = { "CONTROL_FOREVER": "para sempre", "CONTROL_REPEAT": "repetir %1", @@ -8617,7 +8635,7 @@ Blockly.ScratchMsgs.locales["gl"] = "DEFAULT_BROADCAST_MESSAGE_NAME": "mensaxe1" }; -Blockly.ScratchMsgs.locales["ko"] = +ScratchMsgs.locales["ko"] = { "CONTROL_FOREVER": "무한 반복하기", "CONTROL_REPEAT": "%1 번 반복하기", @@ -8904,7 +8922,7 @@ Blockly.ScratchMsgs.locales["ko"] = "DEFAULT_BROADCAST_MESSAGE_NAME": "메시지1" }; -Blockly.ScratchMsgs.locales["ha"] = +ScratchMsgs.locales["ha"] = { "CONTROL_FOREVER": "har abada ", "CONTROL_REPEAT": "maimaita %1", @@ -9191,7 +9209,7 @@ Blockly.ScratchMsgs.locales["ha"] = "DEFAULT_BROADCAST_MESSAGE_NAME": "saƙon1" }; -Blockly.ScratchMsgs.locales["hy"] = +ScratchMsgs.locales["hy"] = { "CONTROL_FOREVER": "անվերջ", "CONTROL_REPEAT": "կրկնել %1", @@ -9478,7 +9496,7 @@ Blockly.ScratchMsgs.locales["hy"] = "DEFAULT_BROADCAST_MESSAGE_NAME": "հաղորդագրություն1" }; -Blockly.ScratchMsgs.locales["he"] = +ScratchMsgs.locales["he"] = { "CONTROL_FOREVER": "לעולמים", "CONTROL_REPEAT": "חזור %1 פעמים", @@ -9765,7 +9783,7 @@ Blockly.ScratchMsgs.locales["he"] = "DEFAULT_BROADCAST_MESSAGE_NAME": "מסר 1" }; -Blockly.ScratchMsgs.locales["hi"] = +ScratchMsgs.locales["hi"] = { "CONTROL_FOREVER": "सदैव", "CONTROL_REPEAT": "%1 बार दोहराएं", @@ -10052,7 +10070,7 @@ Blockly.ScratchMsgs.locales["hi"] = "DEFAULT_BROADCAST_MESSAGE_NAME": "संदेश 1 " }; -Blockly.ScratchMsgs.locales["hr"] = +ScratchMsgs.locales["hr"] = { "CONTROL_FOREVER": "ponavljaj", "CONTROL_REPEAT": "ponovi %1", @@ -10339,7 +10357,7 @@ Blockly.ScratchMsgs.locales["hr"] = "DEFAULT_BROADCAST_MESSAGE_NAME": "poruka1" }; -Blockly.ScratchMsgs.locales["xh"] = +ScratchMsgs.locales["xh"] = { "CONTROL_FOREVER": "naphakade", "CONTROL_REPEAT": "phinda %1", @@ -10626,7 +10644,7 @@ Blockly.ScratchMsgs.locales["xh"] = "DEFAULT_BROADCAST_MESSAGE_NAME": "umyalezo1" }; -Blockly.ScratchMsgs.locales["zu"] = +ScratchMsgs.locales["zu"] = { "CONTROL_FOREVER": "phakade ", "CONTROL_REPEAT": "phinda %1 ", @@ -10913,7 +10931,7 @@ Blockly.ScratchMsgs.locales["zu"] = "DEFAULT_BROADCAST_MESSAGE_NAME": "umyalezo wokuqala" }; -Blockly.ScratchMsgs.locales["is"] = +ScratchMsgs.locales["is"] = { "CONTROL_FOREVER": "endalaust", "CONTROL_REPEAT": "endurtaka %1 sinnum", @@ -11200,7 +11218,7 @@ Blockly.ScratchMsgs.locales["is"] = "DEFAULT_BROADCAST_MESSAGE_NAME": "dæmiUmNafnÁSkilaboðum" }; -Blockly.ScratchMsgs.locales["it"] = +ScratchMsgs.locales["it"] = { "CONTROL_FOREVER": "per sempre", "CONTROL_REPEAT": "ripeti %1 volte", @@ -11487,7 +11505,7 @@ Blockly.ScratchMsgs.locales["it"] = "DEFAULT_BROADCAST_MESSAGE_NAME": "messaggio1" }; -Blockly.ScratchMsgs.locales["ka"] = +ScratchMsgs.locales["ka"] = { "CONTROL_FOREVER": "მუდმივად", "CONTROL_REPEAT": "გაიმეორე %1ჯერ", @@ -11774,7 +11792,7 @@ Blockly.ScratchMsgs.locales["ka"] = "DEFAULT_BROADCAST_MESSAGE_NAME": "შეტყობინება1" }; -Blockly.ScratchMsgs.locales["kk"] = +ScratchMsgs.locales["kk"] = { "CONTROL_FOREVER": "әрқашан", "CONTROL_REPEAT": "%1 рет қайталау", @@ -12061,7 +12079,7 @@ Blockly.ScratchMsgs.locales["kk"] = "DEFAULT_BROADCAST_MESSAGE_NAME": "хабарлама1" }; -Blockly.ScratchMsgs.locales["qu"] = +ScratchMsgs.locales["qu"] = { "CONTROL_FOREVER": "wiñaypaq", "CONTROL_REPEAT": "musuqmanta %1", @@ -12348,7 +12366,7 @@ Blockly.ScratchMsgs.locales["qu"] = "DEFAULT_BROADCAST_MESSAGE_NAME": "qillqa1" }; -Blockly.ScratchMsgs.locales["sw"] = +ScratchMsgs.locales["sw"] = { "CONTROL_FOREVER": "milele", "CONTROL_REPEAT": "rudia %1", @@ -12635,7 +12653,7 @@ Blockly.ScratchMsgs.locales["sw"] = "DEFAULT_BROADCAST_MESSAGE_NAME": "ujumbe1" }; -Blockly.ScratchMsgs.locales["ht"] = +ScratchMsgs.locales["ht"] = { "CONTROL_FOREVER": "pou toujou", "CONTROL_REPEAT": "repete %1", @@ -12922,7 +12940,7 @@ Blockly.ScratchMsgs.locales["ht"] = "DEFAULT_BROADCAST_MESSAGE_NAME": "mesaj1" }; -Blockly.ScratchMsgs.locales["ku"] = +ScratchMsgs.locales["ku"] = { "CONTROL_FOREVER": "berdewamî", "CONTROL_REPEAT": "%1 caran dubare bike", @@ -13209,7 +13227,7 @@ Blockly.ScratchMsgs.locales["ku"] = "DEFAULT_BROADCAST_MESSAGE_NAME": "peyam1" }; -Blockly.ScratchMsgs.locales["ckb"] = +ScratchMsgs.locales["ckb"] = { "CONTROL_FOREVER": "بۆهەتایە", "CONTROL_REPEAT": "دوبارەکردنەوە %1", @@ -13496,7 +13514,7 @@ Blockly.ScratchMsgs.locales["ckb"] = "DEFAULT_BROADCAST_MESSAGE_NAME": "نامەی1" }; -Blockly.ScratchMsgs.locales["lv"] = +ScratchMsgs.locales["lv"] = { "CONTROL_FOREVER": "nepārtraukti", "CONTROL_REPEAT": "atkārtot %1", @@ -13783,7 +13801,7 @@ Blockly.ScratchMsgs.locales["lv"] = "DEFAULT_BROADCAST_MESSAGE_NAME": "ziņa1" }; -Blockly.ScratchMsgs.locales["lt"] = +ScratchMsgs.locales["lt"] = { "CONTROL_FOREVER": "kartok be galo", "CONTROL_REPEAT": "kartok %1", @@ -14070,7 +14088,7 @@ Blockly.ScratchMsgs.locales["lt"] = "DEFAULT_BROADCAST_MESSAGE_NAME": "žinutė1" }; -Blockly.ScratchMsgs.locales["hu"] = +ScratchMsgs.locales["hu"] = { "CONTROL_FOREVER": "mindig", "CONTROL_REPEAT": "ismételd %1", @@ -14357,7 +14375,7 @@ Blockly.ScratchMsgs.locales["hu"] = "DEFAULT_BROADCAST_MESSAGE_NAME": "üzenet1" }; -Blockly.ScratchMsgs.locales["mi"] = +ScratchMsgs.locales["mi"] = { "CONTROL_FOREVER": "mō ake, ake mahia", "CONTROL_REPEAT": "tōaitia %1", @@ -14644,7 +14662,7 @@ Blockly.ScratchMsgs.locales["mi"] = "DEFAULT_BROADCAST_MESSAGE_NAME": "karere1" }; -Blockly.ScratchMsgs.locales["mn"] = +ScratchMsgs.locales["mn"] = { "CONTROL_FOREVER": "Үргэлж", "CONTROL_REPEAT": "%1 удаа давтах", @@ -14931,7 +14949,7 @@ Blockly.ScratchMsgs.locales["mn"] = "DEFAULT_BROADCAST_MESSAGE_NAME": "мэссэж1" }; -Blockly.ScratchMsgs.locales["nl"] = +ScratchMsgs.locales["nl"] = { "CONTROL_FOREVER": "herhaal", "CONTROL_REPEAT": "herhaal %1", @@ -15218,7 +15236,7 @@ Blockly.ScratchMsgs.locales["nl"] = "DEFAULT_BROADCAST_MESSAGE_NAME": "bericht1" }; -Blockly.ScratchMsgs.locales["ja"] = +ScratchMsgs.locales["ja"] = { "CONTROL_FOREVER": "ずっと", "CONTROL_REPEAT": "%1 回繰り返す", @@ -15505,7 +15523,7 @@ Blockly.ScratchMsgs.locales["ja"] = "DEFAULT_BROADCAST_MESSAGE_NAME": "メッセージ1" }; -Blockly.ScratchMsgs.locales["ja-Hira"] = +ScratchMsgs.locales["ja-Hira"] = { "CONTROL_FOREVER": "ずっと", "CONTROL_REPEAT": "%1 かいくりかえす", @@ -15792,7 +15810,7 @@ Blockly.ScratchMsgs.locales["ja-Hira"] = "DEFAULT_BROADCAST_MESSAGE_NAME": "メッセージ1" }; -Blockly.ScratchMsgs.locales["nb"] = +ScratchMsgs.locales["nb"] = { "CONTROL_FOREVER": "gjenta for alltid", "CONTROL_REPEAT": "gjenta %1 ganger", @@ -16079,7 +16097,7 @@ Blockly.ScratchMsgs.locales["nb"] = "DEFAULT_BROADCAST_MESSAGE_NAME": "melding1" }; -Blockly.ScratchMsgs.locales["nn"] = +ScratchMsgs.locales["nn"] = { "CONTROL_FOREVER": "for alltid", "CONTROL_REPEAT": "gjenta %1 gongar", @@ -16366,7 +16384,7 @@ Blockly.ScratchMsgs.locales["nn"] = "DEFAULT_BROADCAST_MESSAGE_NAME": "melding1" }; -Blockly.ScratchMsgs.locales["oc"] = +ScratchMsgs.locales["oc"] = { "CONTROL_FOREVER": "per totjorn", "CONTROL_REPEAT": "repetir %1", @@ -16653,7 +16671,7 @@ Blockly.ScratchMsgs.locales["oc"] = "DEFAULT_BROADCAST_MESSAGE_NAME": "messatge1" }; -Blockly.ScratchMsgs.locales["or"] = +ScratchMsgs.locales["or"] = { "CONTROL_FOREVER": "ସବୁ ଦିନ ପାଇଁ ", "CONTROL_REPEAT": "%1 ପୁନରାବୃତ୍ତି କର", @@ -16940,7 +16958,7 @@ Blockly.ScratchMsgs.locales["or"] = "DEFAULT_BROADCAST_MESSAGE_NAME": "ସନ୍ଦେଶ 1 " }; -Blockly.ScratchMsgs.locales["uz"] = +ScratchMsgs.locales["uz"] = { "CONTROL_FOREVER": "har doim", "CONTROL_REPEAT": "%1 marta takrorlash", @@ -17227,7 +17245,7 @@ Blockly.ScratchMsgs.locales["uz"] = "DEFAULT_BROADCAST_MESSAGE_NAME": "xabar1" }; -Blockly.ScratchMsgs.locales["th"] = +ScratchMsgs.locales["th"] = { "CONTROL_FOREVER": "วนซ้ำตลอด", "CONTROL_REPEAT": "ทำซ้ำ %1", @@ -17514,7 +17532,7 @@ Blockly.ScratchMsgs.locales["th"] = "DEFAULT_BROADCAST_MESSAGE_NAME": "ข้อความ1" }; -Blockly.ScratchMsgs.locales["km"] = +ScratchMsgs.locales["km"] = { "CONTROL_FOREVER": "រហូត", "CONTROL_REPEAT": "ធ្វើដដែលៗ %1 ដង", @@ -17801,7 +17819,7 @@ Blockly.ScratchMsgs.locales["km"] = "DEFAULT_BROADCAST_MESSAGE_NAME": "សារ 1" }; -Blockly.ScratchMsgs.locales["pl"] = +ScratchMsgs.locales["pl"] = { "CONTROL_FOREVER": "zawsze", "CONTROL_REPEAT": "powtórz %1 razy", @@ -18088,7 +18106,7 @@ Blockly.ScratchMsgs.locales["pl"] = "DEFAULT_BROADCAST_MESSAGE_NAME": "wiadomość1" }; -Blockly.ScratchMsgs.locales["pt"] = +ScratchMsgs.locales["pt"] = { "CONTROL_FOREVER": "repete para sempre", "CONTROL_REPEAT": "repete %1 vezes", @@ -18375,7 +18393,7 @@ Blockly.ScratchMsgs.locales["pt"] = "DEFAULT_BROADCAST_MESSAGE_NAME": "Mensagem 1" }; -Blockly.ScratchMsgs.locales["pt-br"] = +ScratchMsgs.locales["pt-br"] = { "CONTROL_FOREVER": "sempre", "CONTROL_REPEAT": "repita %1 vezes", @@ -18662,7 +18680,7 @@ Blockly.ScratchMsgs.locales["pt-br"] = "DEFAULT_BROADCAST_MESSAGE_NAME": "mensagem 1" }; -Blockly.ScratchMsgs.locales["rap"] = +ScratchMsgs.locales["rap"] = { "CONTROL_FOREVER": "mo āŋa paurō te hora", "CONTROL_REPEAT": "haka ʾou %1", @@ -18949,7 +18967,7 @@ Blockly.ScratchMsgs.locales["rap"] = "DEFAULT_BROADCAST_MESSAGE_NAME": "ki hāŋa1" }; -Blockly.ScratchMsgs.locales["ro"] = +ScratchMsgs.locales["ro"] = { "CONTROL_FOREVER": "la infinit", "CONTROL_REPEAT": "repetă %1", @@ -19236,7 +19254,7 @@ Blockly.ScratchMsgs.locales["ro"] = "DEFAULT_BROADCAST_MESSAGE_NAME": "mesaj1" }; -Blockly.ScratchMsgs.locales["ru"] = +ScratchMsgs.locales["ru"] = { "CONTROL_FOREVER": "повторять всегда", "CONTROL_REPEAT": "повторить %1 раз", @@ -19523,7 +19541,7 @@ Blockly.ScratchMsgs.locales["ru"] = "DEFAULT_BROADCAST_MESSAGE_NAME": "сообщение1" }; -Blockly.ScratchMsgs.locales["nso"] = +ScratchMsgs.locales["nso"] = { "CONTROL_FOREVER": "ka go sa felego", "CONTROL_REPEAT": "bušeletša %1", @@ -19810,7 +19828,7 @@ Blockly.ScratchMsgs.locales["nso"] = "DEFAULT_BROADCAST_MESSAGE_NAME": "molaetša1" }; -Blockly.ScratchMsgs.locales["tn"] = +ScratchMsgs.locales["tn"] = { "CONTROL_FOREVER": "gosafeleng", "CONTROL_REPEAT": "boeletsa %1", @@ -20097,7 +20115,7 @@ Blockly.ScratchMsgs.locales["tn"] = "DEFAULT_BROADCAST_MESSAGE_NAME": "molaetsa 1" }; -Blockly.ScratchMsgs.locales["sk"] = +ScratchMsgs.locales["sk"] = { "CONTROL_FOREVER": "opakuj stále", "CONTROL_REPEAT": "opakuj %1", @@ -20384,7 +20402,7 @@ Blockly.ScratchMsgs.locales["sk"] = "DEFAULT_BROADCAST_MESSAGE_NAME": "správa1" }; -Blockly.ScratchMsgs.locales["sl"] = +ScratchMsgs.locales["sl"] = { "CONTROL_FOREVER": "ponavljaj", "CONTROL_REPEAT": "ponovi %1 krat", @@ -20671,7 +20689,7 @@ Blockly.ScratchMsgs.locales["sl"] = "DEFAULT_BROADCAST_MESSAGE_NAME": "sporočilo1" }; -Blockly.ScratchMsgs.locales["sr"] = +ScratchMsgs.locales["sr"] = { "CONTROL_FOREVER": "понављај заувек", "CONTROL_REPEAT": "понови %1", @@ -20958,7 +20976,7 @@ Blockly.ScratchMsgs.locales["sr"] = "DEFAULT_BROADCAST_MESSAGE_NAME": "порука1" }; -Blockly.ScratchMsgs.locales["fi"] = +ScratchMsgs.locales["fi"] = { "CONTROL_FOREVER": "ikuisesti", "CONTROL_REPEAT": "toista %1 kertaa", @@ -21245,7 +21263,7 @@ Blockly.ScratchMsgs.locales["fi"] = "DEFAULT_BROADCAST_MESSAGE_NAME": "viesti1" }; -Blockly.ScratchMsgs.locales["sv"] = +ScratchMsgs.locales["sv"] = { "CONTROL_FOREVER": "för alltid", "CONTROL_REPEAT": "repetera %1", @@ -21532,7 +21550,7 @@ Blockly.ScratchMsgs.locales["sv"] = "DEFAULT_BROADCAST_MESSAGE_NAME": "meddelande1" }; -Blockly.ScratchMsgs.locales["vi"] = +ScratchMsgs.locales["vi"] = { "CONTROL_FOREVER": "liên tục", "CONTROL_REPEAT": "lặp lại %1", @@ -21819,7 +21837,7 @@ Blockly.ScratchMsgs.locales["vi"] = "DEFAULT_BROADCAST_MESSAGE_NAME": "tin nhắn 1" }; -Blockly.ScratchMsgs.locales["tr"] = +ScratchMsgs.locales["tr"] = { "CONTROL_FOREVER": "sürekli tekrarla", "CONTROL_REPEAT": "%1 defa tekrarla", @@ -22106,7 +22124,7 @@ Blockly.ScratchMsgs.locales["tr"] = "DEFAULT_BROADCAST_MESSAGE_NAME": "haber1" }; -Blockly.ScratchMsgs.locales["uk"] = +ScratchMsgs.locales["uk"] = { "CONTROL_FOREVER": "завжди", "CONTROL_REPEAT": "повторити %1", @@ -22393,7 +22411,7 @@ Blockly.ScratchMsgs.locales["uk"] = "DEFAULT_BROADCAST_MESSAGE_NAME": "повідомлення1" }; -Blockly.ScratchMsgs.locales["zh-cn"] = +ScratchMsgs.locales["zh-cn"] = { "CONTROL_FOREVER": "重复执行", "CONTROL_REPEAT": "重复执行 %1 次", @@ -22680,7 +22698,7 @@ Blockly.ScratchMsgs.locales["zh-cn"] = "DEFAULT_BROADCAST_MESSAGE_NAME": "消息1" }; -Blockly.ScratchMsgs.locales["zh-tw"] = +ScratchMsgs.locales["zh-tw"] = { "CONTROL_FOREVER": "重複無限次", "CONTROL_REPEAT": "重複 %1 次", @@ -22967,3 +22985,5 @@ Blockly.ScratchMsgs.locales["zh-tw"] = "DEFAULT_BROADCAST_MESSAGE_NAME": "message1" }; // End of combined translations + +export {ScratchMsgs}; diff --git a/src/index.js b/src/index.js index a4db731a03..055ba88537 100644 --- a/src/index.js +++ b/src/index.js @@ -6,3 +6,4 @@ export * from 'blockly'; export * from '../core/colours.js'; +export * from '../msg/scratch_msgs.js'; From 6f36313fdc8cdbd9e934b57c3f4ca6e584f1b0e3 Mon Sep 17 00:00:00 2001 From: Aaron Dodson Date: Mon, 15 Apr 2024 12:32:26 -0700 Subject: [PATCH 005/130] chore: Re-add commitlint and eslint --- .eslintrc | 5 +- package-lock.json | 5574 ++++++++++++++++++++++++++++++++++++++++++++- package.json | 8 +- 3 files changed, 5481 insertions(+), 106 deletions(-) diff --git a/.eslintrc b/.eslintrc index 9b01970189..cad8fcb744 100644 --- a/.eslintrc +++ b/.eslintrc @@ -57,5 +57,8 @@ "Blockly": true, # Blockly global "goog": true, # goog closure libraries/includes }, - "extends": "eslint:recommended" + "extends": "eslint:recommended", + "parserOptions": { + "sourceType": "module", + } } diff --git a/package-lock.json b/package-lock.json index 3ae254c832..77c16a6cd8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,12 +12,471 @@ "blockly": "^10.0.0" }, "devDependencies": { + "@commitlint/cli": "^17.8.1", + "@commitlint/config-conventional": "^17.8.1", + "eslint": "^4.19.1", "source-map-loader": "^4.0.1", "webpack": "^5.76.0", "webpack-cli": "^4.10.0", "webpack-dev-server": "^4.11.1" } }, + "node_modules/@babel/code-frame": { + "version": "7.24.2", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.2.tgz", + "integrity": "sha512-y5+tLQyV8pg3fsiln67BVLD1P13Eg4lh5RW9mF0zUuvLrv9uIQ4MCL+CRT+FTsBlBjcIan6PGsLcBN0m3ClUyQ==", + "dev": true, + "dependencies": { + "@babel/highlight": "^7.24.2", + "picocolors": "^1.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", + "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight": { + "version": "7.24.2", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.2.tgz", + "integrity": "sha512-Yac1ao4flkTxTteCDZLEvdxg2fZfz1v8M4QpaGypq/WPDqg3ijHYbDfs+LG5hvzSoqaSZ9/Z9lKSP3CjZjv+pA==", + "dev": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.22.20", + "chalk": "^2.4.2", + "js-tokens": "^4.0.0", + "picocolors": "^1.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/@babel/highlight/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "node_modules/@babel/highlight/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@commitlint/cli": { + "version": "17.8.1", + "resolved": "https://registry.npmjs.org/@commitlint/cli/-/cli-17.8.1.tgz", + "integrity": "sha512-ay+WbzQesE0Rv4EQKfNbSMiJJ12KdKTDzIt0tcK4k11FdsWmtwP0Kp1NWMOUswfIWo6Eb7p7Ln721Nx9FLNBjg==", + "dev": true, + "dependencies": { + "@commitlint/format": "^17.8.1", + "@commitlint/lint": "^17.8.1", + "@commitlint/load": "^17.8.1", + "@commitlint/read": "^17.8.1", + "@commitlint/types": "^17.8.1", + "execa": "^5.0.0", + "lodash.isfunction": "^3.0.9", + "resolve-from": "5.0.0", + "resolve-global": "1.0.0", + "yargs": "^17.0.0" + }, + "bin": { + "commitlint": "cli.js" + }, + "engines": { + "node": ">=v14" + } + }, + "node_modules/@commitlint/config-conventional": { + "version": "17.8.1", + "resolved": "https://registry.npmjs.org/@commitlint/config-conventional/-/config-conventional-17.8.1.tgz", + "integrity": "sha512-NxCOHx1kgneig3VLauWJcDWS40DVjg7nKOpBEEK9E5fjJpQqLCilcnKkIIjdBH98kEO1q3NpE5NSrZ2kl/QGJg==", + "dev": true, + "dependencies": { + "conventional-changelog-conventionalcommits": "^6.1.0" + }, + "engines": { + "node": ">=v14" + } + }, + "node_modules/@commitlint/config-validator": { + "version": "17.8.1", + "resolved": "https://registry.npmjs.org/@commitlint/config-validator/-/config-validator-17.8.1.tgz", + "integrity": "sha512-UUgUC+sNiiMwkyiuIFR7JG2cfd9t/7MV8VB4TZ+q02ZFkHoduUS4tJGsCBWvBOGD9Btev6IecPMvlWUfJorkEA==", + "dev": true, + "dependencies": { + "@commitlint/types": "^17.8.1", + "ajv": "^8.11.0" + }, + "engines": { + "node": ">=v14" + } + }, + "node_modules/@commitlint/config-validator/node_modules/ajv": { + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", + "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/@commitlint/config-validator/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true + }, + "node_modules/@commitlint/ensure": { + "version": "17.8.1", + "resolved": "https://registry.npmjs.org/@commitlint/ensure/-/ensure-17.8.1.tgz", + "integrity": "sha512-xjafwKxid8s1K23NFpL8JNo6JnY/ysetKo8kegVM7c8vs+kWLP8VrQq+NbhgVlmCojhEDbzQKp4eRXSjVOGsow==", + "dev": true, + "dependencies": { + "@commitlint/types": "^17.8.1", + "lodash.camelcase": "^4.3.0", + "lodash.kebabcase": "^4.1.1", + "lodash.snakecase": "^4.1.1", + "lodash.startcase": "^4.4.0", + "lodash.upperfirst": "^4.3.1" + }, + "engines": { + "node": ">=v14" + } + }, + "node_modules/@commitlint/execute-rule": { + "version": "17.8.1", + "resolved": "https://registry.npmjs.org/@commitlint/execute-rule/-/execute-rule-17.8.1.tgz", + "integrity": "sha512-JHVupQeSdNI6xzA9SqMF+p/JjrHTcrJdI02PwesQIDCIGUrv04hicJgCcws5nzaoZbROapPs0s6zeVHoxpMwFQ==", + "dev": true, + "engines": { + "node": ">=v14" + } + }, + "node_modules/@commitlint/format": { + "version": "17.8.1", + "resolved": "https://registry.npmjs.org/@commitlint/format/-/format-17.8.1.tgz", + "integrity": "sha512-f3oMTyZ84M9ht7fb93wbCKmWxO5/kKSbwuYvS867duVomoOsgrgljkGGIztmT/srZnaiGbaK8+Wf8Ik2tSr5eg==", + "dev": true, + "dependencies": { + "@commitlint/types": "^17.8.1", + "chalk": "^4.1.0" + }, + "engines": { + "node": ">=v14" + } + }, + "node_modules/@commitlint/is-ignored": { + "version": "17.8.1", + "resolved": "https://registry.npmjs.org/@commitlint/is-ignored/-/is-ignored-17.8.1.tgz", + "integrity": "sha512-UshMi4Ltb4ZlNn4F7WtSEugFDZmctzFpmbqvpyxD3la510J+PLcnyhf9chs7EryaRFJMdAKwsEKfNK0jL/QM4g==", + "dev": true, + "dependencies": { + "@commitlint/types": "^17.8.1", + "semver": "7.5.4" + }, + "engines": { + "node": ">=v14" + } + }, + "node_modules/@commitlint/lint": { + "version": "17.8.1", + "resolved": "https://registry.npmjs.org/@commitlint/lint/-/lint-17.8.1.tgz", + "integrity": "sha512-aQUlwIR1/VMv2D4GXSk7PfL5hIaFSfy6hSHV94O8Y27T5q+DlDEgd/cZ4KmVI+MWKzFfCTiTuWqjfRSfdRllCA==", + "dev": true, + "dependencies": { + "@commitlint/is-ignored": "^17.8.1", + "@commitlint/parse": "^17.8.1", + "@commitlint/rules": "^17.8.1", + "@commitlint/types": "^17.8.1" + }, + "engines": { + "node": ">=v14" + } + }, + "node_modules/@commitlint/load": { + "version": "17.8.1", + "resolved": "https://registry.npmjs.org/@commitlint/load/-/load-17.8.1.tgz", + "integrity": "sha512-iF4CL7KDFstP1kpVUkT8K2Wl17h2yx9VaR1ztTc8vzByWWcbO/WaKwxsnCOqow9tVAlzPfo1ywk9m2oJ9ucMqA==", + "dev": true, + "dependencies": { + "@commitlint/config-validator": "^17.8.1", + "@commitlint/execute-rule": "^17.8.1", + "@commitlint/resolve-extends": "^17.8.1", + "@commitlint/types": "^17.8.1", + "@types/node": "20.5.1", + "chalk": "^4.1.0", + "cosmiconfig": "^8.0.0", + "cosmiconfig-typescript-loader": "^4.0.0", + "lodash.isplainobject": "^4.0.6", + "lodash.merge": "^4.6.2", + "lodash.uniq": "^4.5.0", + "resolve-from": "^5.0.0", + "ts-node": "^10.8.1", + "typescript": "^4.6.4 || ^5.2.2" + }, + "engines": { + "node": ">=v14" + } + }, + "node_modules/@commitlint/load/node_modules/@types/node": { + "version": "20.5.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.5.1.tgz", + "integrity": "sha512-4tT2UrL5LBqDwoed9wZ6N3umC4Yhz3W3FloMmiiG4JwmUJWpie0c7lcnUNd4gtMKuDEO4wRVS8B6Xa0uMRsMKg==", + "dev": true + }, + "node_modules/@commitlint/message": { + "version": "17.8.1", + "resolved": "https://registry.npmjs.org/@commitlint/message/-/message-17.8.1.tgz", + "integrity": "sha512-6bYL1GUQsD6bLhTH3QQty8pVFoETfFQlMn2Nzmz3AOLqRVfNNtXBaSY0dhZ0dM6A2MEq4+2d7L/2LP8TjqGRkA==", + "dev": true, + "engines": { + "node": ">=v14" + } + }, + "node_modules/@commitlint/parse": { + "version": "17.8.1", + "resolved": "https://registry.npmjs.org/@commitlint/parse/-/parse-17.8.1.tgz", + "integrity": "sha512-/wLUickTo0rNpQgWwLPavTm7WbwkZoBy3X8PpkUmlSmQJyWQTj0m6bDjiykMaDt41qcUbfeFfaCvXfiR4EGnfw==", + "dev": true, + "dependencies": { + "@commitlint/types": "^17.8.1", + "conventional-changelog-angular": "^6.0.0", + "conventional-commits-parser": "^4.0.0" + }, + "engines": { + "node": ">=v14" + } + }, + "node_modules/@commitlint/read": { + "version": "17.8.1", + "resolved": "https://registry.npmjs.org/@commitlint/read/-/read-17.8.1.tgz", + "integrity": "sha512-Fd55Oaz9irzBESPCdMd8vWWgxsW3OWR99wOntBDHgf9h7Y6OOHjWEdS9Xzen1GFndqgyoaFplQS5y7KZe0kO2w==", + "dev": true, + "dependencies": { + "@commitlint/top-level": "^17.8.1", + "@commitlint/types": "^17.8.1", + "fs-extra": "^11.0.0", + "git-raw-commits": "^2.0.11", + "minimist": "^1.2.6" + }, + "engines": { + "node": ">=v14" + } + }, + "node_modules/@commitlint/resolve-extends": { + "version": "17.8.1", + "resolved": "https://registry.npmjs.org/@commitlint/resolve-extends/-/resolve-extends-17.8.1.tgz", + "integrity": "sha512-W/ryRoQ0TSVXqJrx5SGkaYuAaE/BUontL1j1HsKckvM6e5ZaG0M9126zcwL6peKSuIetJi7E87PRQF8O86EW0Q==", + "dev": true, + "dependencies": { + "@commitlint/config-validator": "^17.8.1", + "@commitlint/types": "^17.8.1", + "import-fresh": "^3.0.0", + "lodash.mergewith": "^4.6.2", + "resolve-from": "^5.0.0", + "resolve-global": "^1.0.0" + }, + "engines": { + "node": ">=v14" + } + }, + "node_modules/@commitlint/rules": { + "version": "17.8.1", + "resolved": "https://registry.npmjs.org/@commitlint/rules/-/rules-17.8.1.tgz", + "integrity": "sha512-2b7OdVbN7MTAt9U0vKOYKCDsOvESVXxQmrvuVUZ0rGFMCrCPJWWP1GJ7f0lAypbDAhaGb8zqtdOr47192LBrIA==", + "dev": true, + "dependencies": { + "@commitlint/ensure": "^17.8.1", + "@commitlint/message": "^17.8.1", + "@commitlint/to-lines": "^17.8.1", + "@commitlint/types": "^17.8.1", + "execa": "^5.0.0" + }, + "engines": { + "node": ">=v14" + } + }, + "node_modules/@commitlint/to-lines": { + "version": "17.8.1", + "resolved": "https://registry.npmjs.org/@commitlint/to-lines/-/to-lines-17.8.1.tgz", + "integrity": "sha512-LE0jb8CuR/mj6xJyrIk8VLz03OEzXFgLdivBytoooKO5xLt5yalc8Ma5guTWobw998sbR3ogDd+2jed03CFmJA==", + "dev": true, + "engines": { + "node": ">=v14" + } + }, + "node_modules/@commitlint/top-level": { + "version": "17.8.1", + "resolved": "https://registry.npmjs.org/@commitlint/top-level/-/top-level-17.8.1.tgz", + "integrity": "sha512-l6+Z6rrNf5p333SHfEte6r+WkOxGlWK4bLuZKbtf/2TXRN+qhrvn1XE63VhD8Oe9oIHQ7F7W1nG2k/TJFhx2yA==", + "dev": true, + "dependencies": { + "find-up": "^5.0.0" + }, + "engines": { + "node": ">=v14" + } + }, + "node_modules/@commitlint/top-level/node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@commitlint/top-level/node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@commitlint/top-level/node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@commitlint/top-level/node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@commitlint/types": { + "version": "17.8.1", + "resolved": "https://registry.npmjs.org/@commitlint/types/-/types-17.8.1.tgz", + "integrity": "sha512-PXDQXkAmiMEG162Bqdh9ChML/GJZo6vU+7F03ALKDK8zYc6SuAr47LjG7hGYRqUOz+WK0dU7bQ0xzuqFMdxzeQ==", + "dev": true, + "dependencies": { + "chalk": "^4.1.0" + }, + "engines": { + "node": ">=v14" + } + }, + "node_modules/@cspotcode/source-map-support": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "dev": true, + "dependencies": { + "@jridgewell/trace-mapping": "0.3.9" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@cspotcode/source-map-support/node_modules/@jridgewell/trace-mapping": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "dev": true, + "dependencies": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, "node_modules/@discoveryjs/json-ext": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz", @@ -99,6 +558,30 @@ "node": ">= 10" } }, + "node_modules/@tsconfig/node10": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz", + "integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==", + "dev": true + }, + "node_modules/@tsconfig/node12": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", + "dev": true + }, + "node_modules/@tsconfig/node14": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", + "dev": true + }, + "node_modules/@tsconfig/node16": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", + "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", + "dev": true + }, "node_modules/@types/body-parser": { "version": "1.19.5", "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz", @@ -214,6 +697,12 @@ "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==", "dev": true }, + "node_modules/@types/minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-hov8bUuiLiyFPGyFPE1lwWhmzYbirOXQNNo40+y3zow8aFVTeyn3VWL0VFFfdNddA8S4Vf0Tc062rzyNr7Paag==", + "dev": true + }, "node_modules/@types/node": { "version": "20.10.5", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.10.5.tgz", @@ -232,6 +721,12 @@ "@types/node": "*" } }, + "node_modules/@types/normalize-package-data": { + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.4.tgz", + "integrity": "sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==", + "dev": true + }, "node_modules/@types/qs": { "version": "6.9.10", "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.10.tgz", @@ -532,21 +1027,51 @@ "acorn": "^8" } }, - "node_modules/agent-base": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", - "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "node_modules/acorn-jsx": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz", + "integrity": "sha512-AU7pnZkguthwBjKgCg6998ByQNIMjbuDQZ8bb78QAFZwPfmKia8AIzgY/gWgqCjnht8JLdXmB4YxA0KaV60ncQ==", + "dev": true, "dependencies": { - "debug": "4" - }, - "engines": { - "node": ">= 6.0.0" + "acorn": "^3.0.4" } }, - "node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "node_modules/acorn-jsx/node_modules/acorn": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz", + "integrity": "sha512-OLUyIIZ7mF5oaAUT1w0TFqQS81q3saT46x8t7ukpPjMNk+nbs4ZHhs7ToV8EWnLYLepjETXd4XaCE4uxkMeqUw==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-walk": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.2.tgz", + "integrity": "sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, "dependencies": { "fast-deep-equal": "^3.1.1", @@ -607,6 +1132,15 @@ "ajv": "^6.9.1" } }, + "node_modules/ansi-escapes": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz", + "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, "node_modules/ansi-html-community": { "version": "0.0.8", "resolved": "https://registry.npmjs.org/ansi-html-community/-/ansi-html-community-0.0.8.tgz", @@ -619,6 +1153,30 @@ "ansi-html": "bin/ansi-html" } }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, "node_modules/anymatch": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", @@ -632,17 +1190,116 @@ "node": ">= 8" } }, + "node_modules/arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "dev": true + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, "node_modules/array-flatten": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-2.1.2.tgz", "integrity": "sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ==", "dev": true }, + "node_modules/array-ify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array-ify/-/array-ify-1.0.0.tgz", + "integrity": "sha512-c5AMf34bKdvPhQ7tBGhqkgKNUzMr4WUs+WDtC2ZUGOUncbxKMTvqxYctiseW3+L4bA8ec+GcZ6/A/FW4m8ukng==", + "dev": true + }, + "node_modules/arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" }, + "node_modules/babel-code-frame": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", + "integrity": "sha512-XqYMR2dfdGMW+hd0IUZ2PwK+fGeFkOxZJ0wY+JaQAHzt1Zx8LcvpiZD2NiGkEG8qx0CfkAOr5xt76d1e8vG90g==", + "dev": true, + "dependencies": { + "chalk": "^1.1.3", + "esutils": "^2.0.2", + "js-tokens": "^3.0.2" + } + }, + "node_modules/babel-code-frame/node_modules/ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/babel-code-frame/node_modules/ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha512-kmCevFghRiWM7HB5zTPULl4r9bVFSWjz62MhqizDGUrq2NWuNMQyuv4tHHoKJHs69M/MF64lEcHdYIocrdWQYA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/babel-code-frame/node_modules/chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha512-U3lRVLMSlsCfjqYPbLyVv11M9CPW4I728d6TCKMAOJueEeB9/8o+eSsMnxPJD+Q+K909sdESg7C+tIkoH6on1A==", + "dev": true, + "dependencies": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/babel-code-frame/node_modules/js-tokens": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", + "integrity": "sha512-RjTcuD4xjtthQkaWH7dFlH85L+QaVtSoOyGdZ3g6HFhS9dFNDfLyqgm2NFe2X6cQpeFmt0452FJjFG5UameExg==", + "dev": true + }, + "node_modules/babel-code-frame/node_modules/strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==", + "dev": true, + "dependencies": { + "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/babel-code-frame/node_modules/supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha512-KKNVtd6pCYgPIKU4cp2733HWYCpplQhddZLBUryaAHou723x+FRzQ5Df824Fj+IyyuiQTRoub4SnIFfIcrp70g==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", @@ -827,6 +1484,62 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/caller-path": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz", + "integrity": "sha512-UJiE1otjXPF5/x+T3zTnSFiTOEmJoGTD9HmBoxnCUwho61a2eSNn/VwtwuIBDAo2SEOv1AJ7ARI5gCmohFLu/g==", + "dev": true, + "dependencies": { + "callsites": "^0.2.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/caller-path/node_modules/callsites": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz", + "integrity": "sha512-Zv4Dns9IbXXmPkgRRUjAaJQgfN4xX5p6+RQFhWUqscdvvK2xK/ZL8b3IXIJsj+4sD+f24NwnWy2BY8AJ82JB0A==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/camelcase-keys": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-6.2.2.tgz", + "integrity": "sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==", + "dev": true, + "dependencies": { + "camelcase": "^5.3.1", + "map-obj": "^4.0.0", + "quick-lru": "^4.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/caniuse-lite": { "version": "1.0.30001570", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001570.tgz", @@ -847,6 +1560,40 @@ } ] }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/chalk/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/chardet": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.4.2.tgz", + "integrity": "sha512-j/Toj7f1z98Hh2cYo2BVr85EpIRWqUi7rtRSGxh/cqUjqrnJe9l9UE7IUGd2vQ2p+kSHLkSzObQPZPLUC6TQwg==", + "dev": true + }, "node_modules/chokidar": { "version": "3.5.3", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", @@ -883,6 +1630,45 @@ "node": ">=6.0" } }, + "node_modules/circular-json": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz", + "integrity": "sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A==", + "deprecated": "CircularJSON is in maintenance only, flatted is its successor.", + "dev": true + }, + "node_modules/cli-cursor": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", + "integrity": "sha512-8lgKz8LmCRYZZQDpRyT2m5rKJ08TnU4tR9FFFW2rxpxR1FzWi4PQ/NfyODchAatHaUgnSPVcx/R5w6NuTBzFiw==", + "dev": true, + "dependencies": { + "restore-cursor": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/cli-width": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.1.tgz", + "integrity": "sha512-GRMWDxpOB6Dgk2E5Uo+3eEBvtOOlimMmpbFiKuLFnQzYDavtLFY3K5ona41jgN/WdRZtG7utuVSVTL4HbZHGkw==", + "dev": true + }, + "node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/clone-deep": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", @@ -897,6 +1683,34 @@ "node": ">=6" } }, + "node_modules/co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", + "dev": true, + "engines": { + "iojs": ">= 1.0.0", + "node": ">= 0.12.0" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, "node_modules/colorette": { "version": "2.0.20", "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", @@ -920,6 +1734,16 @@ "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", "dev": true }, + "node_modules/compare-func": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/compare-func/-/compare-func-2.0.0.tgz", + "integrity": "sha512-zHig5N+tPWARooBnb0Zx1MFcdfpyJrfTJ3Y5L+IFvUm8rM74hHz66z0gw0x4tijh5CorKkKUCnW82R2vmpeCRA==", + "dev": true, + "dependencies": { + "array-ify": "^1.0.0", + "dot-prop": "^5.1.0" + } + }, "node_modules/compressible": { "version": "2.0.18", "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", @@ -977,6 +1801,51 @@ "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", "dev": true }, + "node_modules/concat-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", + "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "dev": true, + "engines": [ + "node >= 0.8" + ], + "dependencies": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + } + }, + "node_modules/concat-stream/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dev": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/concat-stream/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "node_modules/concat-stream/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, "node_modules/connect-history-api-fallback": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-2.0.0.tgz", @@ -1007,27 +1876,116 @@ "node": ">= 0.6" } }, - "node_modules/cookie": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", - "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", + "node_modules/conventional-changelog-angular": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-6.0.0.tgz", + "integrity": "sha512-6qLgrBF4gueoC7AFVHu51nHL9pF9FRjXrH+ceVf7WmAfH3gs+gEYOkvxhjMPjZu57I4AGUGoNTY8V7Hrgf1uqg==", "dev": true, + "dependencies": { + "compare-func": "^2.0.0" + }, "engines": { - "node": ">= 0.6" + "node": ">=14" } }, - "node_modules/cookie-signature": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", - "dev": true + "node_modules/conventional-changelog-conventionalcommits": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/conventional-changelog-conventionalcommits/-/conventional-changelog-conventionalcommits-6.1.0.tgz", + "integrity": "sha512-3cS3GEtR78zTfMzk0AizXKKIdN4OvSh7ibNz6/DPbhWWQu7LqE/8+/GqSodV+sywUR2gpJAdP/1JFf4XtN7Zpw==", + "dev": true, + "dependencies": { + "compare-func": "^2.0.0" + }, + "engines": { + "node": ">=14" + } }, - "node_modules/core-util-is": { - "version": "1.0.3", + "node_modules/conventional-commits-parser": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-4.0.0.tgz", + "integrity": "sha512-WRv5j1FsVM5FISJkoYMR6tPk07fkKT0UodruX4je86V4owk451yjXAKzKAPOs9l7y59E2viHUS9eQ+dfUA9NSg==", + "dev": true, + "dependencies": { + "is-text-path": "^1.0.1", + "JSONStream": "^1.3.5", + "meow": "^8.1.2", + "split2": "^3.2.2" + }, + "bin": { + "conventional-commits-parser": "cli.js" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/cookie": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", + "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", + "dev": true + }, + "node_modules/core-util-is": { + "version": "1.0.3", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", "dev": true }, + "node_modules/cosmiconfig": { + "version": "8.3.6", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.3.6.tgz", + "integrity": "sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==", + "dev": true, + "dependencies": { + "import-fresh": "^3.3.0", + "js-yaml": "^4.1.0", + "parse-json": "^5.2.0", + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/d-fischer" + }, + "peerDependencies": { + "typescript": ">=4.9.5" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/cosmiconfig-typescript-loader": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/cosmiconfig-typescript-loader/-/cosmiconfig-typescript-loader-4.4.0.tgz", + "integrity": "sha512-BabizFdC3wBHhbI4kJh0VkQP9GkBfoHPydD0COMce1nJ1kJAB3F2TmJ/I7diULBKtmEWSwEbuN/KDtgnmUUVmw==", + "dev": true, + "engines": { + "node": ">=v14.21.3" + }, + "peerDependencies": { + "@types/node": "*", + "cosmiconfig": ">=7", + "ts-node": ">=10", + "typescript": ">=4" + } + }, + "node_modules/create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", + "dev": true + }, "node_modules/cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", @@ -1053,6 +2011,15 @@ "node": ">=14" } }, + "node_modules/dargs": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/dargs/-/dargs-7.0.0.tgz", + "integrity": "sha512-2iy1EkLdlBzQGvbweYRFxmFath8+K7+AKB0TlhHWkNuH+TmovaMH/Wp7V7R4u7f4SnX3OgLsU9t1NI9ioDnUpg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/data-urls": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-4.0.0.tgz", @@ -1082,11 +2049,51 @@ } } }, + "node_modules/decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/decamelize-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.1.tgz", + "integrity": "sha512-WiPxgEirIV0/eIOMcnFBA3/IJZAZqKnwAwWyvvdi4lsr1WCN22nhdf/3db3DoZcUjTV2SqfzIwNyp6y2xs3nmg==", + "dev": true, + "dependencies": { + "decamelize": "^1.1.0", + "map-obj": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/decamelize-keys/node_modules/map-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", + "integrity": "sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/decimal.js": { "version": "10.4.3", "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.3.tgz", "integrity": "sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==" }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true + }, "node_modules/default-gateway": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-6.0.3.tgz", @@ -1155,6 +2162,15 @@ "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==", "dev": true }, + "node_modules/diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true, + "engines": { + "node": ">=0.3.1" + } + }, "node_modules/dns-equal": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/dns-equal/-/dns-equal-1.0.0.tgz", @@ -1173,6 +2189,18 @@ "node": ">=6" } }, + "node_modules/doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/domexception": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/domexception/-/domexception-4.0.0.tgz", @@ -1185,6 +2213,18 @@ "node": ">=12" } }, + "node_modules/dot-prop": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", + "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==", + "dev": true, + "dependencies": { + "is-obj": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", @@ -1197,6 +2237,12 @@ "integrity": "sha512-/bKPPcgZVUziECqDc+0HkT87+0zhaWSZHNXqF8FLd2lQcptpmUFwoCSWjCdOng9Gdq+afKArPdEg/0ZW461Eng==", "dev": true }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, "node_modules/encodeurl": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", @@ -1242,6 +2288,15 @@ "node": ">=4" } }, + "node_modules/error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, "node_modules/es-module-lexer": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.4.1.tgz", @@ -1263,6 +2318,67 @@ "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", "dev": true }, + "node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/eslint": { + "version": "4.19.1", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-4.19.1.tgz", + "integrity": "sha512-bT3/1x1EbZB7phzYu7vCr1v3ONuzDtX8WjuM9c0iYxe+cq+pwcKEoQjl7zd3RpC6YOLgnSy3cTN58M2jcoPDIQ==", + "dev": true, + "dependencies": { + "ajv": "^5.3.0", + "babel-code-frame": "^6.22.0", + "chalk": "^2.1.0", + "concat-stream": "^1.6.0", + "cross-spawn": "^5.1.0", + "debug": "^3.1.0", + "doctrine": "^2.1.0", + "eslint-scope": "^3.7.1", + "eslint-visitor-keys": "^1.0.0", + "espree": "^3.5.4", + "esquery": "^1.0.0", + "esutils": "^2.0.2", + "file-entry-cache": "^2.0.0", + "functional-red-black-tree": "^1.0.1", + "glob": "^7.1.2", + "globals": "^11.0.1", + "ignore": "^3.3.3", + "imurmurhash": "^0.1.4", + "inquirer": "^3.0.6", + "is-resolvable": "^1.0.0", + "js-yaml": "^3.9.1", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.3.0", + "lodash": "^4.17.4", + "minimatch": "^3.0.2", + "mkdirp": "^0.5.1", + "natural-compare": "^1.4.0", + "optionator": "^0.8.2", + "path-is-inside": "^1.0.2", + "pluralize": "^7.0.0", + "progress": "^2.0.0", + "regexpp": "^1.0.1", + "require-uncached": "^1.0.3", + "semver": "^5.3.0", + "strip-ansi": "^4.0.0", + "strip-json-comments": "~2.0.1", + "table": "4.0.2", + "text-table": "~0.2.0" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/eslint-scope": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", @@ -1276,6 +2392,294 @@ "node": ">=8.0.0" } }, + "node_modules/eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint/node_modules/ajv": { + "version": "5.5.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz", + "integrity": "sha512-Ajr4IcMXq/2QmMkEmSvxqfLN5zGmJ92gHXAeOXq1OekoH2rfDNsgdDoL2f7QaRCy7G/E6TpxBVdRuNraMztGHw==", + "dev": true, + "dependencies": { + "co": "^4.6.0", + "fast-deep-equal": "^1.0.0", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.3.0" + } + }, + "node_modules/eslint/node_modules/ansi-regex": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz", + "integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint/node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/eslint/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/eslint/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "node_modules/eslint/node_modules/cross-spawn": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", + "integrity": "sha512-pTgQJ5KC0d2hcY8eyL1IzlBPYjTkyH72XRZPnLyKus2mBfNjQs3klqbJU2VILqZryAZUt9JOb3h/mWMy23/f5A==", + "dev": true, + "dependencies": { + "lru-cache": "^4.0.1", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "node_modules/eslint/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint/node_modules/eslint-scope": { + "version": "3.7.3", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-3.7.3.tgz", + "integrity": "sha512-W+B0SvF4gamyCTmUc+uITPY0989iXVfKvhwtmJocTaYoc/3khEHmEmvfY/Gn9HA9VV75jrQECsHizkNw1b68FA==", + "dev": true, + "dependencies": { + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/eslint/node_modules/fast-deep-equal": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz", + "integrity": "sha512-fueX787WZKCV0Is4/T2cyAdM4+x1S3MXXOAhavE1ys/W42SHAPacLTQhucja22QBYrfGw50M2sRiXPtTGv9Ymw==", + "dev": true + }, + "node_modules/eslint/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint/node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/eslint/node_modules/json-schema-traverse": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz", + "integrity": "sha512-4JD/Ivzg7PoW8NzdrBSr3UFwC9mHgvI7Z6z3QGBsSHgKaRTUDmyZAAKJo2UbG1kUVfS9WS8bi36N49U1xw43DA==", + "dev": true + }, + "node_modules/eslint/node_modules/lru-cache": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", + "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", + "dev": true, + "dependencies": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + }, + "node_modules/eslint/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/eslint/node_modules/shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==", + "dev": true, + "dependencies": { + "shebang-regex": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint/node_modules/shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint/node_modules/strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==", + "dev": true, + "dependencies": { + "ansi-regex": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint/node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "node_modules/eslint/node_modules/yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==", + "dev": true + }, + "node_modules/espree": { + "version": "3.5.4", + "resolved": "https://registry.npmjs.org/espree/-/espree-3.5.4.tgz", + "integrity": "sha512-yAcIQxtmMiB/jL32dzEp2enBeidsB7xWPLNiw3IIkpVds1P+h7qF9YwJq1yUNzp2OKXgAprs4F61ih66UsoD1A==", + "dev": true, + "dependencies": { + "acorn": "^5.5.0", + "acorn-jsx": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/espree/node_modules/acorn": { + "version": "5.7.4", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.4.tgz", + "integrity": "sha512-1D++VG7BhrtvQpNbBzovKNc1FLGGEE/oGe7b9xJm/RFHMBeUaUGpluV9RLjZa47YFdPcDAenEYuq9pQPcMdLJg==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true, + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/esquery": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", + "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", + "dev": true, + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esquery/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, "node_modules/esrecurse": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", @@ -1306,6 +2710,15 @@ "node": ">=4.0" } }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/etag": { "version": "1.8.1", "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", @@ -1416,6 +2829,32 @@ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", "dev": true }, + "node_modules/external-editor": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-2.2.0.tgz", + "integrity": "sha512-bSn6gvGxKt+b7+6TKEv1ZycHleA7aHhRHyAqJyp5pbUFuYYNIzpZnQDk7AsYckyWdEnTeAnay0aCy2aV6iTk9A==", + "dev": true, + "dependencies": { + "chardet": "^0.4.0", + "iconv-lite": "^0.4.17", + "tmp": "^0.0.33" + }, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/external-editor/node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -1428,6 +2867,12 @@ "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", "dev": true }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true + }, "node_modules/fastest-levenshtein": { "version": "1.0.16", "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz", @@ -1449,6 +2894,31 @@ "node": ">=0.8.0" } }, + "node_modules/figures": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", + "integrity": "sha512-Oa2M9atig69ZkfwiApY8F2Yy+tzMbazyvqv21R0NsSC8floSOC09BbT1ITWAdoMGQvJ/aZnR1KMwdx9tvHnTNA==", + "dev": true, + "dependencies": { + "escape-string-regexp": "^1.0.5" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/file-entry-cache": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-2.0.0.tgz", + "integrity": "sha512-uXP/zGzxxFvFfcZGgBIwotm+Tdc55ddPAzF7iHshP4YGaXMww7rSF9peD9D1sui5ebONg5UobsZv+FfgEpGv/w==", + "dev": true, + "dependencies": { + "flat-cache": "^1.2.1", + "object-assign": "^4.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/fill-range": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", @@ -1516,6 +2986,33 @@ "flat": "cli.js" } }, + "node_modules/flat-cache": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.3.4.tgz", + "integrity": "sha512-VwyB3Lkgacfik2vhqR4uv2rvebqmDvFu4jlN/C1RzWoJEo8I7z4Q404oiqYCkq41mni8EzQnm95emU9seckwtg==", + "dev": true, + "dependencies": { + "circular-json": "^0.3.1", + "graceful-fs": "^4.1.2", + "rimraf": "~2.6.2", + "write": "^0.2.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/flat-cache/node_modules/rimraf": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", + "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, "node_modules/follow-redirects": { "version": "1.15.3", "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.3.tgz", @@ -1567,6 +3064,29 @@ "node": ">= 0.6" } }, + "node_modules/fs-extra": { + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz", + "integrity": "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=14.14" + } + }, + "node_modules/fs-extra/node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "dev": true, + "engines": { + "node": ">= 10.0.0" + } + }, "node_modules/fs-monkey": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.0.5.tgz", @@ -1602,6 +3122,21 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==", + "dev": true + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, "node_modules/get-intrinsic": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.2.tgz", @@ -1629,6 +3164,25 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/git-raw-commits": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/git-raw-commits/-/git-raw-commits-2.0.11.tgz", + "integrity": "sha512-VnctFhw+xfj8Va1xtfEqCUD2XDrbAPSJx+hSrE5K7fGdjZruW7XV+QOrN7LF/RJyvspRiD2I0asWsxFp0ya26A==", + "dev": true, + "dependencies": { + "dargs": "^7.0.0", + "lodash": "^4.17.15", + "meow": "^8.0.0", + "split2": "^3.0.0", + "through2": "^4.0.0" + }, + "bin": { + "git-raw-commits": "cli.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/glob": { "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", @@ -1667,6 +3221,27 @@ "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", "dev": true }, + "node_modules/global-dirs": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-0.1.1.tgz", + "integrity": "sha512-NknMLn7F2J7aflwFOlGdNIuCDpN3VGoSoB+aap3KABFWbHVn1TCgFC+np23J8W2BiZbjfEw3BFBycSMv1AFblg==", + "dev": true, + "dependencies": { + "ini": "^1.3.4" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, "node_modules/gopd": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", @@ -1691,6 +3266,36 @@ "integrity": "sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==", "dev": true }, + "node_modules/hard-rejection": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz", + "integrity": "sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha512-C8vBJ8DwUCx19vhm7urhTuUsr4/IyP6l4VzNQDv+ryHQObW3TTTp9yB68WpYgRe2bbaGuZ/se74IqFeVnMnLZg==", + "dev": true, + "dependencies": { + "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/has-ansi/node_modules/ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -1748,6 +3353,18 @@ "node": ">= 0.4" } }, + "node_modules/hosted-git-info": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz", + "integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/hpack.js": { "version": "2.1.6", "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz", @@ -1928,6 +3545,37 @@ "node": ">=0.10.0" } }, + "node_modules/ignore": { + "version": "3.3.10", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.10.tgz", + "integrity": "sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug==", + "dev": true + }, + "node_modules/import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/import-fresh/node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, "node_modules/import-local": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", @@ -1947,6 +3595,24 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", @@ -1963,6 +3629,139 @@ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true }, + "node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "dev": true + }, + "node_modules/inquirer": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-3.3.0.tgz", + "integrity": "sha512-h+xtnyk4EwKvFWHrUYsWErEVR+igKtLdchu+o0Z1RL7VU/jVMFbYir2bp6bAj8efFNxWqHX0dIss6fJQ+/+qeQ==", + "dev": true, + "dependencies": { + "ansi-escapes": "^3.0.0", + "chalk": "^2.0.0", + "cli-cursor": "^2.1.0", + "cli-width": "^2.0.0", + "external-editor": "^2.0.4", + "figures": "^2.0.0", + "lodash": "^4.3.0", + "mute-stream": "0.0.7", + "run-async": "^2.2.0", + "rx-lite": "^4.0.8", + "rx-lite-aggregates": "^4.0.8", + "string-width": "^2.1.0", + "strip-ansi": "^4.0.0", + "through": "^2.3.6" + } + }, + "node_modules/inquirer/node_modules/ansi-regex": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz", + "integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/inquirer/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/inquirer/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/inquirer/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/inquirer/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "node_modules/inquirer/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/inquirer/node_modules/is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/inquirer/node_modules/string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "dependencies": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/inquirer/node_modules/strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==", + "dev": true, + "dependencies": { + "ansi-regex": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/inquirer/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/interpret": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/interpret/-/interpret-2.2.0.tgz", @@ -1981,6 +3780,12 @@ "node": ">= 10" } }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "dev": true + }, "node_modules/is-binary-path": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", @@ -2029,6 +3834,15 @@ "node": ">=0.10.0" } }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/is-glob": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", @@ -2050,6 +3864,15 @@ "node": ">=0.12.0" } }, + "node_modules/is-obj": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", + "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/is-plain-obj": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-3.0.0.tgz", @@ -2079,6 +3902,12 @@ "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==" }, + "node_modules/is-resolvable": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz", + "integrity": "sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==", + "dev": true + }, "node_modules/is-stream": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", @@ -2091,6 +3920,18 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/is-text-path": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-text-path/-/is-text-path-1.0.1.tgz", + "integrity": "sha512-xFuJpne9oFz5qDaodwmmG08e3CawH/2ZV8Qqza1Ko7Sk8POWbkRdwIoAWVhqvq0XeUzANEhKo2n0IXUGBm7A/w==", + "dev": true, + "dependencies": { + "text-extensions": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/is-wsl": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", @@ -2138,6 +3979,24 @@ "node": ">= 10.13.0" } }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, "node_modules/jsdom": { "version": "22.1.0", "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-22.1.0.tgz", @@ -2191,6 +4050,58 @@ "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", "dev": true }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true + }, + "node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/jsonfile/node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "dev": true, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/jsonparse": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", + "integrity": "sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==", + "dev": true, + "engines": [ + "node >= 0.2.0" + ] + }, + "node_modules/JSONStream": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz", + "integrity": "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==", + "dev": true, + "dependencies": { + "jsonparse": "^1.2.0", + "through": ">=2.2.7 <3" + }, + "bin": { + "JSONStream": "bin.js" + }, + "engines": { + "node": "*" + } + }, "node_modules/kind-of": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", @@ -2210,6 +4121,25 @@ "shell-quote": "^1.8.1" } }, + "node_modules/levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==", + "dev": true, + "dependencies": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true + }, "node_modules/loader-runner": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", @@ -2231,6 +4161,102 @@ "node": ">=8" } }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true + }, + "node_modules/lodash.camelcase": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", + "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==", + "dev": true + }, + "node_modules/lodash.isfunction": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/lodash.isfunction/-/lodash.isfunction-3.0.9.tgz", + "integrity": "sha512-AirXNj15uRIMMPihnkInB4i3NHeb4iBtNg9WRWuK2o31S+ePwwNmDPaTL3o7dTJ+VXNZim7rFs4rxN4YU1oUJw==", + "dev": true + }, + "node_modules/lodash.isplainobject": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", + "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==", + "dev": true + }, + "node_modules/lodash.kebabcase": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.kebabcase/-/lodash.kebabcase-4.1.1.tgz", + "integrity": "sha512-N8XRTIMMqqDgSy4VLKPnJ/+hpGZN+PHQiJnSenYqPaVV/NCqEogTnAdZLQiGKhxX+JCs8waWq2t1XHWKOmlY8g==", + "dev": true + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, + "node_modules/lodash.mergewith": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.mergewith/-/lodash.mergewith-4.6.2.tgz", + "integrity": "sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ==", + "dev": true + }, + "node_modules/lodash.snakecase": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.snakecase/-/lodash.snakecase-4.1.1.tgz", + "integrity": "sha512-QZ1d4xoBHYUeuouhEq3lk3Uq7ldgyFXGBhg04+oRLnIz8o9T65Eh+8YdroUwn846zchkA9yDsDl5CVVaV2nqYw==", + "dev": true + }, + "node_modules/lodash.startcase": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.startcase/-/lodash.startcase-4.4.0.tgz", + "integrity": "sha512-+WKqsK294HMSc2jEbNgpHpd0JfIBhp7rEV4aqXWqFr6AlXov+SlcgB1Fv01y2kGe3Gc8nMW7VA0SrGuSkRfIEg==", + "dev": true + }, + "node_modules/lodash.uniq": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", + "integrity": "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==", + "dev": true + }, + "node_modules/lodash.upperfirst": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/lodash.upperfirst/-/lodash.upperfirst-4.3.1.tgz", + "integrity": "sha512-sReKOYJIJf74dhJONhU4e0/shzi1trVbSWDOhKYE5XV2O+H7Sb2Dihwuc7xWxVl+DgFPyTqIN3zMfT9cq5iWDg==", + "dev": true + }, + "node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true + }, + "node_modules/map-obj": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.3.0.tgz", + "integrity": "sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", @@ -2252,6 +4278,31 @@ "node": ">= 4.0.0" } }, + "node_modules/meow": { + "version": "8.1.2", + "resolved": "https://registry.npmjs.org/meow/-/meow-8.1.2.tgz", + "integrity": "sha512-r85E3NdZ+mpYk1C6RjPFEMSE+s1iZMuHtsHAqY0DT3jZczl0diWUZ8g6oU7h0M9cD2EL+PzaYghhCLzR0ZNn5Q==", + "dev": true, + "dependencies": { + "@types/minimist": "^1.2.0", + "camelcase-keys": "^6.2.2", + "decamelize-keys": "^1.1.0", + "hard-rejection": "^2.1.0", + "minimist-options": "4.1.0", + "normalize-package-data": "^3.0.0", + "read-pkg-up": "^7.0.1", + "redent": "^3.0.0", + "trim-newlines": "^3.0.0", + "type-fest": "^0.18.0", + "yargs-parser": "^20.2.3" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/merge-descriptors": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", @@ -2326,6 +4377,15 @@ "node": ">=6" } }, + "node_modules/min-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", + "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", + "dev": true, + "engines": { + "node": ">=4" + } + }, "node_modules/minimalistic-assert": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", @@ -2344,6 +4404,50 @@ "node": "*" } }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/minimist-options": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-4.1.0.tgz", + "integrity": "sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==", + "dev": true, + "dependencies": { + "arrify": "^1.0.1", + "is-plain-obj": "^1.1.0", + "kind-of": "^6.0.3" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/minimist-options/node_modules/is-plain-obj": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", + "integrity": "sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "dev": true, + "dependencies": { + "minimist": "^1.2.6" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, "node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -2362,6 +4466,18 @@ "multicast-dns": "cli.js" } }, + "node_modules/mute-stream": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", + "integrity": "sha512-r65nCZhrbXXb6dXOACihYApHw2Q6pV0M3V0PSxd74N0+D8nzAdEAITq2oAjA1jVnKI+tGvEBUpqiMh0+rW6zDQ==", + "dev": true + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true + }, "node_modules/negotiator": { "version": "0.6.3", "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", @@ -2392,6 +4508,21 @@ "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==", "dev": true }, + "node_modules/normalize-package-data": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.3.tgz", + "integrity": "sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==", + "dev": true, + "dependencies": { + "hosted-git-info": "^4.0.1", + "is-core-module": "^2.5.0", + "semver": "^7.3.4", + "validate-npm-package-license": "^3.0.1" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", @@ -2418,6 +4549,15 @@ "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.7.tgz", "integrity": "sha512-ub5E4+FBPKwAZx0UwIQOjYWGHTEq5sPqHQNRN8Z9e4A7u3Tj1weLJsL59yH9vmvqEtBHaOmT6cYQKIZOxp35FQ==" }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/object-inspect": { "version": "1.13.1", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", @@ -2495,6 +4635,32 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/optionator": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", + "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", + "dev": true, + "dependencies": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.6", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "word-wrap": "~1.2.3" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/p-limit": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", @@ -2544,6 +4710,36 @@ "node": ">=6" } }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/parse5": { "version": "7.1.2", "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz", @@ -2582,6 +4778,12 @@ "node": ">=0.10.0" } }, + "node_modules/path-is-inside": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", + "integrity": "sha512-DUWJr3+ULp4zXmol/SZkFf3JGsS9/SIv+Y3Rt93/UjPpDpklB5f1er4O3POIbUuUJ3FXgqte2Q7SrU6zAqwk8w==", + "dev": true + }, "node_modules/path-key": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", @@ -2603,6 +4805,15 @@ "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==", "dev": true }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/picocolors": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", @@ -2633,12 +4844,39 @@ "node": ">=8" } }, + "node_modules/pluralize": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-7.0.0.tgz", + "integrity": "sha512-ARhBOdzS3e41FbkW/XWrTEtukqqLoK5+Z/4UeDaLuSW+39JPeFgs4gCGqsrJHVZX0fUrx//4OF0K1CUGwlIFow==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, "node_modules/process-nextick-args": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", "dev": true }, + "node_modules/progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/proxy-addr": { "version": "2.0.7", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", @@ -2661,6 +4899,12 @@ "node": ">= 0.10" } }, + "node_modules/pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==", + "dev": true + }, "node_modules/psl": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", @@ -2694,6 +4938,15 @@ "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==" }, + "node_modules/quick-lru": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz", + "integrity": "sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/randombytes": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", @@ -2748,6 +5001,83 @@ "node": ">=0.10.0" } }, + "node_modules/read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "dev": true, + "dependencies": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/read-pkg-up": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", + "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "dev": true, + "dependencies": { + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/read-pkg-up/node_modules/type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/read-pkg/node_modules/hosted-git-info": { + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", + "dev": true + }, + "node_modules/read-pkg/node_modules/normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "dependencies": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "node_modules/read-pkg/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/read-pkg/node_modules/type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/readable-stream": { "version": "3.6.2", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", @@ -2786,6 +5116,37 @@ "node": ">= 0.10" } }, + "node_modules/redent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", + "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", + "dev": true, + "dependencies": { + "indent-string": "^4.0.0", + "strip-indent": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/regexpp": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-1.1.0.tgz", + "integrity": "sha512-LOPw8FpgdQF9etWMaAfG/WRthIdXJGYp4mJ2Jgn/2lpkbod9jPn0t9UqN7AxBOKNfzRbYyVfgc7Vk4t/MpnXgw==", + "dev": true, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/require-from-string": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", @@ -2795,6 +5156,28 @@ "node": ">=0.10.0" } }, + "node_modules/require-uncached": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz", + "integrity": "sha512-Xct+41K3twrbBHdxAgMoOS+cNcoqIjfM2/VxBF4LL2hVph7YsF8VSKyQ3BDFZwEVbok9yeDl2le/qo0S77WG2w==", + "dev": true, + "dependencies": { + "caller-path": "^0.1.0", + "resolve-from": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-uncached/node_modules/resolve-from": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-1.0.1.tgz", + "integrity": "sha512-kT10v4dhrlLNcnO084hEjvXCI1wUG9qZLoz2RogxqDQQYy7IxjI/iMUkOtQTNEh6rzHxvdQWHsJyel1pKOVCxg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/requires-port": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", @@ -2838,6 +5221,52 @@ "node": ">=8" } }, + "node_modules/resolve-global": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/resolve-global/-/resolve-global-1.0.0.tgz", + "integrity": "sha512-zFa12V4OLtT5XUX/Q4VLvTfBf+Ok0SPc1FNGM/z9ctUdiU618qwKpWnd0CHs3+RqROfyEg/DhuHbMWYqcgljEw==", + "dev": true, + "dependencies": { + "global-dirs": "^0.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/restore-cursor": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", + "integrity": "sha512-6IzJLuGi4+R14vwagDHX+JrXmPVtPpn4mffDJ1UdR7/Edm87fl6yi8mMBIVvFtJaNTUvjughmW4hwLhRG7gC1Q==", + "dev": true, + "dependencies": { + "onetime": "^2.0.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/restore-cursor/node_modules/mimic-fn": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", + "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/restore-cursor/node_modules/onetime": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", + "integrity": "sha512-oyyPpiMaKARvvcgip+JV+7zci5L8D1W9RZIz2l1o08AM3pfspitVWnPt3mzHcBPp12oYMTy0pqrFs/C+m3EwsQ==", + "dev": true, + "dependencies": { + "mimic-fn": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/retry": { "version": "0.13.1", "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", @@ -2867,6 +5296,30 @@ "resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.6.0.tgz", "integrity": "sha512-APM0Gt1KoXBz0iIkkdB/kfvGOwC4UuJFeG/c+yV7wSc7q96cG/kJ0HiYCnzivD9SB53cLV1MlHFNfOuPaadYSw==" }, + "node_modules/run-async": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", + "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/rx-lite": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-4.0.8.tgz", + "integrity": "sha512-Cun9QucwK6MIrp3mry/Y7hqD1oFqTYLQ4pGxaHTjIdaFDWRGGLikqp6u8LcWJnzpoALg9hap+JGk8sFIUuEGNA==", + "dev": true + }, + "node_modules/rx-lite-aggregates": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/rx-lite-aggregates/-/rx-lite-aggregates-4.0.8.tgz", + "integrity": "sha512-3xPNZGW93oCjiO7PtKxRK6iOVYBWBvtf9QHDfU23Oc+dLIQmAV//UnyXV/yihv81VS/UqoQPk4NegS8EFi55Hg==", + "dev": true, + "dependencies": { + "rx-lite": "*" + } + }, "node_modules/safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", @@ -2940,6 +5393,21 @@ "node": ">=10" } }, + "node_modules/semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/send": { "version": "0.18.0", "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", @@ -3170,6 +5638,27 @@ "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", "dev": true }, + "node_modules/slice-ansi": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-1.0.0.tgz", + "integrity": "sha512-POqxBK6Lb3q6s047D/XsDVNPnF9Dl8JSaqe9h9lURl0OdNqy/ujDrOiIHtsqXMGbWWTIomRzAMaTyawAU//Reg==", + "dev": true, + "dependencies": { + "is-fullwidth-code-point": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/slice-ansi/node_modules/is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", + "dev": true, + "engines": { + "node": ">=4" + } + }, "node_modules/sockjs": { "version": "0.3.24", "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.24.tgz", @@ -3230,6 +5719,38 @@ "source-map": "^0.6.0" } }, + "node_modules/spdx-correct": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", + "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", + "dev": true, + "dependencies": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-exceptions": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz", + "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==", + "dev": true + }, + "node_modules/spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "dev": true, + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-license-ids": { + "version": "3.0.17", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.17.tgz", + "integrity": "sha512-sh8PWc/ftMqAAdFiBu6Fy6JUOYjqDJBJvIhpfDMyHrr0Rbp5liZqd4TjtQ/RgfLjKFZb+LMx5hpml5qOWy0qvg==", + "dev": true + }, "node_modules/spdy": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.2.tgz", @@ -3260,6 +5781,21 @@ "wbuf": "^1.7.3" } }, + "node_modules/split2": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/split2/-/split2-3.2.2.tgz", + "integrity": "sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg==", + "dev": true, + "dependencies": { + "readable-stream": "^3.0.0" + } + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "dev": true + }, "node_modules/statuses": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", @@ -3278,6 +5814,32 @@ "safe-buffer": "~5.2.0" } }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/strip-final-newline": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", @@ -3287,6 +5849,27 @@ "node": ">=6" } }, + "node_modules/strip-indent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", + "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", + "dev": true, + "dependencies": { + "min-indent": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/supports-color": { "version": "8.1.1", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", @@ -3319,6 +5902,158 @@ "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==" }, + "node_modules/table": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/table/-/table-4.0.2.tgz", + "integrity": "sha512-UUkEAPdSGxtRpiV9ozJ5cMTtYiqz7Ni1OGqLXRCynrvzdtR1p+cfOWe2RJLwvUG8hNanaSRjecIqwOjqeatDsA==", + "dev": true, + "dependencies": { + "ajv": "^5.2.3", + "ajv-keywords": "^2.1.0", + "chalk": "^2.1.0", + "lodash": "^4.17.4", + "slice-ansi": "1.0.0", + "string-width": "^2.1.1" + } + }, + "node_modules/table/node_modules/ajv": { + "version": "5.5.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz", + "integrity": "sha512-Ajr4IcMXq/2QmMkEmSvxqfLN5zGmJ92gHXAeOXq1OekoH2rfDNsgdDoL2f7QaRCy7G/E6TpxBVdRuNraMztGHw==", + "dev": true, + "dependencies": { + "co": "^4.6.0", + "fast-deep-equal": "^1.0.0", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.3.0" + } + }, + "node_modules/table/node_modules/ajv-keywords": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-2.1.1.tgz", + "integrity": "sha512-ZFztHzVRdGLAzJmpUT9LNFLe1YiVOEylcaNpEutM26PVTCtOD919IMfD01CgbRouB42Dd9atjx1HseC15DgOZA==", + "dev": true, + "peerDependencies": { + "ajv": "^5.0.0" + } + }, + "node_modules/table/node_modules/ansi-regex": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz", + "integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/table/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/table/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/table/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/table/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "node_modules/table/node_modules/fast-deep-equal": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz", + "integrity": "sha512-fueX787WZKCV0Is4/T2cyAdM4+x1S3MXXOAhavE1ys/W42SHAPacLTQhucja22QBYrfGw50M2sRiXPtTGv9Ymw==", + "dev": true + }, + "node_modules/table/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/table/node_modules/is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/table/node_modules/json-schema-traverse": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz", + "integrity": "sha512-4JD/Ivzg7PoW8NzdrBSr3UFwC9mHgvI7Z6z3QGBsSHgKaRTUDmyZAAKJo2UbG1kUVfS9WS8bi36N49U1xw43DA==", + "dev": true + }, + "node_modules/table/node_modules/string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "dependencies": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/table/node_modules/strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==", + "dev": true, + "dependencies": { + "ansi-regex": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/table/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/tapable": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", @@ -3380,12 +6115,54 @@ } } }, + "node_modules/text-extensions": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/text-extensions/-/text-extensions-1.9.0.tgz", + "integrity": "sha512-wiBrwC1EhBelW12Zy26JeOUkQ5mRu+5o8rpsJk5+2t+Y5vE7e842qtZDQ2g1NpX/29HdyFeJ4nSIhI47ENSxlQ==", + "dev": true, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", + "dev": true + }, + "node_modules/through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", + "dev": true + }, + "node_modules/through2": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/through2/-/through2-4.0.2.tgz", + "integrity": "sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==", + "dev": true, + "dependencies": { + "readable-stream": "3" + } + }, "node_modules/thunky": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz", "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==", "dev": true }, + "node_modules/tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "dev": true, + "dependencies": { + "os-tmpdir": "~1.0.2" + }, + "engines": { + "node": ">=0.6.0" + } + }, "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", @@ -3432,6 +6209,82 @@ "node": ">=14" } }, + "node_modules/trim-newlines": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.1.tgz", + "integrity": "sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ts-node": { + "version": "10.9.2", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", + "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", + "dev": true, + "dependencies": { + "@cspotcode/source-map-support": "^0.8.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "v8-compile-cache-lib": "^3.0.1", + "yn": "3.1.1" + }, + "bin": { + "ts-node": "dist/bin.js", + "ts-node-cwd": "dist/bin-cwd.js", + "ts-node-esm": "dist/bin-esm.js", + "ts-node-script": "dist/bin-script.js", + "ts-node-transpile-only": "dist/bin-transpile.js", + "ts-script": "dist/bin-script-deprecated.js" + }, + "peerDependencies": { + "@swc/core": ">=1.2.50", + "@swc/wasm": ">=1.2.50", + "@types/node": "*", + "typescript": ">=2.7" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "@swc/wasm": { + "optional": true + } + } + }, + "node_modules/type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==", + "dev": true, + "dependencies": { + "prelude-ls": "~1.1.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-fest": { + "version": "0.18.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.18.1.tgz", + "integrity": "sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/type-is": { "version": "1.6.18", "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", @@ -3445,6 +6298,25 @@ "node": ">= 0.6" } }, + "node_modules/typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==", + "dev": true + }, + "node_modules/typescript": { + "version": "5.4.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz", + "integrity": "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, "node_modules/undici-types": { "version": "5.26.5", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", @@ -3540,6 +6412,22 @@ "uuid": "dist/bin/uuid" } }, + "node_modules/v8-compile-cache-lib": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", + "dev": true + }, + "node_modules/validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "dependencies": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, "node_modules/vary": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", @@ -3918,108 +6806,578 @@ "node": ">=0.8.0" } }, - "node_modules/websocket-extensions": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", - "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", + "node_modules/websocket-extensions": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", + "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/whatwg-encoding": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-2.0.0.tgz", + "integrity": "sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg==", + "dependencies": { + "iconv-lite": "0.6.3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/whatwg-mimetype": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-3.0.0.tgz", + "integrity": "sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q==", + "engines": { + "node": ">=12" + } + }, + "node_modules/whatwg-url": { + "version": "12.0.1", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-12.0.1.tgz", + "integrity": "sha512-Ed/LrqB8EPlGxjS+TrsXcpUond1mhccS3pchLhzSgPCnTimUCKj3IZE75pAs5m6heB2U2TMerKFUXheyHY+VDQ==", + "dependencies": { + "tr46": "^4.1.1", + "webidl-conversions": "^7.0.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/wildcard": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.1.tgz", + "integrity": "sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==", + "dev": true + }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true + }, + "node_modules/write": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/write/-/write-0.2.1.tgz", + "integrity": "sha512-CJ17OoULEKXpA5pef3qLj5AxTJ6mSt7g84he2WIskKwqFO4T97d5V7Tadl0DYDk7qyUOQD5WlUlOMChaYrhxeA==", + "dev": true, + "dependencies": { + "mkdirp": "^0.5.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ws": { + "version": "8.15.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.15.1.tgz", + "integrity": "sha512-W5OZiCjXEmk0yZ66ZN82beM5Sz7l7coYxpRkzS+p9PP+ToQry8szKh+61eNktr7EA9DOwvFGhfC605jDHbP6QQ==", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/xml-name-validator": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-4.0.0.tgz", + "integrity": "sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==", + "engines": { + "node": ">=12" + } + }, + "node_modules/xmlchars": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", + "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==" + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "dev": true, + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs/node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + } + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.24.2", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.2.tgz", + "integrity": "sha512-y5+tLQyV8pg3fsiln67BVLD1P13Eg4lh5RW9mF0zUuvLrv9uIQ4MCL+CRT+FTsBlBjcIan6PGsLcBN0m3ClUyQ==", + "dev": true, + "requires": { + "@babel/highlight": "^7.24.2", + "picocolors": "^1.0.0" + } + }, + "@babel/helper-validator-identifier": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", + "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", + "dev": true + }, + "@babel/highlight": { + "version": "7.24.2", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.2.tgz", + "integrity": "sha512-Yac1ao4flkTxTteCDZLEvdxg2fZfz1v8M4QpaGypq/WPDqg3ijHYbDfs+LG5hvzSoqaSZ9/Z9lKSP3CjZjv+pA==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.22.20", + "chalk": "^2.4.2", + "js-tokens": "^4.0.0", + "picocolors": "^1.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "@commitlint/cli": { + "version": "17.8.1", + "resolved": "https://registry.npmjs.org/@commitlint/cli/-/cli-17.8.1.tgz", + "integrity": "sha512-ay+WbzQesE0Rv4EQKfNbSMiJJ12KdKTDzIt0tcK4k11FdsWmtwP0Kp1NWMOUswfIWo6Eb7p7Ln721Nx9FLNBjg==", + "dev": true, + "requires": { + "@commitlint/format": "^17.8.1", + "@commitlint/lint": "^17.8.1", + "@commitlint/load": "^17.8.1", + "@commitlint/read": "^17.8.1", + "@commitlint/types": "^17.8.1", + "execa": "^5.0.0", + "lodash.isfunction": "^3.0.9", + "resolve-from": "5.0.0", + "resolve-global": "1.0.0", + "yargs": "^17.0.0" + } + }, + "@commitlint/config-conventional": { + "version": "17.8.1", + "resolved": "https://registry.npmjs.org/@commitlint/config-conventional/-/config-conventional-17.8.1.tgz", + "integrity": "sha512-NxCOHx1kgneig3VLauWJcDWS40DVjg7nKOpBEEK9E5fjJpQqLCilcnKkIIjdBH98kEO1q3NpE5NSrZ2kl/QGJg==", + "dev": true, + "requires": { + "conventional-changelog-conventionalcommits": "^6.1.0" + } + }, + "@commitlint/config-validator": { + "version": "17.8.1", + "resolved": "https://registry.npmjs.org/@commitlint/config-validator/-/config-validator-17.8.1.tgz", + "integrity": "sha512-UUgUC+sNiiMwkyiuIFR7JG2cfd9t/7MV8VB4TZ+q02ZFkHoduUS4tJGsCBWvBOGD9Btev6IecPMvlWUfJorkEA==", + "dev": true, + "requires": { + "@commitlint/types": "^17.8.1", + "ajv": "^8.11.0" + }, + "dependencies": { + "ajv": { + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", + "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + } + }, + "json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true + } + } + }, + "@commitlint/ensure": { + "version": "17.8.1", + "resolved": "https://registry.npmjs.org/@commitlint/ensure/-/ensure-17.8.1.tgz", + "integrity": "sha512-xjafwKxid8s1K23NFpL8JNo6JnY/ysetKo8kegVM7c8vs+kWLP8VrQq+NbhgVlmCojhEDbzQKp4eRXSjVOGsow==", + "dev": true, + "requires": { + "@commitlint/types": "^17.8.1", + "lodash.camelcase": "^4.3.0", + "lodash.kebabcase": "^4.1.1", + "lodash.snakecase": "^4.1.1", + "lodash.startcase": "^4.4.0", + "lodash.upperfirst": "^4.3.1" + } + }, + "@commitlint/execute-rule": { + "version": "17.8.1", + "resolved": "https://registry.npmjs.org/@commitlint/execute-rule/-/execute-rule-17.8.1.tgz", + "integrity": "sha512-JHVupQeSdNI6xzA9SqMF+p/JjrHTcrJdI02PwesQIDCIGUrv04hicJgCcws5nzaoZbROapPs0s6zeVHoxpMwFQ==", + "dev": true + }, + "@commitlint/format": { + "version": "17.8.1", + "resolved": "https://registry.npmjs.org/@commitlint/format/-/format-17.8.1.tgz", + "integrity": "sha512-f3oMTyZ84M9ht7fb93wbCKmWxO5/kKSbwuYvS867duVomoOsgrgljkGGIztmT/srZnaiGbaK8+Wf8Ik2tSr5eg==", + "dev": true, + "requires": { + "@commitlint/types": "^17.8.1", + "chalk": "^4.1.0" + } + }, + "@commitlint/is-ignored": { + "version": "17.8.1", + "resolved": "https://registry.npmjs.org/@commitlint/is-ignored/-/is-ignored-17.8.1.tgz", + "integrity": "sha512-UshMi4Ltb4ZlNn4F7WtSEugFDZmctzFpmbqvpyxD3la510J+PLcnyhf9chs7EryaRFJMdAKwsEKfNK0jL/QM4g==", "dev": true, - "engines": { - "node": ">=0.8.0" + "requires": { + "@commitlint/types": "^17.8.1", + "semver": "7.5.4" } }, - "node_modules/whatwg-encoding": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-2.0.0.tgz", - "integrity": "sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg==", - "dependencies": { - "iconv-lite": "0.6.3" + "@commitlint/lint": { + "version": "17.8.1", + "resolved": "https://registry.npmjs.org/@commitlint/lint/-/lint-17.8.1.tgz", + "integrity": "sha512-aQUlwIR1/VMv2D4GXSk7PfL5hIaFSfy6hSHV94O8Y27T5q+DlDEgd/cZ4KmVI+MWKzFfCTiTuWqjfRSfdRllCA==", + "dev": true, + "requires": { + "@commitlint/is-ignored": "^17.8.1", + "@commitlint/parse": "^17.8.1", + "@commitlint/rules": "^17.8.1", + "@commitlint/types": "^17.8.1" + } + }, + "@commitlint/load": { + "version": "17.8.1", + "resolved": "https://registry.npmjs.org/@commitlint/load/-/load-17.8.1.tgz", + "integrity": "sha512-iF4CL7KDFstP1kpVUkT8K2Wl17h2yx9VaR1ztTc8vzByWWcbO/WaKwxsnCOqow9tVAlzPfo1ywk9m2oJ9ucMqA==", + "dev": true, + "requires": { + "@commitlint/config-validator": "^17.8.1", + "@commitlint/execute-rule": "^17.8.1", + "@commitlint/resolve-extends": "^17.8.1", + "@commitlint/types": "^17.8.1", + "@types/node": "20.5.1", + "chalk": "^4.1.0", + "cosmiconfig": "^8.0.0", + "cosmiconfig-typescript-loader": "^4.0.0", + "lodash.isplainobject": "^4.0.6", + "lodash.merge": "^4.6.2", + "lodash.uniq": "^4.5.0", + "resolve-from": "^5.0.0", + "ts-node": "^10.8.1", + "typescript": "^4.6.4 || ^5.2.2" }, - "engines": { - "node": ">=12" + "dependencies": { + "@types/node": { + "version": "20.5.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.5.1.tgz", + "integrity": "sha512-4tT2UrL5LBqDwoed9wZ6N3umC4Yhz3W3FloMmiiG4JwmUJWpie0c7lcnUNd4gtMKuDEO4wRVS8B6Xa0uMRsMKg==", + "dev": true + } } }, - "node_modules/whatwg-mimetype": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-3.0.0.tgz", - "integrity": "sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q==", - "engines": { - "node": ">=12" + "@commitlint/message": { + "version": "17.8.1", + "resolved": "https://registry.npmjs.org/@commitlint/message/-/message-17.8.1.tgz", + "integrity": "sha512-6bYL1GUQsD6bLhTH3QQty8pVFoETfFQlMn2Nzmz3AOLqRVfNNtXBaSY0dhZ0dM6A2MEq4+2d7L/2LP8TjqGRkA==", + "dev": true + }, + "@commitlint/parse": { + "version": "17.8.1", + "resolved": "https://registry.npmjs.org/@commitlint/parse/-/parse-17.8.1.tgz", + "integrity": "sha512-/wLUickTo0rNpQgWwLPavTm7WbwkZoBy3X8PpkUmlSmQJyWQTj0m6bDjiykMaDt41qcUbfeFfaCvXfiR4EGnfw==", + "dev": true, + "requires": { + "@commitlint/types": "^17.8.1", + "conventional-changelog-angular": "^6.0.0", + "conventional-commits-parser": "^4.0.0" } }, - "node_modules/whatwg-url": { - "version": "12.0.1", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-12.0.1.tgz", - "integrity": "sha512-Ed/LrqB8EPlGxjS+TrsXcpUond1mhccS3pchLhzSgPCnTimUCKj3IZE75pAs5m6heB2U2TMerKFUXheyHY+VDQ==", - "dependencies": { - "tr46": "^4.1.1", - "webidl-conversions": "^7.0.0" - }, - "engines": { - "node": ">=14" + "@commitlint/read": { + "version": "17.8.1", + "resolved": "https://registry.npmjs.org/@commitlint/read/-/read-17.8.1.tgz", + "integrity": "sha512-Fd55Oaz9irzBESPCdMd8vWWgxsW3OWR99wOntBDHgf9h7Y6OOHjWEdS9Xzen1GFndqgyoaFplQS5y7KZe0kO2w==", + "dev": true, + "requires": { + "@commitlint/top-level": "^17.8.1", + "@commitlint/types": "^17.8.1", + "fs-extra": "^11.0.0", + "git-raw-commits": "^2.0.11", + "minimist": "^1.2.6" } }, - "node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "@commitlint/resolve-extends": { + "version": "17.8.1", + "resolved": "https://registry.npmjs.org/@commitlint/resolve-extends/-/resolve-extends-17.8.1.tgz", + "integrity": "sha512-W/ryRoQ0TSVXqJrx5SGkaYuAaE/BUontL1j1HsKckvM6e5ZaG0M9126zcwL6peKSuIetJi7E87PRQF8O86EW0Q==", "dev": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" + "requires": { + "@commitlint/config-validator": "^17.8.1", + "@commitlint/types": "^17.8.1", + "import-fresh": "^3.0.0", + "lodash.mergewith": "^4.6.2", + "resolve-from": "^5.0.0", + "resolve-global": "^1.0.0" } }, - "node_modules/wildcard": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.1.tgz", - "integrity": "sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==", - "dev": true + "@commitlint/rules": { + "version": "17.8.1", + "resolved": "https://registry.npmjs.org/@commitlint/rules/-/rules-17.8.1.tgz", + "integrity": "sha512-2b7OdVbN7MTAt9U0vKOYKCDsOvESVXxQmrvuVUZ0rGFMCrCPJWWP1GJ7f0lAypbDAhaGb8zqtdOr47192LBrIA==", + "dev": true, + "requires": { + "@commitlint/ensure": "^17.8.1", + "@commitlint/message": "^17.8.1", + "@commitlint/to-lines": "^17.8.1", + "@commitlint/types": "^17.8.1", + "execa": "^5.0.0" + } }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "@commitlint/to-lines": { + "version": "17.8.1", + "resolved": "https://registry.npmjs.org/@commitlint/to-lines/-/to-lines-17.8.1.tgz", + "integrity": "sha512-LE0jb8CuR/mj6xJyrIk8VLz03OEzXFgLdivBytoooKO5xLt5yalc8Ma5guTWobw998sbR3ogDd+2jed03CFmJA==", "dev": true }, - "node_modules/ws": { - "version": "8.15.1", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.15.1.tgz", - "integrity": "sha512-W5OZiCjXEmk0yZ66ZN82beM5Sz7l7coYxpRkzS+p9PP+ToQry8szKh+61eNktr7EA9DOwvFGhfC605jDHbP6QQ==", - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": ">=5.0.2" + "@commitlint/top-level": { + "version": "17.8.1", + "resolved": "https://registry.npmjs.org/@commitlint/top-level/-/top-level-17.8.1.tgz", + "integrity": "sha512-l6+Z6rrNf5p333SHfEte6r+WkOxGlWK4bLuZKbtf/2TXRN+qhrvn1XE63VhD8Oe9oIHQ7F7W1nG2k/TJFhx2yA==", + "dev": true, + "requires": { + "find-up": "^5.0.0" }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true + "dependencies": { + "find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "requires": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + } }, - "utf-8-validate": { - "optional": true + "locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "requires": { + "p-locate": "^5.0.0" + } + }, + "p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "requires": { + "yocto-queue": "^0.1.0" + } + }, + "p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "requires": { + "p-limit": "^3.0.2" + } } } }, - "node_modules/xml-name-validator": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-4.0.0.tgz", - "integrity": "sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==", - "engines": { - "node": ">=12" + "@commitlint/types": { + "version": "17.8.1", + "resolved": "https://registry.npmjs.org/@commitlint/types/-/types-17.8.1.tgz", + "integrity": "sha512-PXDQXkAmiMEG162Bqdh9ChML/GJZo6vU+7F03ALKDK8zYc6SuAr47LjG7hGYRqUOz+WK0dU7bQ0xzuqFMdxzeQ==", + "dev": true, + "requires": { + "chalk": "^4.1.0" + } + }, + "@cspotcode/source-map-support": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "dev": true, + "requires": { + "@jridgewell/trace-mapping": "0.3.9" + }, + "dependencies": { + "@jridgewell/trace-mapping": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "dev": true, + "requires": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + } } }, - "node_modules/xmlchars": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", - "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==" - } - }, - "dependencies": { "@discoveryjs/json-ext": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz", @@ -4086,6 +7444,30 @@ "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==" }, + "@tsconfig/node10": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz", + "integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==", + "dev": true + }, + "@tsconfig/node12": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", + "dev": true + }, + "@tsconfig/node14": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", + "dev": true + }, + "@tsconfig/node16": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", + "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", + "dev": true + }, "@types/body-parser": { "version": "1.19.5", "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz", @@ -4201,6 +7583,12 @@ "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==", "dev": true }, + "@types/minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-hov8bUuiLiyFPGyFPE1lwWhmzYbirOXQNNo40+y3zow8aFVTeyn3VWL0VFFfdNddA8S4Vf0Tc062rzyNr7Paag==", + "dev": true + }, "@types/node": { "version": "20.10.5", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.10.5.tgz", @@ -4219,6 +7607,12 @@ "@types/node": "*" } }, + "@types/normalize-package-data": { + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.4.tgz", + "integrity": "sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==", + "dev": true + }, "@types/qs": { "version": "6.9.10", "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.10.tgz", @@ -4494,6 +7888,29 @@ "dev": true, "requires": {} }, + "acorn-jsx": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz", + "integrity": "sha512-AU7pnZkguthwBjKgCg6998ByQNIMjbuDQZ8bb78QAFZwPfmKia8AIzgY/gWgqCjnht8JLdXmB4YxA0KaV60ncQ==", + "dev": true, + "requires": { + "acorn": "^3.0.4" + }, + "dependencies": { + "acorn": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz", + "integrity": "sha512-OLUyIIZ7mF5oaAUT1w0TFqQS81q3saT46x8t7ukpPjMNk+nbs4ZHhs7ToV8EWnLYLepjETXd4XaCE4uxkMeqUw==", + "dev": true + } + } + }, + "acorn-walk": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.2.tgz", + "integrity": "sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==", + "dev": true + }, "agent-base": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", @@ -4550,12 +7967,33 @@ "dev": true, "requires": {} }, + "ansi-escapes": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz", + "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==", + "dev": true + }, "ansi-html-community": { "version": "0.0.8", "resolved": "https://registry.npmjs.org/ansi-html-community/-/ansi-html-community-0.0.8.tgz", "integrity": "sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw==", "dev": true }, + "ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, "anymatch": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", @@ -4566,17 +8004,100 @@ "picomatch": "^2.0.4" } }, + "arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "dev": true + }, + "argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, "array-flatten": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-2.1.2.tgz", "integrity": "sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ==", "dev": true }, + "array-ify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array-ify/-/array-ify-1.0.0.tgz", + "integrity": "sha512-c5AMf34bKdvPhQ7tBGhqkgKNUzMr4WUs+WDtC2ZUGOUncbxKMTvqxYctiseW3+L4bA8ec+GcZ6/A/FW4m8ukng==", + "dev": true + }, + "arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==", + "dev": true + }, "asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" }, + "babel-code-frame": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", + "integrity": "sha512-XqYMR2dfdGMW+hd0IUZ2PwK+fGeFkOxZJ0wY+JaQAHzt1Zx8LcvpiZD2NiGkEG8qx0CfkAOr5xt76d1e8vG90g==", + "dev": true, + "requires": { + "chalk": "^1.1.3", + "esutils": "^2.0.2", + "js-tokens": "^3.0.2" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", + "dev": true + }, + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha512-kmCevFghRiWM7HB5zTPULl4r9bVFSWjz62MhqizDGUrq2NWuNMQyuv4tHHoKJHs69M/MF64lEcHdYIocrdWQYA==", + "dev": true + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha512-U3lRVLMSlsCfjqYPbLyVv11M9CPW4I728d6TCKMAOJueEeB9/8o+eSsMnxPJD+Q+K909sdESg7C+tIkoH6on1A==", + "dev": true, + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "js-tokens": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", + "integrity": "sha512-RjTcuD4xjtthQkaWH7dFlH85L+QaVtSoOyGdZ3g6HFhS9dFNDfLyqgm2NFe2X6cQpeFmt0452FJjFG5UameExg==", + "dev": true + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha512-KKNVtd6pCYgPIKU4cp2733HWYCpplQhddZLBUryaAHou723x+FRzQ5Df824Fj+IyyuiQTRoub4SnIFfIcrp70g==", + "dev": true + } + } + }, "balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", @@ -4721,12 +8242,79 @@ "set-function-length": "^1.1.1" } }, + "caller-path": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz", + "integrity": "sha512-UJiE1otjXPF5/x+T3zTnSFiTOEmJoGTD9HmBoxnCUwho61a2eSNn/VwtwuIBDAo2SEOv1AJ7ARI5gCmohFLu/g==", + "dev": true, + "requires": { + "callsites": "^0.2.0" + }, + "dependencies": { + "callsites": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz", + "integrity": "sha512-Zv4Dns9IbXXmPkgRRUjAaJQgfN4xX5p6+RQFhWUqscdvvK2xK/ZL8b3IXIJsj+4sD+f24NwnWy2BY8AJ82JB0A==", + "dev": true + } + } + }, + "callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true + }, + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true + }, + "camelcase-keys": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-6.2.2.tgz", + "integrity": "sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==", + "dev": true, + "requires": { + "camelcase": "^5.3.1", + "map-obj": "^4.0.0", + "quick-lru": "^4.0.1" + } + }, "caniuse-lite": { "version": "1.0.30001570", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001570.tgz", "integrity": "sha512-+3e0ASu4sw1SWaoCtvPeyXp+5PsjigkSt8OXZbF9StH5pQWbxEjLAZE3n8Aup5udop1uRiKA7a4utUk/uoSpUw==", "dev": true }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "dependencies": { + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "chardet": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.4.2.tgz", + "integrity": "sha512-j/Toj7f1z98Hh2cYo2BVr85EpIRWqUi7rtRSGxh/cqUjqrnJe9l9UE7IUGd2vQ2p+kSHLkSzObQPZPLUC6TQwg==", + "dev": true + }, "chokidar": { "version": "3.5.3", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", @@ -4749,6 +8337,38 @@ "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==", "dev": true }, + "circular-json": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz", + "integrity": "sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A==", + "dev": true + }, + "cli-cursor": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", + "integrity": "sha512-8lgKz8LmCRYZZQDpRyT2m5rKJ08TnU4tR9FFFW2rxpxR1FzWi4PQ/NfyODchAatHaUgnSPVcx/R5w6NuTBzFiw==", + "dev": true, + "requires": { + "restore-cursor": "^2.0.0" + } + }, + "cli-width": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.1.tgz", + "integrity": "sha512-GRMWDxpOB6Dgk2E5Uo+3eEBvtOOlimMmpbFiKuLFnQzYDavtLFY3K5ona41jgN/WdRZtG7utuVSVTL4HbZHGkw==", + "dev": true + }, + "cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dev": true, + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + } + }, "clone-deep": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", @@ -4760,6 +8380,27 @@ "shallow-clone": "^3.0.0" } }, + "co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", + "dev": true + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, "colorette": { "version": "2.0.20", "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", @@ -4780,6 +8421,16 @@ "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", "dev": true }, + "compare-func": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/compare-func/-/compare-func-2.0.0.tgz", + "integrity": "sha512-zHig5N+tPWARooBnb0Zx1MFcdfpyJrfTJ3Y5L+IFvUm8rM74hHz66z0gw0x4tijh5CorKkKUCnW82R2vmpeCRA==", + "dev": true, + "requires": { + "array-ify": "^1.0.0", + "dot-prop": "^5.1.0" + } + }, "compressible": { "version": "2.0.18", "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", @@ -4833,6 +8484,50 @@ "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", "dev": true }, + "concat-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", + "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + }, + "dependencies": { + "readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, "connect-history-api-fallback": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-2.0.0.tgz", @@ -4854,6 +8549,36 @@ "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", "dev": true }, + "conventional-changelog-angular": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-6.0.0.tgz", + "integrity": "sha512-6qLgrBF4gueoC7AFVHu51nHL9pF9FRjXrH+ceVf7WmAfH3gs+gEYOkvxhjMPjZu57I4AGUGoNTY8V7Hrgf1uqg==", + "dev": true, + "requires": { + "compare-func": "^2.0.0" + } + }, + "conventional-changelog-conventionalcommits": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/conventional-changelog-conventionalcommits/-/conventional-changelog-conventionalcommits-6.1.0.tgz", + "integrity": "sha512-3cS3GEtR78zTfMzk0AizXKKIdN4OvSh7ibNz6/DPbhWWQu7LqE/8+/GqSodV+sywUR2gpJAdP/1JFf4XtN7Zpw==", + "dev": true, + "requires": { + "compare-func": "^2.0.0" + } + }, + "conventional-commits-parser": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-4.0.0.tgz", + "integrity": "sha512-WRv5j1FsVM5FISJkoYMR6tPk07fkKT0UodruX4je86V4owk451yjXAKzKAPOs9l7y59E2viHUS9eQ+dfUA9NSg==", + "dev": true, + "requires": { + "is-text-path": "^1.0.1", + "JSONStream": "^1.3.5", + "meow": "^8.1.2", + "split2": "^3.2.2" + } + }, "cookie": { "version": "0.5.0", "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", @@ -4872,6 +8597,31 @@ "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", "dev": true }, + "cosmiconfig": { + "version": "8.3.6", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.3.6.tgz", + "integrity": "sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==", + "dev": true, + "requires": { + "import-fresh": "^3.3.0", + "js-yaml": "^4.1.0", + "parse-json": "^5.2.0", + "path-type": "^4.0.0" + } + }, + "cosmiconfig-typescript-loader": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/cosmiconfig-typescript-loader/-/cosmiconfig-typescript-loader-4.4.0.tgz", + "integrity": "sha512-BabizFdC3wBHhbI4kJh0VkQP9GkBfoHPydD0COMce1nJ1kJAB3F2TmJ/I7diULBKtmEWSwEbuN/KDtgnmUUVmw==", + "dev": true, + "requires": {} + }, + "create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", + "dev": true + }, "cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", @@ -4891,6 +8641,12 @@ "rrweb-cssom": "^0.6.0" } }, + "dargs": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/dargs/-/dargs-7.0.0.tgz", + "integrity": "sha512-2iy1EkLdlBzQGvbweYRFxmFath8+K7+AKB0TlhHWkNuH+TmovaMH/Wp7V7R4u7f4SnX3OgLsU9t1NI9ioDnUpg==", + "dev": true + }, "data-urls": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-4.0.0.tgz", @@ -4909,11 +8665,41 @@ "ms": "2.1.2" } }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", + "dev": true + }, + "decamelize-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.1.tgz", + "integrity": "sha512-WiPxgEirIV0/eIOMcnFBA3/IJZAZqKnwAwWyvvdi4lsr1WCN22nhdf/3db3DoZcUjTV2SqfzIwNyp6y2xs3nmg==", + "dev": true, + "requires": { + "decamelize": "^1.1.0", + "map-obj": "^1.0.0" + }, + "dependencies": { + "map-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", + "integrity": "sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==", + "dev": true + } + } + }, "decimal.js": { "version": "10.4.3", "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.3.tgz", "integrity": "sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==" }, + "deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true + }, "default-gateway": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-6.0.3.tgz", @@ -4963,6 +8749,12 @@ "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==", "dev": true }, + "diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true + }, "dns-equal": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/dns-equal/-/dns-equal-1.0.0.tgz", @@ -4978,6 +8770,15 @@ "@leichtgewicht/ip-codec": "^2.0.1" } }, + "doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "requires": { + "esutils": "^2.0.2" + } + }, "domexception": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/domexception/-/domexception-4.0.0.tgz", @@ -4986,6 +8787,15 @@ "webidl-conversions": "^7.0.0" } }, + "dot-prop": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", + "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==", + "dev": true, + "requires": { + "is-obj": "^2.0.0" + } + }, "ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", @@ -4998,6 +8808,12 @@ "integrity": "sha512-/bKPPcgZVUziECqDc+0HkT87+0zhaWSZHNXqF8FLd2lQcptpmUFwoCSWjCdOng9Gdq+afKArPdEg/0ZW461Eng==", "dev": true }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, "encodeurl": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", @@ -5025,6 +8841,15 @@ "integrity": "sha512-G9/6xF1FPbIw0TtalAMaVPpiq2aDEuKLXM314jPVAO9r2fo2a4BLqMNkmRS7O/xPPZ+COAhGIz3ETvHEV3eUcg==", "dev": true }, + "error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "requires": { + "is-arrayish": "^0.2.1" + } + }, "es-module-lexer": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.4.1.tgz", @@ -5043,6 +8868,244 @@ "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", "dev": true }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true + }, + "eslint": { + "version": "4.19.1", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-4.19.1.tgz", + "integrity": "sha512-bT3/1x1EbZB7phzYu7vCr1v3ONuzDtX8WjuM9c0iYxe+cq+pwcKEoQjl7zd3RpC6YOLgnSy3cTN58M2jcoPDIQ==", + "dev": true, + "requires": { + "ajv": "^5.3.0", + "babel-code-frame": "^6.22.0", + "chalk": "^2.1.0", + "concat-stream": "^1.6.0", + "cross-spawn": "^5.1.0", + "debug": "^3.1.0", + "doctrine": "^2.1.0", + "eslint-scope": "^3.7.1", + "eslint-visitor-keys": "^1.0.0", + "espree": "^3.5.4", + "esquery": "^1.0.0", + "esutils": "^2.0.2", + "file-entry-cache": "^2.0.0", + "functional-red-black-tree": "^1.0.1", + "glob": "^7.1.2", + "globals": "^11.0.1", + "ignore": "^3.3.3", + "imurmurhash": "^0.1.4", + "inquirer": "^3.0.6", + "is-resolvable": "^1.0.0", + "js-yaml": "^3.9.1", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.3.0", + "lodash": "^4.17.4", + "minimatch": "^3.0.2", + "mkdirp": "^0.5.1", + "natural-compare": "^1.4.0", + "optionator": "^0.8.2", + "path-is-inside": "^1.0.2", + "pluralize": "^7.0.0", + "progress": "^2.0.0", + "regexpp": "^1.0.1", + "require-uncached": "^1.0.3", + "semver": "^5.3.0", + "strip-ansi": "^4.0.0", + "strip-json-comments": "~2.0.1", + "table": "4.0.2", + "text-table": "~0.2.0" + }, + "dependencies": { + "ajv": { + "version": "5.5.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz", + "integrity": "sha512-Ajr4IcMXq/2QmMkEmSvxqfLN5zGmJ92gHXAeOXq1OekoH2rfDNsgdDoL2f7QaRCy7G/E6TpxBVdRuNraMztGHw==", + "dev": true, + "requires": { + "co": "^4.6.0", + "fast-deep-equal": "^1.0.0", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.3.0" + } + }, + "ansi-regex": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz", + "integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==", + "dev": true + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "cross-spawn": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", + "integrity": "sha512-pTgQJ5KC0d2hcY8eyL1IzlBPYjTkyH72XRZPnLyKus2mBfNjQs3klqbJU2VILqZryAZUt9JOb3h/mWMy23/f5A==", + "dev": true, + "requires": { + "lru-cache": "^4.0.1", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "eslint-scope": { + "version": "3.7.3", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-3.7.3.tgz", + "integrity": "sha512-W+B0SvF4gamyCTmUc+uITPY0989iXVfKvhwtmJocTaYoc/3khEHmEmvfY/Gn9HA9VV75jrQECsHizkNw1b68FA==", + "dev": true, + "requires": { + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" + } + }, + "fast-deep-equal": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz", + "integrity": "sha512-fueX787WZKCV0Is4/T2cyAdM4+x1S3MXXOAhavE1ys/W42SHAPacLTQhucja22QBYrfGw50M2sRiXPtTGv9Ymw==", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true + }, + "js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "json-schema-traverse": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz", + "integrity": "sha512-4JD/Ivzg7PoW8NzdrBSr3UFwC9mHgvI7Z6z3QGBsSHgKaRTUDmyZAAKJo2UbG1kUVfS9WS8bi36N49U1xw43DA==", + "dev": true + }, + "lru-cache": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", + "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", + "dev": true, + "requires": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + }, + "semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true + }, + "shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==", + "dev": true, + "requires": { + "shebang-regex": "^1.0.0" + } + }, + "shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==", + "dev": true + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==", + "dev": true + } + } + }, "eslint-scope": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", @@ -5053,6 +9116,53 @@ "estraverse": "^4.1.1" } }, + "eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true + }, + "espree": { + "version": "3.5.4", + "resolved": "https://registry.npmjs.org/espree/-/espree-3.5.4.tgz", + "integrity": "sha512-yAcIQxtmMiB/jL32dzEp2enBeidsB7xWPLNiw3IIkpVds1P+h7qF9YwJq1yUNzp2OKXgAprs4F61ih66UsoD1A==", + "dev": true, + "requires": { + "acorn": "^5.5.0", + "acorn-jsx": "^3.0.0" + }, + "dependencies": { + "acorn": { + "version": "5.7.4", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.4.tgz", + "integrity": "sha512-1D++VG7BhrtvQpNbBzovKNc1FLGGEE/oGe7b9xJm/RFHMBeUaUGpluV9RLjZa47YFdPcDAenEYuq9pQPcMdLJg==", + "dev": true + } + } + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true + }, + "esquery": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", + "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", + "dev": true, + "requires": { + "estraverse": "^5.1.0" + }, + "dependencies": { + "estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true + } + } + }, "esrecurse": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", @@ -5076,6 +9186,12 @@ "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", "dev": true }, + "esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true + }, "etag": { "version": "1.8.1", "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", @@ -5173,6 +9289,28 @@ } } }, + "external-editor": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-2.2.0.tgz", + "integrity": "sha512-bSn6gvGxKt+b7+6TKEv1ZycHleA7aHhRHyAqJyp5pbUFuYYNIzpZnQDk7AsYckyWdEnTeAnay0aCy2aV6iTk9A==", + "dev": true, + "requires": { + "chardet": "^0.4.0", + "iconv-lite": "^0.4.17", + "tmp": "^0.0.33" + }, + "dependencies": { + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + } + } + }, "fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -5185,6 +9323,12 @@ "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", "dev": true }, + "fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true + }, "fastest-levenshtein": { "version": "1.0.16", "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz", @@ -5200,6 +9344,25 @@ "websocket-driver": ">=0.5.1" } }, + "figures": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", + "integrity": "sha512-Oa2M9atig69ZkfwiApY8F2Yy+tzMbazyvqv21R0NsSC8floSOC09BbT1ITWAdoMGQvJ/aZnR1KMwdx9tvHnTNA==", + "dev": true, + "requires": { + "escape-string-regexp": "^1.0.5" + } + }, + "file-entry-cache": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-2.0.0.tgz", + "integrity": "sha512-uXP/zGzxxFvFfcZGgBIwotm+Tdc55ddPAzF7iHshP4YGaXMww7rSF9peD9D1sui5ebONg5UobsZv+FfgEpGv/w==", + "dev": true, + "requires": { + "flat-cache": "^1.2.1", + "object-assign": "^4.0.1" + } + }, "fill-range": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", @@ -5257,6 +9420,29 @@ "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", "dev": true }, + "flat-cache": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.3.4.tgz", + "integrity": "sha512-VwyB3Lkgacfik2vhqR4uv2rvebqmDvFu4jlN/C1RzWoJEo8I7z4Q404oiqYCkq41mni8EzQnm95emU9seckwtg==", + "dev": true, + "requires": { + "circular-json": "^0.3.1", + "graceful-fs": "^4.1.2", + "rimraf": "~2.6.2", + "write": "^0.2.1" + }, + "dependencies": { + "rimraf": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", + "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + } + } + }, "follow-redirects": { "version": "1.15.3", "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.3.tgz", @@ -5285,6 +9471,25 @@ "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", "dev": true }, + "fs-extra": { + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz", + "integrity": "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==", + "dev": true, + "requires": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "dependencies": { + "universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "dev": true + } + } + }, "fs-monkey": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.0.5.tgz", @@ -5310,6 +9515,18 @@ "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", "dev": true }, + "functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==", + "dev": true + }, + "get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true + }, "get-intrinsic": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.2.tgz", @@ -5328,6 +9545,19 @@ "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", "dev": true }, + "git-raw-commits": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/git-raw-commits/-/git-raw-commits-2.0.11.tgz", + "integrity": "sha512-VnctFhw+xfj8Va1xtfEqCUD2XDrbAPSJx+hSrE5K7fGdjZruW7XV+QOrN7LF/RJyvspRiD2I0asWsxFp0ya26A==", + "dev": true, + "requires": { + "dargs": "^7.0.0", + "lodash": "^4.17.15", + "meow": "^8.0.0", + "split2": "^3.0.0", + "through2": "^4.0.0" + } + }, "glob": { "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", @@ -5357,6 +9587,21 @@ "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", "dev": true }, + "global-dirs": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-0.1.1.tgz", + "integrity": "sha512-NknMLn7F2J7aflwFOlGdNIuCDpN3VGoSoB+aap3KABFWbHVn1TCgFC+np23J8W2BiZbjfEw3BFBycSMv1AFblg==", + "dev": true, + "requires": { + "ini": "^1.3.4" + } + }, + "globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true + }, "gopd": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", @@ -5378,6 +9623,29 @@ "integrity": "sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==", "dev": true }, + "hard-rejection": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz", + "integrity": "sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==", + "dev": true + }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha512-C8vBJ8DwUCx19vhm7urhTuUsr4/IyP6l4VzNQDv+ryHQObW3TTTp9yB68WpYgRe2bbaGuZ/se74IqFeVnMnLZg==", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", + "dev": true + } + } + }, "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -5414,6 +9682,15 @@ "function-bind": "^1.1.2" } }, + "hosted-git-info": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz", + "integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + }, "hpack.js": { "version": "2.1.6", "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz", @@ -5554,6 +9831,30 @@ "safer-buffer": ">= 2.1.2 < 3.0.0" } }, + "ignore": { + "version": "3.3.10", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.10.tgz", + "integrity": "sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug==", + "dev": true + }, + "import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "requires": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "dependencies": { + "resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true + } + } + }, "import-local": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", @@ -5564,6 +9865,18 @@ "resolve-cwd": "^3.0.0" } }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true + }, + "indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "dev": true + }, "inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", @@ -5580,6 +9893,117 @@ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true }, + "ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "dev": true + }, + "inquirer": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-3.3.0.tgz", + "integrity": "sha512-h+xtnyk4EwKvFWHrUYsWErEVR+igKtLdchu+o0Z1RL7VU/jVMFbYir2bp6bAj8efFNxWqHX0dIss6fJQ+/+qeQ==", + "dev": true, + "requires": { + "ansi-escapes": "^3.0.0", + "chalk": "^2.0.0", + "cli-cursor": "^2.1.0", + "cli-width": "^2.0.0", + "external-editor": "^2.0.4", + "figures": "^2.0.0", + "lodash": "^4.3.0", + "mute-stream": "0.0.7", + "run-async": "^2.2.0", + "rx-lite": "^4.0.8", + "rx-lite-aggregates": "^4.0.8", + "string-width": "^2.1.0", + "strip-ansi": "^4.0.0", + "through": "^2.3.6" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz", + "integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==", + "dev": true + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", + "dev": true + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + } + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, "interpret": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/interpret/-/interpret-2.2.0.tgz", @@ -5592,6 +10016,12 @@ "integrity": "sha512-LlbxQ7xKzfBusov6UMi4MFpEg0m+mAm9xyNGEduwXMEDuf4WfzB/RZwMVYEd7IKGvh4IUkEXYxtAVu9T3OelJQ==", "dev": true }, + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "dev": true + }, "is-binary-path": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", @@ -5622,6 +10052,12 @@ "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", "dev": true }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, "is-glob": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", @@ -5637,6 +10073,12 @@ "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "dev": true }, + "is-obj": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", + "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", + "dev": true + }, "is-plain-obj": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-3.0.0.tgz", @@ -5657,12 +10099,27 @@ "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==" }, + "is-resolvable": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz", + "integrity": "sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==", + "dev": true + }, "is-stream": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", "dev": true }, + "is-text-path": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-text-path/-/is-text-path-1.0.1.tgz", + "integrity": "sha512-xFuJpne9oFz5qDaodwmmG08e3CawH/2ZV8Qqza1Ko7Sk8POWbkRdwIoAWVhqvq0XeUzANEhKo2n0IXUGBm7A/w==", + "dev": true, + "requires": { + "text-extensions": "^1.0.0" + } + }, "is-wsl": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", @@ -5701,6 +10158,21 @@ "supports-color": "^8.0.0" } }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "requires": { + "argparse": "^2.0.1" + } + }, "jsdom": { "version": "22.1.0", "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-22.1.0.tgz", @@ -5743,6 +10215,46 @@ "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", "dev": true }, + "json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true + }, + "jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.6", + "universalify": "^2.0.0" + }, + "dependencies": { + "universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "dev": true + } + } + }, + "jsonparse": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", + "integrity": "sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==", + "dev": true + }, + "JSONStream": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz", + "integrity": "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==", + "dev": true, + "requires": { + "jsonparse": "^1.2.0", + "through": ">=2.2.7 <3" + } + }, "kind-of": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", @@ -5759,6 +10271,22 @@ "shell-quote": "^1.8.1" } }, + "levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==", + "dev": true, + "requires": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + } + }, + "lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true + }, "loader-runner": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", @@ -5774,6 +10302,93 @@ "p-locate": "^4.1.0" } }, + "lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true + }, + "lodash.camelcase": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", + "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==", + "dev": true + }, + "lodash.isfunction": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/lodash.isfunction/-/lodash.isfunction-3.0.9.tgz", + "integrity": "sha512-AirXNj15uRIMMPihnkInB4i3NHeb4iBtNg9WRWuK2o31S+ePwwNmDPaTL3o7dTJ+VXNZim7rFs4rxN4YU1oUJw==", + "dev": true + }, + "lodash.isplainobject": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", + "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==", + "dev": true + }, + "lodash.kebabcase": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.kebabcase/-/lodash.kebabcase-4.1.1.tgz", + "integrity": "sha512-N8XRTIMMqqDgSy4VLKPnJ/+hpGZN+PHQiJnSenYqPaVV/NCqEogTnAdZLQiGKhxX+JCs8waWq2t1XHWKOmlY8g==", + "dev": true + }, + "lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, + "lodash.mergewith": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.mergewith/-/lodash.mergewith-4.6.2.tgz", + "integrity": "sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ==", + "dev": true + }, + "lodash.snakecase": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.snakecase/-/lodash.snakecase-4.1.1.tgz", + "integrity": "sha512-QZ1d4xoBHYUeuouhEq3lk3Uq7ldgyFXGBhg04+oRLnIz8o9T65Eh+8YdroUwn846zchkA9yDsDl5CVVaV2nqYw==", + "dev": true + }, + "lodash.startcase": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.startcase/-/lodash.startcase-4.4.0.tgz", + "integrity": "sha512-+WKqsK294HMSc2jEbNgpHpd0JfIBhp7rEV4aqXWqFr6AlXov+SlcgB1Fv01y2kGe3Gc8nMW7VA0SrGuSkRfIEg==", + "dev": true + }, + "lodash.uniq": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", + "integrity": "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==", + "dev": true + }, + "lodash.upperfirst": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/lodash.upperfirst/-/lodash.upperfirst-4.3.1.tgz", + "integrity": "sha512-sReKOYJIJf74dhJONhU4e0/shzi1trVbSWDOhKYE5XV2O+H7Sb2Dihwuc7xWxVl+DgFPyTqIN3zMfT9cq5iWDg==", + "dev": true + }, + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true + }, + "map-obj": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.3.0.tgz", + "integrity": "sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==", + "dev": true + }, "media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", @@ -5789,6 +10404,25 @@ "fs-monkey": "^1.0.4" } }, + "meow": { + "version": "8.1.2", + "resolved": "https://registry.npmjs.org/meow/-/meow-8.1.2.tgz", + "integrity": "sha512-r85E3NdZ+mpYk1C6RjPFEMSE+s1iZMuHtsHAqY0DT3jZczl0diWUZ8g6oU7h0M9cD2EL+PzaYghhCLzR0ZNn5Q==", + "dev": true, + "requires": { + "@types/minimist": "^1.2.0", + "camelcase-keys": "^6.2.2", + "decamelize-keys": "^1.1.0", + "hard-rejection": "^2.1.0", + "minimist-options": "4.1.0", + "normalize-package-data": "^3.0.0", + "read-pkg-up": "^7.0.1", + "redent": "^3.0.0", + "trim-newlines": "^3.0.0", + "type-fest": "^0.18.0", + "yargs-parser": "^20.2.3" + } + }, "merge-descriptors": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", @@ -5842,6 +10476,12 @@ "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", "dev": true }, + "min-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", + "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", + "dev": true + }, "minimalistic-assert": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", @@ -5857,6 +10497,40 @@ "brace-expansion": "^1.1.7" } }, + "minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true + }, + "minimist-options": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-4.1.0.tgz", + "integrity": "sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==", + "dev": true, + "requires": { + "arrify": "^1.0.1", + "is-plain-obj": "^1.1.0", + "kind-of": "^6.0.3" + }, + "dependencies": { + "is-plain-obj": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", + "integrity": "sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==", + "dev": true + } + } + }, + "mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "dev": true, + "requires": { + "minimist": "^1.2.6" + } + }, "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -5872,6 +10546,18 @@ "thunky": "^1.0.2" } }, + "mute-stream": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", + "integrity": "sha512-r65nCZhrbXXb6dXOACihYApHw2Q6pV0M3V0PSxd74N0+D8nzAdEAITq2oAjA1jVnKI+tGvEBUpqiMh0+rW6zDQ==", + "dev": true + }, + "natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true + }, "negotiator": { "version": "0.6.3", "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", @@ -5896,6 +10582,18 @@ "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==", "dev": true }, + "normalize-package-data": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.3.tgz", + "integrity": "sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==", + "dev": true, + "requires": { + "hosted-git-info": "^4.0.1", + "is-core-module": "^2.5.0", + "semver": "^7.3.4", + "validate-npm-package-license": "^3.0.1" + } + }, "normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", @@ -5916,6 +10614,12 @@ "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.7.tgz", "integrity": "sha512-ub5E4+FBPKwAZx0UwIQOjYWGHTEq5sPqHQNRN8Z9e4A7u3Tj1weLJsL59yH9vmvqEtBHaOmT6cYQKIZOxp35FQ==" }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "dev": true + }, "object-inspect": { "version": "1.13.1", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", @@ -5972,6 +10676,26 @@ "is-wsl": "^2.2.0" } }, + "optionator": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", + "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", + "dev": true, + "requires": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.6", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "word-wrap": "~1.2.3" + } + }, + "os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", + "dev": true + }, "p-limit": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", @@ -6006,6 +10730,27 @@ "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", "dev": true }, + "parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "requires": { + "callsites": "^3.0.0" + } + }, + "parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + } + }, "parse5": { "version": "7.1.2", "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz", @@ -6032,6 +10777,12 @@ "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", "dev": true }, + "path-is-inside": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", + "integrity": "sha512-DUWJr3+ULp4zXmol/SZkFf3JGsS9/SIv+Y3Rt93/UjPpDpklB5f1er4O3POIbUuUJ3FXgqte2Q7SrU6zAqwk8w==", + "dev": true + }, "path-key": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", @@ -6050,6 +10801,12 @@ "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==", "dev": true }, + "path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true + }, "picocolors": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", @@ -6071,12 +10828,30 @@ "find-up": "^4.0.0" } }, + "pluralize": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-7.0.0.tgz", + "integrity": "sha512-ARhBOdzS3e41FbkW/XWrTEtukqqLoK5+Z/4UeDaLuSW+39JPeFgs4gCGqsrJHVZX0fUrx//4OF0K1CUGwlIFow==", + "dev": true + }, + "prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==", + "dev": true + }, "process-nextick-args": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", "dev": true }, + "progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "dev": true + }, "proxy-addr": { "version": "2.0.7", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", @@ -6095,6 +10870,12 @@ } } }, + "pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==", + "dev": true + }, "psl": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", @@ -6119,6 +10900,12 @@ "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==" }, + "quick-lru": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz", + "integrity": "sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==", + "dev": true + }, "randombytes": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", @@ -6163,6 +10950,69 @@ } } }, + "read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "dev": true, + "requires": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "dependencies": { + "hosted-git-info": { + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", + "dev": true + }, + "normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "requires": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true + }, + "type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "dev": true + } + } + }, + "read-pkg-up": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", + "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "dev": true, + "requires": { + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" + }, + "dependencies": { + "type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true + } + } + }, "readable-stream": { "version": "3.6.2", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", @@ -6192,12 +11042,52 @@ "resolve": "^1.9.0" } }, + "redent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", + "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", + "dev": true, + "requires": { + "indent-string": "^4.0.0", + "strip-indent": "^3.0.0" + } + }, + "regexpp": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-1.1.0.tgz", + "integrity": "sha512-LOPw8FpgdQF9etWMaAfG/WRthIdXJGYp4mJ2Jgn/2lpkbod9jPn0t9UqN7AxBOKNfzRbYyVfgc7Vk4t/MpnXgw==", + "dev": true + }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "dev": true + }, "require-from-string": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", "dev": true }, + "require-uncached": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz", + "integrity": "sha512-Xct+41K3twrbBHdxAgMoOS+cNcoqIjfM2/VxBF4LL2hVph7YsF8VSKyQ3BDFZwEVbok9yeDl2le/qo0S77WG2w==", + "dev": true, + "requires": { + "caller-path": "^0.1.0", + "resolve-from": "^1.0.0" + }, + "dependencies": { + "resolve-from": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-1.0.1.tgz", + "integrity": "sha512-kT10v4dhrlLNcnO084hEjvXCI1wUG9qZLoz2RogxqDQQYy7IxjI/iMUkOtQTNEh6rzHxvdQWHsJyel1pKOVCxg==", + "dev": true + } + } + }, "requires-port": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", @@ -6229,6 +11119,42 @@ "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", "dev": true }, + "resolve-global": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/resolve-global/-/resolve-global-1.0.0.tgz", + "integrity": "sha512-zFa12V4OLtT5XUX/Q4VLvTfBf+Ok0SPc1FNGM/z9ctUdiU618qwKpWnd0CHs3+RqROfyEg/DhuHbMWYqcgljEw==", + "dev": true, + "requires": { + "global-dirs": "^0.1.1" + } + }, + "restore-cursor": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", + "integrity": "sha512-6IzJLuGi4+R14vwagDHX+JrXmPVtPpn4mffDJ1UdR7/Edm87fl6yi8mMBIVvFtJaNTUvjughmW4hwLhRG7gC1Q==", + "dev": true, + "requires": { + "onetime": "^2.0.0", + "signal-exit": "^3.0.2" + }, + "dependencies": { + "mimic-fn": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", + "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", + "dev": true + }, + "onetime": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", + "integrity": "sha512-oyyPpiMaKARvvcgip+JV+7zci5L8D1W9RZIz2l1o08AM3pfspitVWnPt3mzHcBPp12oYMTy0pqrFs/C+m3EwsQ==", + "dev": true, + "requires": { + "mimic-fn": "^1.0.0" + } + } + } + }, "retry": { "version": "0.13.1", "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", @@ -6249,6 +11175,27 @@ "resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.6.0.tgz", "integrity": "sha512-APM0Gt1KoXBz0iIkkdB/kfvGOwC4UuJFeG/c+yV7wSc7q96cG/kJ0HiYCnzivD9SB53cLV1MlHFNfOuPaadYSw==" }, + "run-async": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", + "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==", + "dev": true + }, + "rx-lite": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-4.0.8.tgz", + "integrity": "sha512-Cun9QucwK6MIrp3mry/Y7hqD1oFqTYLQ4pGxaHTjIdaFDWRGGLikqp6u8LcWJnzpoALg9hap+JGk8sFIUuEGNA==", + "dev": true + }, + "rx-lite-aggregates": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/rx-lite-aggregates/-/rx-lite-aggregates-4.0.8.tgz", + "integrity": "sha512-3xPNZGW93oCjiO7PtKxRK6iOVYBWBvtf9QHDfU23Oc+dLIQmAV//UnyXV/yihv81VS/UqoQPk4NegS8EFi55Hg==", + "dev": true, + "requires": { + "rx-lite": "*" + } + }, "safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", @@ -6295,6 +11242,15 @@ "node-forge": "^1" } }, + "semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + }, "send": { "version": "0.18.0", "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", @@ -6495,6 +11451,23 @@ "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", "dev": true }, + "slice-ansi": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-1.0.0.tgz", + "integrity": "sha512-POqxBK6Lb3q6s047D/XsDVNPnF9Dl8JSaqe9h9lURl0OdNqy/ujDrOiIHtsqXMGbWWTIomRzAMaTyawAU//Reg==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "^2.0.0" + }, + "dependencies": { + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", + "dev": true + } + } + }, "sockjs": { "version": "0.3.24", "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.24.tgz", @@ -6539,6 +11512,38 @@ "source-map": "^0.6.0" } }, + "spdx-correct": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", + "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", + "dev": true, + "requires": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-exceptions": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz", + "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==", + "dev": true + }, + "spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "dev": true, + "requires": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-license-ids": { + "version": "3.0.17", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.17.tgz", + "integrity": "sha512-sh8PWc/ftMqAAdFiBu6Fy6JUOYjqDJBJvIhpfDMyHrr0Rbp5liZqd4TjtQ/RgfLjKFZb+LMx5hpml5qOWy0qvg==", + "dev": true + }, "spdy": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.2.tgz", @@ -6566,6 +11571,21 @@ "wbuf": "^1.7.3" } }, + "split2": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/split2/-/split2-3.2.2.tgz", + "integrity": "sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg==", + "dev": true, + "requires": { + "readable-stream": "^3.0.0" + } + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "dev": true + }, "statuses": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", @@ -6581,12 +11601,47 @@ "safe-buffer": "~5.2.0" } }, + "string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + } + }, + "strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.1" + } + }, "strip-final-newline": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", "dev": true }, + "strip-indent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", + "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", + "dev": true, + "requires": { + "min-indent": "^1.0.0" + } + }, + "strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", + "dev": true + }, "supports-color": { "version": "8.1.1", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", @@ -6607,6 +11662,134 @@ "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==" }, + "table": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/table/-/table-4.0.2.tgz", + "integrity": "sha512-UUkEAPdSGxtRpiV9ozJ5cMTtYiqz7Ni1OGqLXRCynrvzdtR1p+cfOWe2RJLwvUG8hNanaSRjecIqwOjqeatDsA==", + "dev": true, + "requires": { + "ajv": "^5.2.3", + "ajv-keywords": "^2.1.0", + "chalk": "^2.1.0", + "lodash": "^4.17.4", + "slice-ansi": "1.0.0", + "string-width": "^2.1.1" + }, + "dependencies": { + "ajv": { + "version": "5.5.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz", + "integrity": "sha512-Ajr4IcMXq/2QmMkEmSvxqfLN5zGmJ92gHXAeOXq1OekoH2rfDNsgdDoL2f7QaRCy7G/E6TpxBVdRuNraMztGHw==", + "dev": true, + "requires": { + "co": "^4.6.0", + "fast-deep-equal": "^1.0.0", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.3.0" + } + }, + "ajv-keywords": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-2.1.1.tgz", + "integrity": "sha512-ZFztHzVRdGLAzJmpUT9LNFLe1YiVOEylcaNpEutM26PVTCtOD919IMfD01CgbRouB42Dd9atjx1HseC15DgOZA==", + "dev": true, + "requires": {} + }, + "ansi-regex": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz", + "integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==", + "dev": true + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "fast-deep-equal": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz", + "integrity": "sha512-fueX787WZKCV0Is4/T2cyAdM4+x1S3MXXOAhavE1ys/W42SHAPacLTQhucja22QBYrfGw50M2sRiXPtTGv9Ymw==", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", + "dev": true + }, + "json-schema-traverse": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz", + "integrity": "sha512-4JD/Ivzg7PoW8NzdrBSr3UFwC9mHgvI7Z6z3QGBsSHgKaRTUDmyZAAKJo2UbG1kUVfS9WS8bi36N49U1xw43DA==", + "dev": true + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + } + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, "tapable": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", @@ -6638,12 +11821,48 @@ "terser": "^5.16.8" } }, + "text-extensions": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/text-extensions/-/text-extensions-1.9.0.tgz", + "integrity": "sha512-wiBrwC1EhBelW12Zy26JeOUkQ5mRu+5o8rpsJk5+2t+Y5vE7e842qtZDQ2g1NpX/29HdyFeJ4nSIhI47ENSxlQ==", + "dev": true + }, + "text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", + "dev": true + }, + "through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", + "dev": true + }, + "through2": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/through2/-/through2-4.0.2.tgz", + "integrity": "sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==", + "dev": true, + "requires": { + "readable-stream": "3" + } + }, "thunky": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz", "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==", "dev": true }, + "tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "dev": true, + "requires": { + "os-tmpdir": "~1.0.2" + } + }, "to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", @@ -6678,6 +11897,48 @@ "punycode": "^2.3.0" } }, + "trim-newlines": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.1.tgz", + "integrity": "sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==", + "dev": true + }, + "ts-node": { + "version": "10.9.2", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", + "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", + "dev": true, + "requires": { + "@cspotcode/source-map-support": "^0.8.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "v8-compile-cache-lib": "^3.0.1", + "yn": "3.1.1" + } + }, + "type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==", + "dev": true, + "requires": { + "prelude-ls": "~1.1.2" + } + }, + "type-fest": { + "version": "0.18.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.18.1.tgz", + "integrity": "sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw==", + "dev": true + }, "type-is": { "version": "1.6.18", "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", @@ -6688,6 +11949,18 @@ "mime-types": "~2.1.24" } }, + "typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==", + "dev": true + }, + "typescript": { + "version": "5.4.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz", + "integrity": "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==", + "dev": true + }, "undici-types": { "version": "5.26.5", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", @@ -6751,6 +12024,22 @@ "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", "dev": true }, + "v8-compile-cache-lib": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", + "dev": true + }, + "validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "requires": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, "vary": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", @@ -7053,12 +12342,38 @@ "integrity": "sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==", "dev": true }, + "word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true + }, + "wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + } + }, "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", "dev": true }, + "write": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/write/-/write-0.2.1.tgz", + "integrity": "sha512-CJ17OoULEKXpA5pef3qLj5AxTJ6mSt7g84he2WIskKwqFO4T97d5V7Tadl0DYDk7qyUOQD5WlUlOMChaYrhxeA==", + "dev": true, + "requires": { + "mkdirp": "^0.5.1" + } + }, "ws": { "version": "8.15.1", "resolved": "https://registry.npmjs.org/ws/-/ws-8.15.1.tgz", @@ -7074,6 +12389,59 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==" + }, + "y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "dev": true, + "requires": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "dependencies": { + "yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true + } + } + }, + "yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "dev": true + }, + "yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "dev": true + }, + "yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true } } } diff --git a/package.json b/package.json index c0e8b1df79..1f02c6681d 100644 --- a/package.json +++ b/package.json @@ -14,9 +14,13 @@ "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "build": "webpack --mode production", - "start": "webpack serve --open --mode development" + "start": "webpack serve --open --mode development", + "test:lint": "eslint ." }, "devDependencies": { + "@commitlint/cli": "^17.8.1", + "@commitlint/config-conventional": "^17.8.1", + "eslint": "^4.19.1", "source-map-loader": "^4.0.1", "webpack": "^5.76.0", "webpack-cli": "^4.10.0", @@ -25,4 +29,4 @@ "dependencies": { "blockly": "^10.0.0" } -} \ No newline at end of file +} From 3125c37b4a633421d575f65954db44cef63d151d Mon Sep 17 00:00:00 2001 From: Aaron Dodson Date: Mon, 15 Apr 2024 13:26:06 -0700 Subject: [PATCH 006/130] chore: remove build/test Github action (#18) --- .github/workflows/deploy.yml | 49 ------------------------------------ 1 file changed, 49 deletions(-) delete mode 100644 .github/workflows/deploy.yml diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml deleted file mode 100644 index cd39592905..0000000000 --- a/.github/workflows/deploy.yml +++ /dev/null @@ -1,49 +0,0 @@ -name: build-scratch-blocks -on: - push: # Runs whenever a commit is pushed to the repository - workflow_dispatch: # Allows you to run this workflow manually from the Actions tab -jobs: - setup: - runs-on: ubuntu-latest - env: - JVM_OPTS: -Xmx3200m - PROJECT_PATH: ./scratch-blocks - steps: - - run: | - for F in chrome chromium chromedriver; do - which $F && $F --version || echo Not found: $F - done - - uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3 - - name: Check Python version - run: python --version - - name: Setup Java - uses: actions/setup-java@0ab4596768b603586c0de567f2430c30f5b0d2b0 # v3 - with: - distribution: 'temurin' - java-version: 17 - - name: Setup Node - uses: actions/setup-node@1a4442cacd436585916779262731d5b162bc6ec7 # v3 - with: - node-version-file: '.nvmrc' - - name: Install Node Dependencies - run: npm ci - - name: Lint - run: npm run test:lint - - name: Run Tests - run: npm run test:messages - - name: Run Unit Tests - run: DISPLAY=:99 npm run test:unit - - name: Remove Closure App - run: rm -rf gh-pages/closure-library/scripts/ci/CloseAdobeDialog.exe - - name: Deploy playground to GitHub Pages - uses: peaceiris/actions-gh-pages@373f7f263a76c20808c831209c920827a82a2847 # v3 - with: - github_token: ${{ secrets.GITHUB_TOKEN }} - publish_dir: ./gh-pages - full_commit_message: "Build for ${{ github.sha }} ${{ github.event.head_commit.message }}" - enable_jekyll: true - - name: Run semantic-release - env: - NPM_TOKEN: ${{ secrets.NPM_TOKEN }} - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: npx --no -- semantic-release From 8024e9fd638586d26e6b47424e0067c0387af8cd Mon Sep 17 00:00:00 2001 From: Aaron Dodson Date: Wed, 17 Apr 2024 11:03:06 -0700 Subject: [PATCH 007/130] fix: readd the operator blocks and dependencies (#19) * fix: readd the operator blocks and dependencies * fix: only import core Blockly blocks_common/math.js Co-authored-by: Beka Westberg * fix: only import core Blockly in vertical_extensions.js --------- Co-authored-by: Beka Westberg --- blocks_common/math.js | 61 ++++++++++------------ blocks_vertical/operators.js | 47 ++++++++--------- blocks_vertical/vertical_extensions.js | 70 ++++++++++++-------------- src/categories.js | 15 ++++++ src/index.js | 5 ++ 5 files changed, 100 insertions(+), 98 deletions(-) create mode 100644 src/categories.js diff --git a/blocks_common/math.js b/blocks_common/math.js index 63a95e9887..542026127f 100644 --- a/blocks_common/math.js +++ b/blocks_common/math.js @@ -22,15 +22,8 @@ * @fileoverview Math blocks for Blockly. * @author q.neutron@gmail.com (Quynh Neutron) */ -'use strict'; - -goog.provide('Blockly.Blocks.math'); - -goog.require('Blockly.Blocks'); - -goog.require('Blockly.Colours'); - -goog.require('Blockly.constants'); +import * as Blockly from 'blockly/core'; +import {Colours} from '../core/colours.js'; Blockly.Blocks['math_number'] = { /** @@ -48,11 +41,11 @@ Blockly.Blocks['math_number'] = { } ], "output": "Number", - "outputShape": Blockly.OUTPUT_SHAPE_ROUND, - "colour": Blockly.Colours.textField, - "colourSecondary": Blockly.Colours.textField, - "colourTertiary": Blockly.Colours.textField, - "colourQuaternary": Blockly.Colours.textField + // "outputShape": Blockly.OUTPUT_SHAPE_ROUND, + "colour": Colours.textField, + "colourSecondary": Colours.textField, + "colourTertiary": Colours.textField, + "colourQuaternary": Colours.textField }); } }; @@ -73,11 +66,11 @@ Blockly.Blocks['math_integer'] = { } ], "output": "Number", - "outputShape": Blockly.OUTPUT_SHAPE_ROUND, - "colour": Blockly.Colours.textField, - "colourSecondary": Blockly.Colours.textField, - "colourTertiary": Blockly.Colours.textField, - "colourQuaternary": Blockly.Colours.textField + // "outputShape": Blockly.OUTPUT_SHAPE_ROUND, + "colour": Colours.textField, + "colourSecondary": Colours.textField, + "colourTertiary": Colours.textField, + "colourQuaternary": Colours.textField }); } }; @@ -99,11 +92,11 @@ Blockly.Blocks['math_whole_number'] = { } ], "output": "Number", - "outputShape": Blockly.OUTPUT_SHAPE_ROUND, - "colour": Blockly.Colours.textField, - "colourSecondary": Blockly.Colours.textField, - "colourTertiary": Blockly.Colours.textField, - "colourQuaternary": Blockly.Colours.textField + // "outputShape": Blockly.OUTPUT_SHAPE_ROUND, + "colour": Colours.textField, + "colourSecondary": Colours.textField, + "colourTertiary": Colours.textField, + "colourQuaternary": Colours.textField }); } }; @@ -124,11 +117,11 @@ Blockly.Blocks['math_positive_number'] = { } ], "output": "Number", - "outputShape": Blockly.OUTPUT_SHAPE_ROUND, - "colour": Blockly.Colours.textField, - "colourSecondary": Blockly.Colours.textField, - "colourTertiary": Blockly.Colours.textField, - "colourQuaternary": Blockly.Colours.textField + // "outputShape": Blockly.OUTPUT_SHAPE_ROUND, + "colour": Colours.textField, + "colourSecondary": Colours.textField, + "colourTertiary": Colours.textField, + "colourQuaternary": Colours.textField }); } }; @@ -149,11 +142,11 @@ Blockly.Blocks['math_angle'] = { } ], "output": "Number", - "outputShape": Blockly.OUTPUT_SHAPE_ROUND, - "colour": Blockly.Colours.textField, - "colourSecondary": Blockly.Colours.textField, - "colourTertiary": Blockly.Colours.textField, - "colourQuaternary": Blockly.Colours.textField + // "outputShape": Blockly.OUTPUT_SHAPE_ROUND, + "colour": Colours.textField, + "colourSecondary": Colours.textField, + "colourTertiary": Colours.textField, + "colourQuaternary": Colours.textField }); } }; diff --git a/blocks_vertical/operators.js b/blocks_vertical/operators.js index 1caa04481c..f47c8743bf 100644 --- a/blocks_vertical/operators.js +++ b/blocks_vertical/operators.js @@ -18,15 +18,8 @@ * limitations under the License. */ -'use strict'; - -goog.provide('Blockly.Blocks.operators'); - -goog.require('Blockly.Blocks'); -goog.require('Blockly.Colours'); -goog.require('Blockly.constants'); -goog.require('Blockly.ScratchBlocks.VerticalExtensions'); - +import * as Blockly from 'blockly'; +import {Categories} from '../src/categories.js'; Blockly.Blocks['operator_add'] = { /** @@ -46,7 +39,7 @@ Blockly.Blocks['operator_add'] = { "name": "NUM2" } ], - "category": Blockly.Categories.operators, + "category": Categories.operators, "extensions": ["colours_operators", "output_number"] }); } @@ -70,7 +63,7 @@ Blockly.Blocks['operator_subtract'] = { "name": "NUM2" } ], - "category": Blockly.Categories.operators, + "category": Categories.operators, "extensions": ["colours_operators", "output_number"] }); } @@ -94,7 +87,7 @@ Blockly.Blocks['operator_multiply'] = { "name": "NUM2" } ], - "category": Blockly.Categories.operators, + "category": Categories.operators, "extensions": ["colours_operators", "output_number"] }); } @@ -118,7 +111,7 @@ Blockly.Blocks['operator_divide'] = { "name": "NUM2" } ], - "category": Blockly.Categories.operators, + "category": Categories.operators, "extensions": ["colours_operators", "output_number"] }); } @@ -142,7 +135,7 @@ Blockly.Blocks['operator_random'] = { "name": "TO" } ], - "category": Blockly.Categories.operators, + "category": Categories.operators, "extensions": ["colours_operators", "output_number"] }); } @@ -166,7 +159,7 @@ Blockly.Blocks['operator_lt'] = { "name": "OPERAND2" } ], - "category": Blockly.Categories.operators, + "category": Categories.operators, "extensions": ["colours_operators", "output_boolean"] }); } @@ -190,7 +183,7 @@ Blockly.Blocks['operator_equals'] = { "name": "OPERAND2" } ], - "category": Blockly.Categories.operators, + "category": Categories.operators, "extensions": ["colours_operators", "output_boolean"] }); } @@ -214,7 +207,7 @@ Blockly.Blocks['operator_gt'] = { "name": "OPERAND2" } ], - "category": Blockly.Categories.operators, + "category": Categories.operators, "extensions": ["colours_operators", "output_boolean"] }); } @@ -240,7 +233,7 @@ Blockly.Blocks['operator_and'] = { "check": "Boolean" } ], - "category": Blockly.Categories.operators, + "category": Categories.operators, "extensions": ["colours_operators", "output_boolean"] }); } @@ -266,7 +259,7 @@ Blockly.Blocks['operator_or'] = { "check": "Boolean" } ], - "category": Blockly.Categories.operators, + "category": Categories.operators, "extensions": ["colours_operators", "output_boolean"] }); } @@ -287,7 +280,7 @@ Blockly.Blocks['operator_not'] = { "check": "Boolean" } ], - "category": Blockly.Categories.operators, + "category": Categories.operators, "extensions": ["colours_operators", "output_boolean"] }); } @@ -311,7 +304,7 @@ Blockly.Blocks['operator_join'] = { "name": "STRING2" } ], - "category": Blockly.Categories.operators, + "category": Categories.operators, "extensions": ["colours_operators", "output_string"] }); } @@ -335,7 +328,7 @@ Blockly.Blocks['operator_letter_of'] = { "name": "STRING" } ], - "category": Blockly.Categories.operators, + "category": Categories.operators, "extensions": ["colours_operators", "output_string"] }); } @@ -355,7 +348,7 @@ Blockly.Blocks['operator_length'] = { "name": "STRING" } ], - "category": Blockly.Categories.operators, + "category": Categories.operators, "extensions": ["colours_operators", "output_string"] }); } @@ -379,7 +372,7 @@ Blockly.Blocks['operator_contains'] = { "name": "STRING2" } ], - "category": Blockly.Categories.operators, + "category": Categories.operators, "extensions": ["colours_operators", "output_boolean"] }); } @@ -403,7 +396,7 @@ Blockly.Blocks['operator_mod'] = { "name": "NUM2" } ], - "category": Blockly.Categories.operators, + "category": Categories.operators, "extensions": ["colours_operators", "output_number"] }); } @@ -423,7 +416,7 @@ Blockly.Blocks['operator_round'] = { "name": "NUM" } ], - "category": Blockly.Categories.operators, + "category": Categories.operators, "extensions": ["colours_operators", "output_number"] }); } @@ -463,7 +456,7 @@ Blockly.Blocks['operator_mathop'] = { "name": "NUM" } ], - "category": Blockly.Categories.operators, + "category": Categories.operators, "extensions": ["colours_operators", "output_number"] }); } diff --git a/blocks_vertical/vertical_extensions.js b/blocks_vertical/vertical_extensions.js index 16059da1ec..22cc6162ff 100644 --- a/blocks_vertical/vertical_extensions.js +++ b/blocks_vertical/vertical_extensions.js @@ -25,14 +25,10 @@ * would have the "colours_operators" and "output_number" extensions. * @author fenichel@google.com (Rachel Fenichel) */ -'use strict'; - -goog.provide('Blockly.ScratchBlocks.VerticalExtensions'); - -goog.require('Blockly.Colours'); -goog.require('Blockly.constants'); - +import * as Blockly from 'blockly/core'; +import {Colours} from '../core/colours.js'; +const VerticalExtensions = {}; /** * Helper function that generates an extension based on a category name. * The generated function will set primary, secondary, tertiary, and quaternary @@ -41,8 +37,8 @@ goog.require('Blockly.constants'); * @return {function} An extension function that sets colours based on the given * category. */ -Blockly.ScratchBlocks.VerticalExtensions.colourHelper = function(category) { - var colours = Blockly.Colours[category]; +VerticalExtensions.colourHelper = function(category) { + var colours = Colours[category]; if (!(colours && colours.primary && colours.secondary && colours.tertiary && colours.quaternary)) { throw new Error('Could not find colours for category "' + category + '"'); @@ -53,18 +49,18 @@ Blockly.ScratchBlocks.VerticalExtensions.colourHelper = function(category) { * @this {Blockly.Block} */ return function() { - this.setColourFromRawValues_(colours.primary, colours.secondary, - colours.tertiary, colours.quaternary); + // this.setColourFromRawValues_(colours.primary, colours.secondary, + // colours.tertiary, colours.quaternary); }; }; /** * Extension to set the colours of a text field, which are all the same. */ -Blockly.ScratchBlocks.VerticalExtensions.COLOUR_TEXTFIELD = function() { - this.setColourFromRawValues_(Blockly.Colours.textField, - Blockly.Colours.textField, Blockly.Colours.textField, - Blockly.Colours.textField); +VerticalExtensions.COLOUR_TEXTFIELD = function() { + // this.setColourFromRawValues_(Colours.textField, + // Colours.textField, Colours.textField, + // Colours.textField); }; /** @@ -74,7 +70,7 @@ Blockly.ScratchBlocks.VerticalExtensions.COLOUR_TEXTFIELD = function() { * @this {Blockly.Block} * @readonly */ -Blockly.ScratchBlocks.VerticalExtensions.SHAPE_STATEMENT = function() { +VerticalExtensions.SHAPE_STATEMENT = function() { this.setInputsInline(true); this.setPreviousStatement(true, null); this.setNextStatement(true, null); @@ -87,7 +83,7 @@ Blockly.ScratchBlocks.VerticalExtensions.SHAPE_STATEMENT = function() { * @this {Blockly.Block} * @readonly */ -Blockly.ScratchBlocks.VerticalExtensions.SHAPE_HAT = function() { +VerticalExtensions.SHAPE_HAT = function() { this.setInputsInline(true); this.setNextStatement(true, null); }; @@ -99,7 +95,7 @@ Blockly.ScratchBlocks.VerticalExtensions.SHAPE_HAT = function() { * @this {Blockly.Block} * @readonly */ -Blockly.ScratchBlocks.VerticalExtensions.SHAPE_END = function() { +VerticalExtensions.SHAPE_END = function() { this.setInputsInline(true); this.setPreviousStatement(true, null); }; @@ -111,7 +107,7 @@ Blockly.ScratchBlocks.VerticalExtensions.SHAPE_END = function() { * @this {Blockly.Block} * @readonly */ -Blockly.ScratchBlocks.VerticalExtensions.OUTPUT_NUMBER = function() { +VerticalExtensions.OUTPUT_NUMBER = function() { this.setInputsInline(true); this.setOutputShape(Blockly.OUTPUT_SHAPE_ROUND); this.setOutput(true, 'Number'); @@ -124,7 +120,7 @@ Blockly.ScratchBlocks.VerticalExtensions.OUTPUT_NUMBER = function() { * @this {Blockly.Block} * @readonly */ -Blockly.ScratchBlocks.VerticalExtensions.OUTPUT_STRING = function() { +VerticalExtensions.OUTPUT_STRING = function() { this.setInputsInline(true); this.setOutputShape(Blockly.OUTPUT_SHAPE_ROUND); this.setOutput(true, 'String'); @@ -137,7 +133,7 @@ Blockly.ScratchBlocks.VerticalExtensions.OUTPUT_STRING = function() { * @this {Blockly.Block} * @readonly */ -Blockly.ScratchBlocks.VerticalExtensions.OUTPUT_BOOLEAN = function() { +VerticalExtensions.OUTPUT_BOOLEAN = function() { this.setInputsInline(true); this.setOutputShape(Blockly.OUTPUT_SHAPE_HEXAGONAL); this.setOutput(true, 'Boolean'); @@ -151,7 +147,7 @@ Blockly.ScratchBlocks.VerticalExtensions.OUTPUT_BOOLEAN = function() { * @package * @readonly */ -Blockly.ScratchBlocks.VerticalExtensions.PROCEDURE_DEF_CONTEXTMENU = { +VerticalExtensions.PROCEDURE_DEF_CONTEXTMENU = { /** * Add the "edit" option and removes the "duplicate" option from the context * menu. @@ -201,7 +197,7 @@ Blockly.ScratchBlocks.VerticalExtensions.PROCEDURE_DEF_CONTEXTMENU = { * @package * @readonly */ -Blockly.ScratchBlocks.VerticalExtensions.PROCEDURE_CALL_CONTEXTMENU = { +VerticalExtensions.PROCEDURE_CALL_CONTEXTMENU = { /** * Add the "edit" option to the context menu. * @todo Add "go to definition" option once implemented. @@ -214,14 +210,14 @@ Blockly.ScratchBlocks.VerticalExtensions.PROCEDURE_CALL_CONTEXTMENU = { }; -Blockly.ScratchBlocks.VerticalExtensions.SCRATCH_EXTENSION = function() { +VerticalExtensions.SCRATCH_EXTENSION = function() { this.isScratchExtension = true; }; /** * Register all extensions for scratch-blocks. * @package */ -Blockly.ScratchBlocks.VerticalExtensions.registerAll = function() { +VerticalExtensions.registerAll = function() { var categoryNames = ['control', 'data', 'data_lists', 'sounds', 'motion', 'looks', 'event', 'sensing', 'pen', 'operators', 'more']; @@ -229,38 +225,38 @@ Blockly.ScratchBlocks.VerticalExtensions.registerAll = function() { for (var i = 0; i < categoryNames.length; i++) { var name = categoryNames[i]; Blockly.Extensions.register('colours_' + name, - Blockly.ScratchBlocks.VerticalExtensions.colourHelper(name)); + VerticalExtensions.colourHelper(name)); } // Text fields transcend categories. Blockly.Extensions.register('colours_textfield', - Blockly.ScratchBlocks.VerticalExtensions.COLOUR_TEXTFIELD); + VerticalExtensions.COLOUR_TEXTFIELD); // Register extensions for common block shapes. Blockly.Extensions.register('shape_statement', - Blockly.ScratchBlocks.VerticalExtensions.SHAPE_STATEMENT); + VerticalExtensions.SHAPE_STATEMENT); Blockly.Extensions.register('shape_hat', - Blockly.ScratchBlocks.VerticalExtensions.SHAPE_HAT); + VerticalExtensions.SHAPE_HAT); Blockly.Extensions.register('shape_end', - Blockly.ScratchBlocks.VerticalExtensions.SHAPE_END); + VerticalExtensions.SHAPE_END); // Output shapes and types are related. Blockly.Extensions.register('output_number', - Blockly.ScratchBlocks.VerticalExtensions.OUTPUT_NUMBER); + VerticalExtensions.OUTPUT_NUMBER); Blockly.Extensions.register('output_string', - Blockly.ScratchBlocks.VerticalExtensions.OUTPUT_STRING); + VerticalExtensions.OUTPUT_STRING); Blockly.Extensions.register('output_boolean', - Blockly.ScratchBlocks.VerticalExtensions.OUTPUT_BOOLEAN); + VerticalExtensions.OUTPUT_BOOLEAN); // Custom procedures have interesting context menus. Blockly.Extensions.registerMixin('procedure_def_contextmenu', - Blockly.ScratchBlocks.VerticalExtensions.PROCEDURE_DEF_CONTEXTMENU); + VerticalExtensions.PROCEDURE_DEF_CONTEXTMENU); Blockly.Extensions.registerMixin('procedure_call_contextmenu', - Blockly.ScratchBlocks.VerticalExtensions.PROCEDURE_CALL_CONTEXTMENU); + VerticalExtensions.PROCEDURE_CALL_CONTEXTMENU); // Extension blocks have slightly different block rendering. Blockly.Extensions.register('scratch_extension', - Blockly.ScratchBlocks.VerticalExtensions.SCRATCH_EXTENSION); + VerticalExtensions.SCRATCH_EXTENSION); }; -Blockly.ScratchBlocks.VerticalExtensions.registerAll(); +VerticalExtensions.registerAll(); diff --git a/src/categories.js b/src/categories.js new file mode 100644 index 0000000000..f691dbef7b --- /dev/null +++ b/src/categories.js @@ -0,0 +1,15 @@ +const Categories = { + "motion": "motion", + "looks": "looks", + "sound": "sounds", + "pen": "pen", + "data": "data", + "dataLists": "data-lists", + "event": "events", + "control": "control", + "sensing": "sensing", + "operators": "operators", + "more": "more" +}; + +export {Categories}; diff --git a/src/index.js b/src/index.js index 055ba88537..5b7ea64b59 100644 --- a/src/index.js +++ b/src/index.js @@ -4,6 +4,11 @@ * SPDX-License-Identifier: Apache-2.0 */ +import '../blocks_common/math.js'; +import '../blocks_vertical/vertical_extensions.js'; +import '../blocks_vertical/operators.js'; + export * from 'blockly'; +export * from './categories.js'; export * from '../core/colours.js'; export * from '../msg/scratch_msgs.js'; From 79398c2ebae7329d0d428bab5870e559423ab36b Mon Sep 17 00:00:00 2001 From: Aaron Dodson Date: Wed, 17 Apr 2024 14:01:57 -0700 Subject: [PATCH 008/130] fix: readd the motion blocks (#20) * fix: readd the motion blocks * fix: use the colours_motion extension instead of hardcoding colors --- blocks_vertical/motion.js | 78 +++++++++++++++------------------------ src/index.js | 1 + 2 files changed, 31 insertions(+), 48 deletions(-) diff --git a/blocks_vertical/motion.js b/blocks_vertical/motion.js index b4b5969231..5c9bf5f853 100644 --- a/blocks_vertical/motion.js +++ b/blocks_vertical/motion.js @@ -18,14 +18,8 @@ * limitations under the License. */ -'use strict'; - -goog.provide('Blockly.Blocks.motion'); - -goog.require('Blockly.Blocks'); -goog.require('Blockly.Colours'); -goog.require('Blockly.constants'); -goog.require('Blockly.ScratchBlocks.VerticalExtensions'); +import * as Blockly from 'blockly/core'; +import {Categories} from '../src/categories.js'; Blockly.Blocks['motion_movesteps'] = { @@ -42,7 +36,7 @@ Blockly.Blocks['motion_movesteps'] = { "name": "STEPS" } ], - "category": Blockly.Categories.motion, + "category": Categories.motion, "extensions": ["colours_motion", "shape_statement"] }); } @@ -59,7 +53,7 @@ Blockly.Blocks['motion_turnright'] = { "args0": [ { "type": "field_image", - "src": Blockly.mainWorkspace.options.pathToMedia + "rotate-right.svg", + "src": Blockly.getMainWorkspace().options.pathToMedia + "rotate-right.svg", "width": 24, "height": 24 }, @@ -68,7 +62,7 @@ Blockly.Blocks['motion_turnright'] = { "name": "DEGREES" } ], - "category": Blockly.Categories.motion, + "category": Categories.motion, "extensions": ["colours_motion", "shape_statement"] }); } @@ -85,7 +79,7 @@ Blockly.Blocks['motion_turnleft'] = { "args0": [ { "type": "field_image", - "src": Blockly.mainWorkspace.options.pathToMedia + "rotate-left.svg", + "src": Blockly.getMainWorkspace().options.pathToMedia + "rotate-left.svg", "width": 24, "height": 24 }, @@ -94,7 +88,7 @@ Blockly.Blocks['motion_turnleft'] = { "name": "DEGREES" } ], - "category": Blockly.Categories.motion, + "category": Categories.motion, "extensions": ["colours_motion", "shape_statement"] }); } @@ -114,7 +108,7 @@ Blockly.Blocks['motion_pointindirection'] = { "name": "DIRECTION" } ], - "category": Blockly.Categories.motion, + "category": Categories.motion, "extensions": ["colours_motion", "shape_statement"] }); } @@ -138,11 +132,7 @@ Blockly.Blocks['motion_pointtowards_menu'] = { ] } ], - "colour": Blockly.Colours.motion.secondary, - "colourSecondary": Blockly.Colours.motion.secondary, - "colourTertiary": Blockly.Colours.motion.tertiary, - "colourQuaternary": Blockly.Colours.motion.quaternary, - "extensions": ["output_string"] + "extensions": ["colours_motion", "output_string"] }); } }; @@ -161,7 +151,7 @@ Blockly.Blocks['motion_pointtowards'] = { "name": "TOWARDS" } ], - "category": Blockly.Categories.motion, + "category": Categories.motion, "extensions": ["colours_motion", "shape_statement"] }); } @@ -185,11 +175,7 @@ Blockly.Blocks['motion_goto_menu'] = { ] } ], - "colour": Blockly.Colours.motion.secondary, - "colourSecondary": Blockly.Colours.motion.secondary, - "colourTertiary": Blockly.Colours.motion.tertiary, - "colourQuaternary": Blockly.Colours.motion.quaternary, - "extensions": ["output_string"] + "extensions": ["colours_motion", "output_string"] }); } }; @@ -212,7 +198,7 @@ Blockly.Blocks['motion_gotoxy'] = { "name": "Y" } ], - "category": Blockly.Categories.motion, + "category": Categories.motion, "extensions": ["colours_motion", "shape_statement"] }); } @@ -232,7 +218,7 @@ Blockly.Blocks['motion_goto'] = { "name": "TO" } ], - "category": Blockly.Categories.motion, + "category": Categories.motion, "extensions": ["colours_motion", "shape_statement"] }); } @@ -260,7 +246,7 @@ Blockly.Blocks['motion_glidesecstoxy'] = { "name": "Y" } ], - "category": Blockly.Categories.motion, + "category": Categories.motion, "extensions": ["colours_motion", "shape_statement"] }); } @@ -284,11 +270,7 @@ Blockly.Blocks['motion_glideto_menu'] = { ] } ], - "colour": Blockly.Colours.motion.secondary, - "colourSecondary": Blockly.Colours.motion.secondary, - "colourTertiary": Blockly.Colours.motion.tertiary, - "colourQuaternary": Blockly.Colours.motion.quaternary, - "extensions": ["output_string"] + "extensions": ["colours_motion", "output_string"] }); } }; @@ -311,7 +293,7 @@ Blockly.Blocks['motion_glideto'] = { "name": "TO" } ], - "category": Blockly.Categories.motion, + "category": Categories.motion, "extensions": ["colours_motion", "shape_statement"] }); } @@ -331,7 +313,7 @@ Blockly.Blocks['motion_changexby'] = { "name": "DX" } ], - "category": Blockly.Categories.motion, + "category": Categories.motion, "extensions": ["colours_motion", "shape_statement"] }); } @@ -351,7 +333,7 @@ Blockly.Blocks['motion_setx'] = { "name": "X" } ], - "category": Blockly.Categories.motion, + "category": Categories.motion, "extensions": ["colours_motion", "shape_statement"] }); } @@ -371,7 +353,7 @@ Blockly.Blocks['motion_changeyby'] = { "name": "DY" } ], - "category": Blockly.Categories.motion, + "category": Categories.motion, "extensions": ["colours_motion", "shape_statement"] }); } @@ -391,7 +373,7 @@ Blockly.Blocks['motion_sety'] = { "name": "Y" } ], - "category": Blockly.Categories.motion, + "category": Categories.motion, "extensions": ["colours_motion", "shape_statement"] }); } @@ -405,7 +387,7 @@ Blockly.Blocks['motion_ifonedgebounce'] = { init: function() { this.jsonInit({ "message0": Blockly.Msg.MOTION_IFONEDGEBOUNCE, - "category": Blockly.Categories.motion, + "category": Categories.motion, "extensions": ["colours_motion", "shape_statement"] }); } @@ -430,7 +412,7 @@ Blockly.Blocks['motion_setrotationstyle'] = { ] } ], - "category": Blockly.Categories.motion, + "category": Categories.motion, "extensions": ["colours_motion", "shape_statement"] }); } @@ -444,7 +426,7 @@ Blockly.Blocks['motion_xposition'] = { init: function() { this.jsonInit({ "message0": Blockly.Msg.MOTION_XPOSITION, - "category": Blockly.Categories.motion, + "category": Categories.motion, "checkboxInFlyout": true, "extensions": ["colours_motion", "output_number"] }); @@ -459,7 +441,7 @@ Blockly.Blocks['motion_yposition'] = { init: function() { this.jsonInit({ "message0": Blockly.Msg.MOTION_YPOSITION, - "category": Blockly.Categories.motion, + "category": Categories.motion, "checkboxInFlyout": true, "extensions": ["colours_motion", "output_number"] }); @@ -474,7 +456,7 @@ Blockly.Blocks['motion_direction'] = { init: function() { this.jsonInit({ "message0": Blockly.Msg.MOTION_DIRECTION, - "category": Blockly.Categories.motion, + "category": Categories.motion, "checkboxInFlyout": true, "extensions": ["colours_motion", "output_number"] }); @@ -497,7 +479,7 @@ Blockly.Blocks['motion_scroll_right'] = { "name": "DISTANCE" } ], - "category": Blockly.Categories.motion, + "category": Categories.motion, "extensions": ["colours_motion", "shape_statement"] }); } @@ -519,7 +501,7 @@ Blockly.Blocks['motion_scroll_up'] = { "name": "DISTANCE" } ], - "category": Blockly.Categories.motion, + "category": Categories.motion, "extensions": ["colours_motion", "shape_statement"] }); } @@ -548,7 +530,7 @@ Blockly.Blocks['motion_align_scene'] = { ] } ], - "category": Blockly.Categories.motion, + "category": Categories.motion, "extensions": ["colours_motion", "shape_statement"] }); } @@ -564,7 +546,7 @@ Blockly.Blocks['motion_xscroll'] = { init: function() { this.jsonInit({ "message0": Blockly.Msg.MOTION_XSCROLL, - "category": Blockly.Categories.motion, + "category": Categories.motion, "extensions": ["colours_motion", "output_number"] }); } @@ -580,7 +562,7 @@ Blockly.Blocks['motion_yscroll'] = { init: function() { this.jsonInit({ "message0": Blockly.Msg.MOTION_YSCROLL, - "category": Blockly.Categories.motion, + "category": Categories.motion, "extensions": ["colours_motion", "output_number"] }); } diff --git a/src/index.js b/src/index.js index 5b7ea64b59..04f74482f3 100644 --- a/src/index.js +++ b/src/index.js @@ -6,6 +6,7 @@ import '../blocks_common/math.js'; import '../blocks_vertical/vertical_extensions.js'; +import '../blocks_vertical/motion.js'; import '../blocks_vertical/operators.js'; export * from 'blockly'; From 4de530f00310ee27c0ad55940c9cb6bf1208df91 Mon Sep 17 00:00:00 2001 From: Aaron Dodson Date: Wed, 17 Apr 2024 14:33:30 -0700 Subject: [PATCH 009/130] fix: readd the event blocks (#21) * fix: readd the event blocks * fix: only import core Blockly --- blocks_vertical/event.js | 45 +++++++++++++++++----------------------- src/constants.js | 9 ++++++++ src/index.js | 1 + 3 files changed, 29 insertions(+), 26 deletions(-) create mode 100644 src/constants.js diff --git a/blocks_vertical/event.js b/blocks_vertical/event.js index 5694893cf3..ca9529717f 100644 --- a/blocks_vertical/event.js +++ b/blocks_vertical/event.js @@ -18,14 +18,9 @@ * limitations under the License. */ -'use strict'; - -goog.provide('Blockly.Blocks.event'); - -goog.require('Blockly.Blocks'); -goog.require('Blockly.Colours'); -goog.require('Blockly.constants'); -goog.require('Blockly.ScratchBlocks.VerticalExtensions'); +import * as Blockly from 'blockly/core'; +import {Categories} from '../src/categories.js'; +import * as Constants from '../src/constants.js'; Blockly.Blocks['event_whentouchingobject'] = { /** @@ -41,7 +36,7 @@ Blockly.Blocks['event_whentouchingobject'] = { "name": "TOUCHINGOBJECTMENU" } ], - "category": Blockly.Categories.event, + "category": Categories.event, "extensions": ["colours_event", "shape_hat"] }); } @@ -82,13 +77,13 @@ Blockly.Blocks['event_whenflagclicked'] = { "args0": [ { "type": "field_image", - "src": Blockly.mainWorkspace.options.pathToMedia + "green-flag.svg", + "src": Blockly.getMainWorkspace().options.pathToMedia + "green-flag.svg", "width": 24, "height": 24, "alt": "flag" } ], - "category": Blockly.Categories.event, + "category": Categories.event, "extensions": ["colours_event", "shape_hat"] }); } @@ -102,7 +97,7 @@ Blockly.Blocks['event_whenthisspriteclicked'] = { init: function() { this.jsonInit({ "message0": Blockly.Msg.EVENT_WHENTHISSPRITECLICKED, - "category": Blockly.Categories.event, + "category": Categories.event, "extensions": ["colours_event", "shape_hat"] }); } @@ -117,7 +112,7 @@ Blockly.Blocks['event_whenstageclicked'] = { init: function() { this.jsonInit({ "message0": Blockly.Msg.EVENT_WHENSTAGECLICKED, - "category": Blockly.Categories.event, + "category": Categories.event, "extensions": ["colours_event", "shape_hat"] }); } @@ -136,11 +131,12 @@ Blockly.Blocks['event_whenbroadcastreceived'] = { { "type": "field_variable", "name": "BROADCAST_OPTION", - "variableTypes": [Blockly.BROADCAST_MESSAGE_VARIABLE_TYPE], + "variableTypes": [Constants.BROADCAST_MESSAGE_VARIABLE_TYPE], + "defaultType": Constants.BROADCAST_MESSAGE_VARIABLE_TYPE, "variable": Blockly.Msg.DEFAULT_BROADCAST_MESSAGE_NAME } ], - "category": Blockly.Categories.event, + "category": Categories.event, "extensions": ["colours_event", "shape_hat"] }); } @@ -163,7 +159,7 @@ Blockly.Blocks['event_whenbackdropswitchesto'] = { ] } ], - "category": Blockly.Categories.event, + "category": Categories.event, "extensions": ["colours_event", "shape_hat"] }); } @@ -191,7 +187,7 @@ Blockly.Blocks['event_whengreaterthan'] = { "name": "VALUE" } ], - "category": Blockly.Categories.event, + "category": Categories.event, "extensions": ["colours_event", "shape_hat"] }); } @@ -209,15 +205,12 @@ Blockly.Blocks['event_broadcast_menu'] = { { "type": "field_variable", "name": "BROADCAST_OPTION", - "variableTypes":[Blockly.BROADCAST_MESSAGE_VARIABLE_TYPE], + "variableTypes": [Constants.BROADCAST_MESSAGE_VARIABLE_TYPE], + "defaultType": Constants.BROADCAST_MESSAGE_VARIABLE_TYPE, "variable": Blockly.Msg.DEFAULT_BROADCAST_MESSAGE_NAME } ], - "colour": Blockly.Colours.event.secondary, - "colourSecondary": Blockly.Colours.event.secondary, - "colourTertiary": Blockly.Colours.event.tertiary, - "colourQuaternary": Blockly.Colours.event.quaternary, - "extensions": ["output_string"] + "extensions": ["colours_event", "output_string"] }); } }; @@ -237,7 +230,7 @@ Blockly.Blocks['event_broadcast'] = { "name": "BROADCAST_INPUT" } ], - "category": Blockly.Categories.event, + "category": Categories.event, "extensions": ["colours_event", "shape_statement"] }); } @@ -257,7 +250,7 @@ Blockly.Blocks['event_broadcastandwait'] = { "name":"BROADCAST_INPUT" } ], - "category": Blockly.Categories.event, + "category": Categories.event, "extensions": ["colours_event", "shape_statement"] }); } @@ -322,7 +315,7 @@ Blockly.Blocks['event_whenkeypressed'] = { ] } ], - "category": Blockly.Categories.event, + "category": Categories.event, "extensions": ["colours_event", "shape_hat"] }); } diff --git a/src/constants.js b/src/constants.js new file mode 100644 index 0000000000..aad139c40f --- /dev/null +++ b/src/constants.js @@ -0,0 +1,9 @@ +/** + * String representing the variable type of broadcast message blocks. + * This string, for use in differentiating between types of variables, + * indicates that the current variable is a broadcast message. + * @const {string} + */ +const BROADCAST_MESSAGE_VARIABLE_TYPE = 'broadcast_msg'; + +export {BROADCAST_MESSAGE_VARIABLE_TYPE}; diff --git a/src/index.js b/src/index.js index 04f74482f3..06cdb4c9bf 100644 --- a/src/index.js +++ b/src/index.js @@ -6,6 +6,7 @@ import '../blocks_common/math.js'; import '../blocks_vertical/vertical_extensions.js'; +import '../blocks_vertical/event.js'; import '../blocks_vertical/motion.js'; import '../blocks_vertical/operators.js'; From f69d4ac8ebd128b318919f4a3ac5222d211adfbb Mon Sep 17 00:00:00 2001 From: Aaron Dodson Date: Wed, 17 Apr 2024 14:48:31 -0700 Subject: [PATCH 010/130] fix: readd the control blocks (#22) --- blocks_vertical/control.js | 60 +++++++++++++++++--------------------- src/index.js | 1 + 2 files changed, 28 insertions(+), 33 deletions(-) diff --git a/blocks_vertical/control.js b/blocks_vertical/control.js index 3418745882..67d59f6add 100644 --- a/blocks_vertical/control.js +++ b/blocks_vertical/control.js @@ -18,14 +18,9 @@ * limitations under the License. */ -'use strict'; - -goog.provide('Blockly.Blocks.control'); - -goog.require('Blockly.Blocks'); -goog.require('Blockly.Colours'); -goog.require('Blockly.ScratchBlocks.VerticalExtensions'); - +import * as Blockly from 'blockly/core'; +import {Categories} from '../src/categories.js'; +import {Colours} from '../core/colours.js'; Blockly.Blocks['control_forever'] = { /** @@ -49,14 +44,14 @@ Blockly.Blocks['control_forever'] = { "args2": [ { "type": "field_image", - "src": Blockly.mainWorkspace.options.pathToMedia + "repeat.svg", + "src": Blockly.getMainWorkspace().options.pathToMedia + "repeat.svg", "width": 24, "height": 24, "alt": "*", "flip_rtl": true } ], - "category": Blockly.Categories.control, + "category": Categories.control, "extensions": ["colours_control", "shape_end"] }); } @@ -90,14 +85,14 @@ Blockly.Blocks['control_repeat'] = { "args2": [ { "type": "field_image", - "src": Blockly.mainWorkspace.options.pathToMedia + "repeat.svg", + "src": Blockly.getMainWorkspace().options.pathToMedia + "repeat.svg", "width": 24, "height": 24, "alt": "*", "flip_rtl": true } ], - "category": Blockly.Categories.control, + "category": Categories.control, "extensions": ["colours_control", "shape_statement"] }); } @@ -126,7 +121,7 @@ Blockly.Blocks['control_if'] = { "name": "SUBSTACK" } ], - "category": Blockly.Categories.control, + "category": Categories.control, "extensions": ["colours_control", "shape_statement"] }); } @@ -163,7 +158,7 @@ Blockly.Blocks['control_if_else'] = { "name": "SUBSTACK2" } ], - "category": Blockly.Categories.control, + "category": Categories.control, "extensions": ["colours_control", "shape_statement"] }); } @@ -206,11 +201,10 @@ Blockly.Blocks['control_stop'] = { this.appendDummyInput() .appendField(Blockly.Msg.CONTROL_STOP) .appendField(stopDropdown, 'STOP_OPTION'); - this.setCategory(Blockly.Categories.control); - this.setColour(Blockly.Colours.control.primary, - Blockly.Colours.control.secondary, - Blockly.Colours.control.tertiary, - Blockly.Colours.control.quaternary + this.setColour(Colours.control.primary, + Colours.control.secondary, + Colours.control.tertiary, + Colours.control.quaternary ); this.setPreviousStatement(true); }, @@ -240,7 +234,7 @@ Blockly.Blocks['control_wait'] = { "name": "DURATION" } ], - "category": Blockly.Categories.control, + "category": Categories.control, "extensions": ["colours_control", "shape_statement"] }); } @@ -261,7 +255,7 @@ Blockly.Blocks['control_wait_until'] = { "check": "Boolean" } ], - "category": Blockly.Categories.control, + "category": Categories.control, "extensions": ["colours_control", "shape_statement"] }); } @@ -294,14 +288,14 @@ Blockly.Blocks['control_repeat_until'] = { "args2": [ { "type": "field_image", - "src": Blockly.mainWorkspace.options.pathToMedia + "repeat.svg", + "src": Blockly.getMainWorkspace().options.pathToMedia + "repeat.svg", "width": 24, "height": 24, "alt": "*", "flip_rtl": true } ], - "category": Blockly.Categories.control, + "category": Categories.control, "extensions": ["colours_control", "shape_statement"] }); } @@ -334,14 +328,14 @@ Blockly.Blocks['control_while'] = { "args2": [ { "type": "field_image", - "src": Blockly.mainWorkspace.options.pathToMedia + "repeat.svg", + "src": Blockly.getMainWorkspace().options.pathToMedia + "repeat.svg", "width": 24, "height": 24, "alt": "*", "flip_rtl": true } ], - "category": Blockly.Categories.control, + "category": Categories.control, "extensions": ["colours_control", "shape_statement"] }); } @@ -374,7 +368,7 @@ Blockly.Blocks['control_for_each'] = { "name": "SUBSTACK" } ], - "category": Blockly.Categories.control, + "category": Categories.control, "extensions": ["colours_control", "shape_statement"] }); } @@ -391,7 +385,7 @@ Blockly.Blocks['control_start_as_clone'] = { "message0": Blockly.Msg.CONTROL_STARTASCLONE, "args0": [ ], - "category": Blockly.Categories.control, + "category": Categories.control, "extensions": ["colours_control", "shape_hat"] }); } @@ -434,7 +428,7 @@ Blockly.Blocks['control_create_clone_of'] = { "name": "CLONE_OPTION" } ], - "category": Blockly.Categories.control, + "category": Categories.control, "extensions": ["colours_control", "shape_statement"] }); } @@ -450,7 +444,7 @@ Blockly.Blocks['control_delete_this_clone'] = { "message0": Blockly.Msg.CONTROL_DELETETHISCLONE, "args0": [ ], - "category": Blockly.Categories.control, + "category": Categories.control, "extensions": ["colours_control", "shape_end"] }); } @@ -465,7 +459,7 @@ Blockly.Blocks['control_get_counter'] = { init: function() { this.jsonInit({ "message0": Blockly.Msg.CONTROL_COUNTER, - "category": Blockly.Categories.control, + "category": Categories.control, "extensions": ["colours_control", "output_number"] }); } @@ -480,7 +474,7 @@ Blockly.Blocks['control_incr_counter'] = { init: function() { this.jsonInit({ "message0": Blockly.Msg.CONTROL_INCRCOUNTER, - "category": Blockly.Categories.control, + "category": Categories.control, "extensions": ["colours_control", "shape_statement"] }); } @@ -495,7 +489,7 @@ Blockly.Blocks['control_clear_counter'] = { init: function() { this.jsonInit({ "message0": Blockly.Msg.CONTROL_CLEARCOUNTER, - "category": Blockly.Categories.control, + "category": Categories.control, "extensions": ["colours_control", "shape_statement"] }); } @@ -525,7 +519,7 @@ Blockly.Blocks['control_all_at_once'] = { "name": "SUBSTACK" } ], - "category": Blockly.Categories.control, + "category": Categories.control, "extensions": ["colours_control", "shape_statement"] }); } diff --git a/src/index.js b/src/index.js index 06cdb4c9bf..1a47656305 100644 --- a/src/index.js +++ b/src/index.js @@ -6,6 +6,7 @@ import '../blocks_common/math.js'; import '../blocks_vertical/vertical_extensions.js'; +import '../blocks_vertical/control.js'; import '../blocks_vertical/event.js'; import '../blocks_vertical/motion.js'; import '../blocks_vertical/operators.js'; From 34f07c0ed7982963ded8563b5f45d374e740d98c Mon Sep 17 00:00:00 2001 From: Aaron Dodson Date: Wed, 17 Apr 2024 15:02:58 -0700 Subject: [PATCH 011/130] fix: readd the looks blocks (#23) --- blocks_vertical/looks.js | 71 ++++++++++++++++------------------------ src/index.js | 1 + 2 files changed, 29 insertions(+), 43 deletions(-) diff --git a/blocks_vertical/looks.js b/blocks_vertical/looks.js index 66482f0ef3..d0f0a12b90 100644 --- a/blocks_vertical/looks.js +++ b/blocks_vertical/looks.js @@ -18,15 +18,8 @@ * limitations under the License. */ -'use strict'; - -goog.provide('Blockly.Blocks.looks'); - -goog.require('Blockly.Blocks'); -goog.require('Blockly.Colours'); -goog.require('Blockly.constants'); -goog.require('Blockly.ScratchBlocks.VerticalExtensions'); - +import * as Blockly from 'blockly/core'; +import {Categories} from '../src/categories.js'; Blockly.Blocks['looks_sayforsecs'] = { /** @@ -46,7 +39,7 @@ Blockly.Blocks['looks_sayforsecs'] = { "name": "SECS" } ], - "category": Blockly.Categories.looks, + "category": Categories.looks, "extensions": ["colours_looks", "shape_statement"] }); } @@ -66,7 +59,7 @@ Blockly.Blocks['looks_say'] = { "name": "MESSAGE" } ], - "category": Blockly.Categories.looks, + "category": Categories.looks, "extensions": ["colours_looks", "shape_statement"] }); } @@ -90,7 +83,7 @@ Blockly.Blocks['looks_thinkforsecs'] = { "name": "SECS" } ], - "category": Blockly.Categories.looks, + "category": Categories.looks, "extensions": ["colours_looks", "shape_statement"] }); } @@ -110,7 +103,7 @@ Blockly.Blocks['looks_think'] = { "name": "MESSAGE" } ], - "category": Blockly.Categories.looks, + "category": Categories.looks, "extensions": ["colours_looks", "shape_statement"] }); } @@ -124,7 +117,7 @@ Blockly.Blocks['looks_show'] = { init: function() { this.jsonInit({ "message0": Blockly.Msg.LOOKS_SHOW, - "category": Blockly.Categories.looks, + "category": Categories.looks, "extensions": ["colours_looks", "shape_statement"] }); } @@ -138,7 +131,7 @@ Blockly.Blocks['looks_hide'] = { init: function() { this.jsonInit({ "message0": Blockly.Msg.LOOKS_HIDE, - "category": Blockly.Categories.looks, + "category": Categories.looks, "extensions": ["colours_looks", "shape_statement"] }); } @@ -154,7 +147,7 @@ Blockly.Blocks['looks_hideallsprites'] = { init: function() { this.jsonInit({ "message0": Blockly.Msg.LOOKS_HIDEALLSPRITES, - "category": Blockly.Categories.looks, + "category": Categories.looks, "extensions": ["colours_looks", "shape_statement"] }); } @@ -187,7 +180,7 @@ Blockly.Blocks['looks_changeeffectby'] = { "name": "CHANGE" } ], - "category": Blockly.Categories.looks, + "category": Categories.looks, "extensions": ["colours_looks", "shape_statement"] }); } @@ -220,7 +213,7 @@ Blockly.Blocks['looks_seteffectto'] = { "name": "VALUE" } ], - "category": Blockly.Categories.looks, + "category": Categories.looks, "extensions": ["colours_looks", "shape_statement"] }); } @@ -234,7 +227,7 @@ Blockly.Blocks['looks_cleargraphiceffects'] = { init: function() { this.jsonInit({ "message0": Blockly.Msg.LOOKS_CLEARGRAPHICEFFECTS, - "category": Blockly.Categories.looks, + "category": Categories.looks, "extensions": ["colours_looks", "shape_statement"] }); } @@ -254,7 +247,7 @@ Blockly.Blocks['looks_changesizeby'] = { "name": "CHANGE" } ], - "category": Blockly.Categories.looks, + "category": Categories.looks, "extensions": ["colours_looks", "shape_statement"] }); } @@ -274,7 +267,7 @@ Blockly.Blocks['looks_setsizeto'] = { "name": "SIZE" } ], - "category": Blockly.Categories.looks, + "category": Categories.looks, "extensions": ["colours_looks", "shape_statement"] }); } @@ -288,7 +281,7 @@ Blockly.Blocks['looks_size'] = { init: function() { this.jsonInit({ "message0": Blockly.Msg.LOOKS_SIZE, - "category": Blockly.Categories.looks, + "category": Categories.looks, "checkboxInFlyout": true, "extensions": ["colours_looks", "output_number"] }); @@ -318,7 +311,7 @@ Blockly.Blocks['looks_changestretchby'] = { "name": "CHANGE" } ], - "category": Blockly.Categories.looks, + "category": Categories.looks, "extensions": ["colours_looks", "shape_statement"] }); } @@ -340,7 +333,7 @@ Blockly.Blocks['looks_setstretchto'] = { "name": "STRETCH" } ], - "category": Blockly.Categories.looks, + "category": Categories.looks, "extensions": ["colours_looks", "shape_statement"] }); } @@ -364,11 +357,7 @@ Blockly.Blocks['looks_costume'] = { ] } ], - "colour": Blockly.Colours.looks.secondary, - "colourSecondary": Blockly.Colours.looks.secondary, - "colourTertiary": Blockly.Colours.looks.tertiary, - "colourQuaternary": Blockly.Colours.looks.quaternary, - "extensions": ["output_string"] + "extensions": ["colours_looks", "output_string"] }); } }; @@ -387,7 +376,7 @@ Blockly.Blocks['looks_switchcostumeto'] = { "name": "COSTUME" } ], - "category": Blockly.Categories.looks, + "category": Categories.looks, "extensions": ["colours_looks", "shape_statement"] }); } @@ -401,7 +390,7 @@ Blockly.Blocks['looks_nextcostume'] = { init: function() { this.jsonInit({ "message0": Blockly.Msg.LOOKS_NEXTCOSTUME, - "category": Blockly.Categories.looks, + "category": Categories.looks, "extensions": ["colours_looks", "shape_statement"] }); } @@ -421,7 +410,7 @@ Blockly.Blocks['looks_switchbackdropto'] = { "name": "BACKDROP" } ], - "category": Blockly.Categories.looks, + "category": Categories.looks, "extensions": ["colours_looks", "shape_statement"] }); } @@ -445,11 +434,7 @@ Blockly.Blocks['looks_backdrops'] = { ] } ], - "colour": Blockly.Colours.looks.secondary, - "colourSecondary": Blockly.Colours.looks.secondary, - "colourTertiary": Blockly.Colours.looks.tertiary, - "colourQuaternary": Blockly.Colours.looks.quaternary, - "extensions": ["output_string"] + "extensions": ["colours_looks", "output_string"] }); } }; @@ -472,7 +457,7 @@ Blockly.Blocks['looks_gotofrontback'] = { ] } ], - "category": Blockly.Categories.looks, + "category": Categories.looks, "extensions": ["colours_looks", "shape_statement"] }); } @@ -500,7 +485,7 @@ Blockly.Blocks['looks_goforwardbackwardlayers'] = { "name": "NUM" } ], - "category": Blockly.Categories.looks, + "category": Categories.looks, "extensions": ["colours_looks", "shape_statement"] }); } @@ -524,7 +509,7 @@ Blockly.Blocks['looks_backdropnumbername'] = { ] } ], - "category": Blockly.Categories.looks, + "category": Categories.looks, "checkboxInFlyout": true, "extensions": ["colours_looks", "output_number"] }); @@ -549,7 +534,7 @@ Blockly.Blocks['looks_costumenumbername'] = { ] } ], - "category": Blockly.Categories.looks, + "category": Categories.looks, "checkboxInFlyout": true, "extensions": ["colours_looks", "output_number"] }); @@ -570,7 +555,7 @@ Blockly.Blocks['looks_switchbackdroptoandwait'] = { "name": "BACKDROP" } ], - "category": Blockly.Categories.looks, + "category": Categories.looks, "extensions": ["colours_looks", "shape_statement"] }); } @@ -584,7 +569,7 @@ Blockly.Blocks['looks_nextbackdrop'] = { init: function() { this.jsonInit({ "message0": Blockly.Msg.LOOKS_NEXTBACKDROP_BLOCK, - "category": Blockly.Categories.looks, + "category": Categories.looks, "extensions": ["colours_looks", "shape_statement"] }); } diff --git a/src/index.js b/src/index.js index 1a47656305..22fd9f0a64 100644 --- a/src/index.js +++ b/src/index.js @@ -8,6 +8,7 @@ import '../blocks_common/math.js'; import '../blocks_vertical/vertical_extensions.js'; import '../blocks_vertical/control.js'; import '../blocks_vertical/event.js'; +import '../blocks_vertical/looks.js'; import '../blocks_vertical/motion.js'; import '../blocks_vertical/operators.js'; From 6837513d3f217e94522a3ce756273d6ff8e7538c Mon Sep 17 00:00:00 2001 From: Aaron Dodson Date: Wed, 17 Apr 2024 15:54:48 -0700 Subject: [PATCH 012/130] fix: readd the sound blocks (#24) * fix: readd the sound blocks * chore: remove vestigial sound_sounds_menu implementation --- blocks_vertical/sound.js | 61 ++++++++-------------------------------- src/index.js | 1 + 2 files changed, 13 insertions(+), 49 deletions(-) diff --git a/blocks_vertical/sound.js b/blocks_vertical/sound.js index 03c33630ba..fb39ed2eea 100644 --- a/blocks_vertical/sound.js +++ b/blocks_vertical/sound.js @@ -18,51 +18,14 @@ * limitations under the License. */ -'use strict'; - -goog.provide('Blockly.Blocks.sound'); - -goog.require('Blockly.Blocks'); -goog.require('Blockly.Colours'); -goog.require('Blockly.constants'); -goog.require('Blockly.ScratchBlocks.VerticalExtensions'); +import * as Blockly from 'blockly/core'; +import {Categories} from '../src/categories.js'; Blockly.Blocks['sound_sounds_menu'] = { /** - * Sound effects drop-down menu. + * Sound effects drop-down menu. Populated dynamically by scratch-gui. * @this Blockly.Block */ - init: function() { - this.jsonInit({ - "message0": "%1", - "args0": [ - { - "type": "field_dropdown", - "name": "SOUND_MENU", - "options": [ - ['1', '0'], - ['2', '1'], - ['3', '2'], - ['4', '3'], - ['5', '4'], - ['6', '5'], - ['7', '6'], - ['8', '7'], - ['9', '8'], - ['10', '9'], - ['call a function', function() { - window.alert('function called!');} - ] - ] - } - ], - "colour": Blockly.Colours.sounds.secondary, - "colourSecondary": Blockly.Colours.sounds.secondary, - "colourTertiary": Blockly.Colours.sounds.tertiary, - "colourQuaternary": Blockly.Colours.sounds.quaternary, - "extensions": ["output_string"] - }); - } }; Blockly.Blocks['sound_play'] = { @@ -79,7 +42,7 @@ Blockly.Blocks['sound_play'] = { "name": "SOUND_MENU" } ], - "category": Blockly.Categories.sound, + "category": Categories.sound, "extensions": ["colours_sounds", "shape_statement"] }); } @@ -99,7 +62,7 @@ Blockly.Blocks['sound_playuntildone'] = { "name": "SOUND_MENU" } ], - "category": Blockly.Categories.sound, + "category": Categories.sound, "extensions": ["colours_sounds", "shape_statement"] }); } @@ -113,7 +76,7 @@ Blockly.Blocks['sound_stopallsounds'] = { init: function() { this.jsonInit({ "message0": Blockly.Msg.SOUND_STOPALLSOUNDS, - "category": Blockly.Categories.sound, + "category": Categories.sound, "extensions": ["colours_sounds", "shape_statement"] }); } @@ -141,7 +104,7 @@ Blockly.Blocks['sound_seteffectto'] = { "name": "VALUE" } ], - "category": Blockly.Categories.sound, + "category": Categories.sound, "extensions": ["colours_sounds", "shape_statement"] }); } @@ -170,7 +133,7 @@ Blockly.Blocks['sound_changeeffectby'] = { "name": "VALUE" } ], - "category": Blockly.Categories.sound, + "category": Categories.sound, "extensions": ["colours_sounds", "shape_statement"] }); } @@ -184,7 +147,7 @@ Blockly.Blocks['sound_cleareffects'] = { init: function() { this.jsonInit({ "message0": Blockly.Msg.SOUND_CLEAREFFECTS, - "category": Blockly.Categories.sound, + "category": Categories.sound, "extensions": ["colours_sounds", "shape_statement"] }); } @@ -204,7 +167,7 @@ Blockly.Blocks['sound_changevolumeby'] = { "name": "VOLUME" } ], - "category": Blockly.Categories.sound, + "category": Categories.sound, "extensions": ["colours_sounds", "shape_statement"] }); } @@ -224,7 +187,7 @@ Blockly.Blocks['sound_setvolumeto'] = { "name": "VOLUME" } ], - "category": Blockly.Categories.sound, + "category": Categories.sound, "extensions": ["colours_sounds", "shape_statement"] }); } @@ -238,7 +201,7 @@ Blockly.Blocks['sound_volume'] = { init: function() { this.jsonInit({ "message0": Blockly.Msg.SOUND_VOLUME, - "category": Blockly.Categories.sound, + "category": Categories.sound, "checkboxInFlyout": true, "extensions": ["colours_sounds", "output_number"] }); diff --git a/src/index.js b/src/index.js index 22fd9f0a64..ab673fd4d0 100644 --- a/src/index.js +++ b/src/index.js @@ -11,6 +11,7 @@ import '../blocks_vertical/event.js'; import '../blocks_vertical/looks.js'; import '../blocks_vertical/motion.js'; import '../blocks_vertical/operators.js'; +import '../blocks_vertical/sound.js'; export * from 'blockly'; export * from './categories.js'; From 685ecfc0ce9f3c9335393f5af71eb3755aabedd4 Mon Sep 17 00:00:00 2001 From: Aaron Dodson Date: Thu, 18 Apr 2024 12:53:59 -0700 Subject: [PATCH 013/130] fix: re-export scratch-blocks utility functions (#26) --- core/scratch_blocks_utils.js | 28 ++++++++++------------------ src/index.js | 2 ++ 2 files changed, 12 insertions(+), 18 deletions(-) diff --git a/core/scratch_blocks_utils.js b/core/scratch_blocks_utils.js index 99f492b427..4780bf2126 100644 --- a/core/scratch_blocks_utils.js +++ b/core/scratch_blocks_utils.js @@ -22,14 +22,7 @@ * @fileoverview Utility methods for Scratch Blocks but not Blockly. * @author fenichel@google.com (Rachel Fenichel) */ -'use strict'; - -/** - * @name Blockly.scratchBlocksUtils - * @namespace - **/ -goog.provide('Blockly.scratchBlocksUtils'); - +import * as Blockly from 'blockly/core'; /** * Measure some text using a canvas in-memory. @@ -41,7 +34,7 @@ goog.provide('Blockly.scratchBlocksUtils'); * @return {number} Width of the text in px. * @package */ -Blockly.scratchBlocksUtils.measureText = function(fontSize, fontFamily, +export function measureText(fontSize, fontFamily, fontWeight, text) { var canvas = document.createElement('canvas'); var context = canvas.getContext('2d'); @@ -57,7 +50,7 @@ Blockly.scratchBlocksUtils.measureText = function(fontSize, fontFamily, * @return {string} String with HTML entities encoded. * @package */ -Blockly.scratchBlocksUtils.encodeEntities = function(rawStr) { +export function encodeEntities(rawStr) { // CC-BY-SA https://stackoverflow.com/questions/18749591/encode-html-entities-in-javascript return rawStr.replace(/[\u00A0-\u9999<>&]/gim, function(i) { return '&#' + i.charCodeAt(0) + ';'; @@ -70,7 +63,7 @@ Blockly.scratchBlocksUtils.encodeEntities = function(rawStr) { * @param {Blockly.Block} block the root block to be processed. * @package */ -Blockly.scratchBlocksUtils.changeObscuredShadowIds = function(block) { +export function changeObscuredShadowIds(block) { var blocks = block.getDescendants(false); for (var i = blocks.length - 1; i >= 0; i--) { var descendant = blocks[i]; @@ -97,7 +90,7 @@ Blockly.scratchBlocksUtils.changeObscuredShadowIds = function(block) { * @return {boolean} True if the block should be duplicated on drag. * @package */ -Blockly.scratchBlocksUtils.isShadowArgumentReporter = function(block) { +export function isShadowArgumentReporter(block) { return (block.isShadow() && (block.type == 'argument_reporter_boolean' || block.type == 'argument_reporter_string_number')); }; @@ -108,7 +101,7 @@ Blockly.scratchBlocksUtils.isShadowArgumentReporter = function(block) { * @param {string} str2 Second input. * @return {number} -1, 0, or 1 to signify greater than, equality, or less than. */ -Blockly.scratchBlocksUtils.compareStrings = function(str1, str2) { +export function compareStrings(str1, str2) { return str1.localeCompare(str2, [], { sensitivity: 'base', numeric: true @@ -122,7 +115,7 @@ Blockly.scratchBlocksUtils.compareStrings = function(str1, str2) { * @return {boolean} True if the block can be recycled. * @package */ -Blockly.scratchBlocksUtils.blockIsRecyclable = function(block) { +export function blockIsRecyclable(block) { // If the block needs to parse mutations, never recycle. if (block.mutationToDom && block.domToMutation) { return false; @@ -148,7 +141,7 @@ Blockly.scratchBlocksUtils.blockIsRecyclable = function(block) { // Check children. if (input.connection) { var child = input.connection.targetBlock(); - if (child && !Blockly.scratchBlocksUtils.blockIsRecyclable(child)) { + if (child && !blockIsRecyclable(child)) { return false; } } @@ -156,7 +149,6 @@ Blockly.scratchBlocksUtils.blockIsRecyclable = function(block) { return true; }; - /** * Creates a callback function for a click on the "duplicate" context menu * option in Scratch Blocks. The block is duplicated and attached to the mouse, @@ -168,7 +160,7 @@ Blockly.scratchBlocksUtils.blockIsRecyclable = function(block) { * drag. * @package */ -Blockly.scratchBlocksUtils.duplicateAndDragCallback = function(oldBlock, event) { +export function duplicateAndDragCallback(oldBlock, event) { var isMouseEvent = Blockly.Touch.getTouchIdentifierFromEvent(event) === 'mouse'; return function(e) { // Give the context menu a chance to close. @@ -195,7 +187,7 @@ Blockly.scratchBlocksUtils.duplicateAndDragCallback = function(oldBlock, event) var newBlock = Blockly.Xml.domToBlock(xml, ws); // Scratch-specific: Give shadow dom new IDs to prevent duplicating on paste - Blockly.scratchBlocksUtils.changeObscuredShadowIds(newBlock); + changeObscuredShadowIds(newBlock); var svgRootNew = newBlock.getSvgRoot(); if (!svgRootNew) { diff --git a/src/index.js b/src/index.js index ab673fd4d0..34e5bca92a 100644 --- a/src/index.js +++ b/src/index.js @@ -12,8 +12,10 @@ import '../blocks_vertical/looks.js'; import '../blocks_vertical/motion.js'; import '../blocks_vertical/operators.js'; import '../blocks_vertical/sound.js'; +import * as scratchBlocksUtils from '../core/scratch_blocks_utils.js'; export * from 'blockly'; export * from './categories.js'; export * from '../core/colours.js'; export * from '../msg/scratch_msgs.js'; +export {scratchBlocksUtils}; From 9f5f1351be5818fb9392214b8047acace8333a65 Mon Sep 17 00:00:00 2001 From: Aaron Dodson Date: Thu, 18 Apr 2024 14:09:59 -0700 Subject: [PATCH 014/130] fix: readd the sensing blocks (#27) --- blocks_vertical/sensing.js | 53 +++++++++++++++++--------------------- src/index.js | 1 + 2 files changed, 24 insertions(+), 30 deletions(-) diff --git a/blocks_vertical/sensing.js b/blocks_vertical/sensing.js index cd75de8d12..0fb53ef43f 100644 --- a/blocks_vertical/sensing.js +++ b/blocks_vertical/sensing.js @@ -18,15 +18,8 @@ * limitations under the License. */ -'use strict'; - -goog.provide('Blockly.Blocks.sensing'); - -goog.require('Blockly.Blocks'); -goog.require('Blockly.Colours'); -goog.require('Blockly.constants'); -goog.require('Blockly.ScratchBlocks.VerticalExtensions'); - +import * as Blockly from 'blockly/core'; +import {Categories} from '../src/categories.js'; Blockly.Blocks['sensing_touchingobject'] = { /** @@ -42,7 +35,7 @@ Blockly.Blocks['sensing_touchingobject'] = { "name": "TOUCHINGOBJECTMENU" } ], - "category": Blockly.Categories.sensing, + "category": Categories.sensing, "extensions": ["colours_sensing", "output_boolean"] }); } @@ -85,7 +78,7 @@ Blockly.Blocks['sensing_touchingcolor'] = { "name": "COLOR" } ], - "category": Blockly.Categories.sensing, + "category": Categories.sensing, "extensions": ["colours_sensing", "output_boolean"] }); } @@ -109,7 +102,7 @@ Blockly.Blocks['sensing_coloristouchingcolor'] = { "name": "COLOR2" } ], - "category": Blockly.Categories.sensing, + "category": Categories.sensing, "extensions": ["colours_sensing", "output_boolean"] }); } @@ -129,7 +122,7 @@ Blockly.Blocks['sensing_distanceto'] = { "name": "DISTANCETOMENU" } ], - "category": Blockly.Categories.sensing, + "category": Categories.sensing, "extensions": ["colours_sensing", "output_number"] }); } @@ -171,7 +164,7 @@ Blockly.Blocks['sensing_askandwait'] = { "name": "QUESTION" } ], - "category": Blockly.Categories.sensing, + "category": Categories.sensing, "extensions": ["colours_sensing", "shape_statement"] }); } @@ -185,7 +178,7 @@ Blockly.Blocks['sensing_answer'] = { init: function() { this.jsonInit({ "message0": Blockly.Msg.SENSING_ANSWER, - "category": Blockly.Categories.sensing, + "category": Categories.sensing, "checkboxInFlyout": true, "extensions": ["colours_sensing", "output_number"] }); @@ -206,7 +199,7 @@ Blockly.Blocks['sensing_keypressed'] = { "name": "KEY_OPTION" } ], - "category": Blockly.Categories.sensing, + "category": Categories.sensing, "extensions": ["colours_sensing", "output_boolean"] }); } @@ -283,7 +276,7 @@ Blockly.Blocks['sensing_mousedown'] = { init: function() { this.jsonInit({ "message0": Blockly.Msg.SENSING_MOUSEDOWN, - "category": Blockly.Categories.sensing, + "category": Categories.sensing, "extensions": ["colours_sensing", "output_boolean"] }); } @@ -297,7 +290,7 @@ Blockly.Blocks['sensing_mousex'] = { init: function() { this.jsonInit({ "message0": Blockly.Msg.SENSING_MOUSEX, - "category": Blockly.Categories.sensing, + "category": Categories.sensing, "extensions": ["colours_sensing", "output_number"] }); } @@ -311,7 +304,7 @@ Blockly.Blocks['sensing_mousey'] = { init: function() { this.jsonInit({ "message0": Blockly.Msg.SENSING_MOUSEY, - "category": Blockly.Categories.sensing, + "category": Categories.sensing, "extensions": ["colours_sensing", "output_number"] }); } @@ -335,7 +328,7 @@ Blockly.Blocks['sensing_setdragmode'] = { ] } ], - "category": Blockly.Categories.sensing, + "category": Categories.sensing, "extensions": ["colours_sensing", "shape_statement"] }); } @@ -349,7 +342,7 @@ Blockly.Blocks['sensing_loudness'] = { init: function() { this.jsonInit({ "message0": Blockly.Msg.SENSING_LOUDNESS, - "category": Blockly.Categories.sensing, + "category": Categories.sensing, "checkboxInFlyout": true, "extensions": ["colours_sensing", "output_number"] }); @@ -366,7 +359,7 @@ Blockly.Blocks['sensing_loud'] = { init: function() { this.jsonInit({ "message0": Blockly.Msg.SENSING_LOUD, - "category": Blockly.Categories.sensing, + "category": Categories.sensing, "extensions": ["colours_sensing", "output_boolean"] }); } @@ -380,7 +373,7 @@ Blockly.Blocks['sensing_timer'] = { init: function() { this.jsonInit({ "message0": Blockly.Msg.SENSING_TIMER, - "category": Blockly.Categories.sensing, + "category": Categories.sensing, "checkboxInFlyout": true, "extensions": ["colours_sensing", "output_number"] }); @@ -395,7 +388,7 @@ Blockly.Blocks['sensing_resettimer'] = { init: function() { this.jsonInit({ "message0": Blockly.Msg.SENSING_RESETTIMER, - "category": Blockly.Categories.sensing, + "category": Categories.sensing, "extensions": ["colours_sensing", "shape_statement"] }); } @@ -419,7 +412,7 @@ Blockly.Blocks['sensing_of_object_menu'] = { ] } ], - "category": Blockly.Categories.sensing, + "category": Categories.sensing, "extensions": ["colours_sensing", "output_string"] }); } @@ -456,7 +449,7 @@ Blockly.Blocks['sensing_of'] = { } ], "output": true, - "category": Blockly.Categories.sensing, + "category": Categories.sensing, "outputShape": Blockly.OUTPUT_SHAPE_ROUND, "extensions": ["colours_sensing"] }); @@ -486,7 +479,7 @@ Blockly.Blocks['sensing_current'] = { ] } ], - "category": Blockly.Categories.sensing, + "category": Categories.sensing, "checkboxInFlyout": true, "extensions": ["colours_sensing", "output_number"] }); @@ -501,7 +494,7 @@ Blockly.Blocks['sensing_dayssince2000'] = { init: function() { this.jsonInit({ "message0": Blockly.Msg.SENSING_DAYSSINCE2000, - "category": Blockly.Categories.sensing, + "category": Categories.sensing, "extensions": ["colours_sensing", "output_number"] }); } @@ -515,7 +508,7 @@ Blockly.Blocks['sensing_username'] = { init: function() { this.jsonInit({ "message0": Blockly.Msg.SENSING_USERNAME, - "category": Blockly.Categories.sensing, + "category": Categories.sensing, "checkboxInFlyout": true, "extensions": ["colours_sensing", "output_number"] }); @@ -532,7 +525,7 @@ Blockly.Blocks['sensing_userid'] = { init: function() { this.jsonInit({ "message0": Blockly.Msg.SENSING_USERID, - "category": Blockly.Categories.sensing, + "category": Categories.sensing, "extensions": ["colours_sensing", "output_number"] }); } diff --git a/src/index.js b/src/index.js index 34e5bca92a..bb80f98a03 100644 --- a/src/index.js +++ b/src/index.js @@ -11,6 +11,7 @@ import '../blocks_vertical/event.js'; import '../blocks_vertical/looks.js'; import '../blocks_vertical/motion.js'; import '../blocks_vertical/operators.js'; +import '../blocks_vertical/sensing.js'; import '../blocks_vertical/sound.js'; import * as scratchBlocksUtils from '../core/scratch_blocks_utils.js'; From fafed65e73f59877200741c36244d082f2b3aad1 Mon Sep 17 00:00:00 2001 From: Aaron Dodson Date: Fri, 19 Apr 2024 09:07:04 -0700 Subject: [PATCH 015/130] fix: readd the data blocks (#29) * fix: readd the data blocks * fix: import constants correctly --- blocks_vertical/data.js | 105 +++++++++++++++++++--------------------- src/constants.js | 11 ++++- src/index.js | 1 + 3 files changed, 61 insertions(+), 56 deletions(-) diff --git a/blocks_vertical/data.js b/blocks_vertical/data.js index 726697d47d..e8754c305a 100644 --- a/blocks_vertical/data.js +++ b/blocks_vertical/data.js @@ -18,15 +18,10 @@ * limitations under the License. */ -'use strict'; - -goog.provide('Blockly.Blocks.data'); -goog.provide('Blockly.Constants.Data'); - -goog.require('Blockly.Blocks'); -goog.require('Blockly.Colours'); -goog.require('Blockly.constants'); -goog.require('Blockly.ScratchBlocks.VerticalExtensions'); +import * as Blockly from 'blockly/core'; +import {Categories} from '../src/categories.js'; +import * as Constants from '../src/constants.js'; +import * as scratchBlocksUtils from '../core/scratch_blocks_utils.js'; Blockly.Blocks['data_variable'] = { @@ -46,7 +41,7 @@ Blockly.Blocks['data_variable'] = { "variableType": "" } ], - "category": Blockly.Categories.data, + "category": Categories.data, "checkboxInFlyout": true, "extensions": ["contextMenu_getVariableBlock", "colours_data", "output_string"] }); @@ -71,7 +66,7 @@ Blockly.Blocks['data_setvariableto'] = { "name": "VALUE" } ], - "category": Blockly.Categories.data, + "category": Categories.data, "extensions": ["colours_data", "shape_statement"] }); } @@ -95,7 +90,7 @@ Blockly.Blocks['data_changevariableby'] = { "name": "VALUE" } ], - "category": Blockly.Categories.data, + "category": Categories.data, "extensions": ["colours_data", "shape_statement"] }); } @@ -117,7 +112,7 @@ Blockly.Blocks['data_showvariable'] = { ], "previousStatement": null, "nextStatement": null, - "category": Blockly.Categories.data, + "category": Categories.data, "extensions": ["colours_data"] }); } @@ -139,7 +134,7 @@ Blockly.Blocks['data_hidevariable'] = { ], "previousStatement": null, "nextStatement": null, - "category": Blockly.Categories.data, + "category": Categories.data, "extensions": ["colours_data"] }); } @@ -158,10 +153,10 @@ Blockly.Blocks['data_listcontents'] = { "type": "field_variable_getter", "text": "", "name": "LIST", - "variableType": Blockly.LIST_VARIABLE_TYPE + "variableType": Constants.LIST_VARIABLE_TYPE } ], - "category": Blockly.Categories.dataLists, + "category": Categories.dataLists, "extensions": ["contextMenu_getListBlock", "colours_data_lists", "output_string"], "checkboxInFlyout": true }); @@ -190,7 +185,7 @@ Blockly.Blocks['data_listindexall'] = { ] } ], - "category": Blockly.Categories.data, + "category": Categories.data, "extensions": ["colours_textfield", "output_string"] }); } @@ -218,7 +213,7 @@ Blockly.Blocks['data_listindexrandom'] = { ] } ], - "category": Blockly.Categories.data, + "category": Categories.data, "extensions": ["colours_textfield", "output_string"] }); } @@ -240,10 +235,10 @@ Blockly.Blocks['data_addtolist'] = { { "type": "field_variable", "name": "LIST", - "variableTypes": [Blockly.LIST_VARIABLE_TYPE] + "variableTypes": [Constants.LIST_VARIABLE_TYPE] } ], - "category": Blockly.Categories.dataLists, + "category": Categories.dataLists, "extensions": ["colours_data_lists", "shape_statement"] }); } @@ -265,10 +260,10 @@ Blockly.Blocks['data_deleteoflist'] = { { "type": "field_variable", "name": "LIST", - "variableTypes": [Blockly.LIST_VARIABLE_TYPE] + "variableTypes": [Constants.LIST_VARIABLE_TYPE] } ], - "category": Blockly.Categories.dataLists, + "category": Categories.dataLists, "extensions": ["colours_data_lists", "shape_statement"] }); } @@ -286,10 +281,10 @@ Blockly.Blocks['data_deletealloflist'] = { { "type": "field_variable", "name": "LIST", - "variableTypes": [Blockly.LIST_VARIABLE_TYPE] + "variableTypes": [Constants.LIST_VARIABLE_TYPE] } ], - "category": Blockly.Categories.dataLists, + "category": Categories.dataLists, "extensions": ["colours_data_lists", "shape_statement"] }); } @@ -315,10 +310,10 @@ Blockly.Blocks['data_insertatlist'] = { { "type": "field_variable", "name": "LIST", - "variableTypes": [Blockly.LIST_VARIABLE_TYPE] + "variableTypes": [Constants.LIST_VARIABLE_TYPE] } ], - "category": Blockly.Categories.dataLists, + "category": Categories.dataLists, "extensions": ["colours_data_lists", "shape_statement"] }); } @@ -340,14 +335,14 @@ Blockly.Blocks['data_replaceitemoflist'] = { { "type": "field_variable", "name": "LIST", - "variableTypes": [Blockly.LIST_VARIABLE_TYPE] + "variableTypes": [Constants.LIST_VARIABLE_TYPE] }, { "type": "input_value", "name": "ITEM" } ], - "category": Blockly.Categories.dataLists, + "category": Categories.dataLists, "extensions": ["colours_data_lists", "shape_statement"] }); } @@ -369,11 +364,11 @@ Blockly.Blocks['data_itemoflist'] = { { "type": "field_variable", "name": "LIST", - "variableTypes": [Blockly.LIST_VARIABLE_TYPE] + "variableTypes": [Constants.LIST_VARIABLE_TYPE] } ], "output": null, - "category": Blockly.Categories.dataLists, + "category": Categories.dataLists, "extensions": ["colours_data_lists"], "outputShape": Blockly.OUTPUT_SHAPE_ROUND }); @@ -396,11 +391,11 @@ Blockly.Blocks['data_itemnumoflist'] = { { "type": "field_variable", "name": "LIST", - "variableTypes": [Blockly.LIST_VARIABLE_TYPE] + "variableTypes": [Constants.LIST_VARIABLE_TYPE] } ], "output": null, - "category": Blockly.Categories.dataLists, + "category": Categories.dataLists, "extensions": ["colours_data_lists"], "outputShape": Blockly.OUTPUT_SHAPE_ROUND }); @@ -419,10 +414,10 @@ Blockly.Blocks['data_lengthoflist'] = { { "type": "field_variable", "name": "LIST", - "variableTypes": [Blockly.LIST_VARIABLE_TYPE] + "variableTypes": [Constants.LIST_VARIABLE_TYPE] } ], - "category": Blockly.Categories.dataLists, + "category": Categories.dataLists, "extensions": ["colours_data_lists", "output_number"] }); } @@ -440,14 +435,14 @@ Blockly.Blocks['data_listcontainsitem'] = { { "type": "field_variable", "name": "LIST", - "variableTypes": [Blockly.LIST_VARIABLE_TYPE] + "variableTypes": [Constants.LIST_VARIABLE_TYPE] }, { "type": "input_value", "name": "ITEM" } ], - "category": Blockly.Categories.dataLists, + "category": Categories.dataLists, "extensions": ["colours_data_lists", "output_boolean"] }); } @@ -465,10 +460,10 @@ Blockly.Blocks['data_showlist'] = { { "type": "field_variable", "name": "LIST", - "variableTypes": [Blockly.LIST_VARIABLE_TYPE] + "variableTypes": [Constants.LIST_VARIABLE_TYPE] } ], - "category": Blockly.Categories.dataLists, + "category": Categories.dataLists, "extensions": ["colours_data_lists", "shape_statement"] }); } @@ -486,10 +481,10 @@ Blockly.Blocks['data_hidelist'] = { { "type": "field_variable", "name": "LIST", - "variableTypes": [Blockly.LIST_VARIABLE_TYPE] + "variableTypes": [Constants.LIST_VARIABLE_TYPE] } ], - "category": Blockly.Categories.dataLists, + "category": Categories.dataLists, "extensions": ["colours_data_lists", "shape_statement"] }); } @@ -503,7 +498,7 @@ Blockly.Blocks['data_hidelist'] = { * @package * @readonly */ -Blockly.Constants.Data.CUSTOM_CONTEXT_MENU_GET_VARIABLE_MIXIN = { +const CUSTOM_CONTEXT_MENU_GET_VARIABLE_MIXIN = { /** * Add context menu option to change the selected variable. * @param {!Array} options List of menu options to add to. @@ -518,7 +513,7 @@ Blockly.Constants.Data.CUSTOM_CONTEXT_MENU_GET_VARIABLE_MIXIN = { if (!this.isInFlyout) { var variablesList = this.workspace.getVariablesOfType(''); variablesList.sort(function(a, b) { - return Blockly.scratchBlocksUtils.compareStrings(a.name, b.name); + return scratchBlocksUtils.compareStrings(a.name, b.name); }); for (var i = 0; i < variablesList.length; i++) { var varName = variablesList[i].name; @@ -528,7 +523,7 @@ Blockly.Constants.Data.CUSTOM_CONTEXT_MENU_GET_VARIABLE_MIXIN = { option.text = varName; option.callback = - Blockly.Constants.Data.VARIABLE_OPTION_CALLBACK_FACTORY(this, + VARIABLE_OPTION_CALLBACK_FACTORY(this, variablesList[i].getId(), fieldName); options.push(option); } @@ -536,13 +531,13 @@ Blockly.Constants.Data.CUSTOM_CONTEXT_MENU_GET_VARIABLE_MIXIN = { var renameOption = { text: Blockly.Msg.RENAME_VARIABLE, enabled: true, - callback: Blockly.Constants.Data.RENAME_OPTION_CALLBACK_FACTORY(this, + callback: RENAME_OPTION_CALLBACK_FACTORY(this, fieldName) }; var deleteOption = { text: Blockly.Msg.DELETE_VARIABLE.replace('%1', currentVarName), enabled: true, - callback: Blockly.Constants.Data.DELETE_OPTION_CALLBACK_FACTORY(this, + callback: DELETE_OPTION_CALLBACK_FACTORY(this, fieldName) }; options.push(renameOption); @@ -552,7 +547,7 @@ Blockly.Constants.Data.CUSTOM_CONTEXT_MENU_GET_VARIABLE_MIXIN = { }; Blockly.Extensions.registerMixin('contextMenu_getVariableBlock', - Blockly.Constants.Data.CUSTOM_CONTEXT_MENU_GET_VARIABLE_MIXIN); + CUSTOM_CONTEXT_MENU_GET_VARIABLE_MIXIN); /** * Mixin to add a context menu for a data_listcontents block. It adds one item for @@ -562,7 +557,7 @@ Blockly.Extensions.registerMixin('contextMenu_getVariableBlock', * @package * @readonly */ -Blockly.Constants.Data.CUSTOM_CONTEXT_MENU_GET_LIST_MIXIN = { +const CUSTOM_CONTEXT_MENU_GET_LIST_MIXIN = { /** * Add context menu option to change the selected list. * @param {!Array} options List of menu options to add to. @@ -577,7 +572,7 @@ Blockly.Constants.Data.CUSTOM_CONTEXT_MENU_GET_LIST_MIXIN = { if (!this.isInFlyout) { var variablesList = this.workspace.getVariablesOfType('list'); variablesList.sort(function(a, b) { - return Blockly.scratchBlocksUtils.compareStrings(a.name, b.name); + return scratchBlocksUtils.compareStrings(a.name, b.name); }); for (var i = 0; i < variablesList.length; i++) { var varName = variablesList[i].name; @@ -587,7 +582,7 @@ Blockly.Constants.Data.CUSTOM_CONTEXT_MENU_GET_LIST_MIXIN = { option.text = varName; option.callback = - Blockly.Constants.Data.VARIABLE_OPTION_CALLBACK_FACTORY(this, + VARIABLE_OPTION_CALLBACK_FACTORY(this, variablesList[i].getId(), fieldName); options.push(option); } @@ -595,13 +590,13 @@ Blockly.Constants.Data.CUSTOM_CONTEXT_MENU_GET_LIST_MIXIN = { var renameOption = { text: Blockly.Msg.RENAME_LIST, enabled: true, - callback: Blockly.Constants.Data.RENAME_OPTION_CALLBACK_FACTORY(this, + callback: RENAME_OPTION_CALLBACK_FACTORY(this, fieldName) }; var deleteOption = { text: Blockly.Msg.DELETE_LIST.replace('%1', currentVarName), enabled: true, - callback: Blockly.Constants.Data.DELETE_OPTION_CALLBACK_FACTORY(this, + callback: DELETE_OPTION_CALLBACK_FACTORY(this, fieldName) }; options.push(renameOption); @@ -610,7 +605,7 @@ Blockly.Constants.Data.CUSTOM_CONTEXT_MENU_GET_LIST_MIXIN = { } }; Blockly.Extensions.registerMixin('contextMenu_getListBlock', - Blockly.Constants.Data.CUSTOM_CONTEXT_MENU_GET_LIST_MIXIN); + CUSTOM_CONTEXT_MENU_GET_LIST_MIXIN); /** * Callback factory for dropdown menu options associated with a variable getter @@ -622,7 +617,7 @@ Blockly.Extensions.registerMixin('contextMenu_getListBlock', * @param {string} fieldName The name of the field to update on the block. * @return {!function()} A function that updates the block with the new name. */ -Blockly.Constants.Data.VARIABLE_OPTION_CALLBACK_FACTORY = function(block, +const VARIABLE_OPTION_CALLBACK_FACTORY = function(block, id, fieldName) { return function() { var variableField = block.getField(fieldName); @@ -640,7 +635,7 @@ Blockly.Constants.Data.VARIABLE_OPTION_CALLBACK_FACTORY = function(block, * @param {string} fieldName The name of the field to inspect on the block. * @return {!function()} A function that renames the variable. */ -Blockly.Constants.Data.RENAME_OPTION_CALLBACK_FACTORY = function(block, +const RENAME_OPTION_CALLBACK_FACTORY = function(block, fieldName) { return function() { var workspace = block.workspace; @@ -656,7 +651,7 @@ Blockly.Constants.Data.RENAME_OPTION_CALLBACK_FACTORY = function(block, * @param {string} fieldName The name of the field to inspect on the block. * @return {!function()} A function that deletes the variable. */ -Blockly.Constants.Data.DELETE_OPTION_CALLBACK_FACTORY = function(block, +const DELETE_OPTION_CALLBACK_FACTORY = function(block, fieldName) { return function() { var workspace = block.workspace; diff --git a/src/constants.js b/src/constants.js index aad139c40f..0d6f6e3a44 100644 --- a/src/constants.js +++ b/src/constants.js @@ -5,5 +5,14 @@ * @const {string} */ const BROADCAST_MESSAGE_VARIABLE_TYPE = 'broadcast_msg'; - export {BROADCAST_MESSAGE_VARIABLE_TYPE}; + + +/** + * String representing the variable type of list blocks. + * This string, for use in differentiating between types of variables, + * indicates that the current variable is a list. + * @const {string} + */ +const LIST_VARIABLE_TYPE = 'list'; +export {LIST_VARIABLE_TYPE}; diff --git a/src/index.js b/src/index.js index bb80f98a03..c3d352081c 100644 --- a/src/index.js +++ b/src/index.js @@ -7,6 +7,7 @@ import '../blocks_common/math.js'; import '../blocks_vertical/vertical_extensions.js'; import '../blocks_vertical/control.js'; +import '../blocks_vertical/data.js'; import '../blocks_vertical/event.js'; import '../blocks_vertical/looks.js'; import '../blocks_vertical/motion.js'; From 920febf5c3304bcf3a561b1e7c0e016540399540 Mon Sep 17 00:00:00 2001 From: Aaron Dodson Date: Fri, 19 Apr 2024 14:01:59 -0700 Subject: [PATCH 016/130] fix: make block images work in all contexts (#30) --- blocks_vertical/control.js | 12 ++++++++---- blocks_vertical/event.js | 3 ++- blocks_vertical/motion.js | 6 ++++-- blocks_vertical/vertical_extensions.js | 2 ++ 4 files changed, 16 insertions(+), 7 deletions(-) diff --git a/blocks_vertical/control.js b/blocks_vertical/control.js index 67d59f6add..d9de23414a 100644 --- a/blocks_vertical/control.js +++ b/blocks_vertical/control.js @@ -29,6 +29,7 @@ Blockly.Blocks['control_forever'] = { * @this Blockly.Block */ init: function() { + const ws = this.workspace.options.parentWorkspace || this.workspace; this.jsonInit({ "id": "control_forever", "message0": Blockly.Msg.CONTROL_FOREVER, @@ -44,7 +45,7 @@ Blockly.Blocks['control_forever'] = { "args2": [ { "type": "field_image", - "src": Blockly.getMainWorkspace().options.pathToMedia + "repeat.svg", + "src": ws.options.pathToMedia + "repeat.svg", "width": 24, "height": 24, "alt": "*", @@ -64,6 +65,7 @@ Blockly.Blocks['control_repeat'] = { * @this Blockly.Block */ init: function() { + const ws = this.workspace.options.parentWorkspace || this.workspace; this.jsonInit({ "id": "control_repeat", "message0": Blockly.Msg.CONTROL_REPEAT, @@ -85,7 +87,7 @@ Blockly.Blocks['control_repeat'] = { "args2": [ { "type": "field_image", - "src": Blockly.getMainWorkspace().options.pathToMedia + "repeat.svg", + "src": ws.options.pathToMedia + "repeat.svg", "width": 24, "height": 24, "alt": "*", @@ -267,6 +269,7 @@ Blockly.Blocks['control_repeat_until'] = { * @this Blockly.Block */ init: function() { + const ws = this.workspace.options.parentWorkspace || this.workspace; this.jsonInit({ "message0": Blockly.Msg.CONTROL_REPEATUNTIL, "message1": "%1", @@ -288,7 +291,7 @@ Blockly.Blocks['control_repeat_until'] = { "args2": [ { "type": "field_image", - "src": Blockly.getMainWorkspace().options.pathToMedia + "repeat.svg", + "src": ws.options.pathToMedia + "repeat.svg", "width": 24, "height": 24, "alt": "*", @@ -307,6 +310,7 @@ Blockly.Blocks['control_while'] = { * (This is an obsolete "hacked" block, for compatibility with 2.0.) */ init: function() { + const ws = this.workspace.options.parentWorkspace || this.workspace; this.jsonInit({ "message0": Blockly.Msg.CONTROL_WHILE, "message1": "%1", @@ -328,7 +332,7 @@ Blockly.Blocks['control_while'] = { "args2": [ { "type": "field_image", - "src": Blockly.getMainWorkspace().options.pathToMedia + "repeat.svg", + "src": ws.options.pathToMedia + "repeat.svg", "width": 24, "height": 24, "alt": "*", diff --git a/blocks_vertical/event.js b/blocks_vertical/event.js index ca9529717f..2bbc788ff3 100644 --- a/blocks_vertical/event.js +++ b/blocks_vertical/event.js @@ -71,13 +71,14 @@ Blockly.Blocks['event_whenflagclicked'] = { * @this Blockly.Block */ init: function() { + const ws = this.workspace.options.parentWorkspace || this.workspace; this.jsonInit({ "id": "event_whenflagclicked", "message0": Blockly.Msg.EVENT_WHENFLAGCLICKED, "args0": [ { "type": "field_image", - "src": Blockly.getMainWorkspace().options.pathToMedia + "green-flag.svg", + "src": ws.options.pathToMedia + "green-flag.svg", "width": 24, "height": 24, "alt": "flag" diff --git a/blocks_vertical/motion.js b/blocks_vertical/motion.js index 5c9bf5f853..156a941945 100644 --- a/blocks_vertical/motion.js +++ b/blocks_vertical/motion.js @@ -48,12 +48,13 @@ Blockly.Blocks['motion_turnright'] = { * @this Blockly.Block */ init: function() { + const ws = this.workspace.options.parentWorkspace || this.workspace; this.jsonInit({ "message0": Blockly.Msg.MOTION_TURNRIGHT, "args0": [ { "type": "field_image", - "src": Blockly.getMainWorkspace().options.pathToMedia + "rotate-right.svg", + "src": ws.options.pathToMedia + "rotate-right.svg", "width": 24, "height": 24 }, @@ -74,12 +75,13 @@ Blockly.Blocks['motion_turnleft'] = { * @this Blockly.Block */ init: function() { + const ws = this.workspace.options.parentWorkspace || this.workspace; this.jsonInit({ "message0": Blockly.Msg.MOTION_TURNLEFT, "args0": [ { "type": "field_image", - "src": Blockly.getMainWorkspace().options.pathToMedia + "rotate-left.svg", + "src": ws.options.pathToMedia + "rotate-left.svg", "width": 24, "height": 24 }, diff --git a/blocks_vertical/vertical_extensions.js b/blocks_vertical/vertical_extensions.js index 22cc6162ff..9eb7504a66 100644 --- a/blocks_vertical/vertical_extensions.js +++ b/blocks_vertical/vertical_extensions.js @@ -49,6 +49,7 @@ VerticalExtensions.colourHelper = function(category) { * @this {Blockly.Block} */ return function() { + this.setColour(colours.primary); // this.setColourFromRawValues_(colours.primary, colours.secondary, // colours.tertiary, colours.quaternary); }; @@ -58,6 +59,7 @@ VerticalExtensions.colourHelper = function(category) { * Extension to set the colours of a text field, which are all the same. */ VerticalExtensions.COLOUR_TEXTFIELD = function() { + this.setColour(colours.textField); // this.setColourFromRawValues_(Colours.textField, // Colours.textField, Colours.textField, // Colours.textField); From ea68b1c25f055288e2ee39f846c17e5861f1a01f Mon Sep 17 00:00:00 2001 From: Aaron Dodson Date: Fri, 19 Apr 2024 14:39:33 -0700 Subject: [PATCH 017/130] fix: load the continuous toolbox (#31) --- package-lock.json | 18 ++++++++++++++++++ package.json | 1 + src/index.js | 18 ++++++++++++++++++ 3 files changed, 37 insertions(+) diff --git a/package-lock.json b/package-lock.json index 77c16a6cd8..d3bd004fe9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,6 +9,7 @@ "version": "2.0.0", "license": "Apache-2.0", "dependencies": { + "@blockly/continuous-toolbox": "^5.0.15", "blockly": "^10.0.0" }, "devDependencies": { @@ -120,6 +121,17 @@ "node": ">=4" } }, + "node_modules/@blockly/continuous-toolbox": { + "version": "5.0.15", + "resolved": "https://registry.npmjs.org/@blockly/continuous-toolbox/-/continuous-toolbox-5.0.15.tgz", + "integrity": "sha512-XXW+ETvPljsq9A5KdXO/aKnVbEIy+ANlgfQmPN9Vztl4U0NdQ3QvA/PtZRlZ6ISJdEkM4GnhTXOIIO+0qDqJ8w==", + "engines": { + "node": ">=8.17.0" + }, + "peerDependencies": { + "blockly": "^10.0.0" + } + }, "node_modules/@commitlint/cli": { "version": "17.8.1", "resolved": "https://registry.npmjs.org/@commitlint/cli/-/cli-17.8.1.tgz", @@ -7098,6 +7110,12 @@ } } }, + "@blockly/continuous-toolbox": { + "version": "5.0.15", + "resolved": "https://registry.npmjs.org/@blockly/continuous-toolbox/-/continuous-toolbox-5.0.15.tgz", + "integrity": "sha512-XXW+ETvPljsq9A5KdXO/aKnVbEIy+ANlgfQmPN9Vztl4U0NdQ3QvA/PtZRlZ6ISJdEkM4GnhTXOIIO+0qDqJ8w==", + "requires": {} + }, "@commitlint/cli": { "version": "17.8.1", "resolved": "https://registry.npmjs.org/@commitlint/cli/-/cli-17.8.1.tgz", diff --git a/package.json b/package.json index 1f02c6681d..ab6450e05f 100644 --- a/package.json +++ b/package.json @@ -27,6 +27,7 @@ "webpack-dev-server": "^4.11.1" }, "dependencies": { + "@blockly/continuous-toolbox": "^5.0.15", "blockly": "^10.0.0" } } diff --git a/src/index.js b/src/index.js index c3d352081c..bd0320177a 100644 --- a/src/index.js +++ b/src/index.js @@ -4,6 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ +import * as Blockly from 'blockly/core'; import '../blocks_common/math.js'; import '../blocks_vertical/vertical_extensions.js'; import '../blocks_vertical/control.js'; @@ -15,9 +16,26 @@ import '../blocks_vertical/operators.js'; import '../blocks_vertical/sensing.js'; import '../blocks_vertical/sound.js'; import * as scratchBlocksUtils from '../core/scratch_blocks_utils.js'; +import { + ContinuousToolbox, + ContinuousFlyout, + ContinuousMetrics, +} from '@blockly/continuous-toolbox'; export * from 'blockly'; export * from './categories.js'; export * from '../core/colours.js'; export * from '../msg/scratch_msgs.js'; export {scratchBlocksUtils}; + +export function inject(container, options) { + Object.assign(options, { + plugins: { + toolbox: ContinuousToolbox, + flyoutsVerticalToolbox: ContinuousFlyout, + metricsManager: ContinuousMetrics, + }, + }); + const workspace = Blockly.inject(container, options); + return workspace; +} \ No newline at end of file From 1645129950797408d01e3966a9d1b7bdf6223226 Mon Sep 17 00:00:00 2001 From: Aaron Dodson Date: Mon, 22 Apr 2024 13:50:38 -0700 Subject: [PATCH 018/130] fix: load CSS and fix up UI appearance (#33) * fix: load CSS and fix up UI appearance * fix: fix size of flyout section header labels --- core/colours.js | 224 ++--- core/css.js | 2294 ++++++++++++++++++++++------------------------- src/index.js | 5 +- 3 files changed, 1223 insertions(+), 1300 deletions(-) diff --git a/core/colours.js b/core/colours.js index ea60b6ec8d..167336594b 100644 --- a/core/colours.js +++ b/core/colours.js @@ -17,109 +17,114 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + import * as Blockly from 'blockly/core'; + + const cssColours = { + // SVG colours: these must be specificed in #RRGGBB style + // To add an opacity, this must be specified as a separate property (for SVG fill-opacity) + "motion": { + "primary": "#4C97FF", + "secondary": "#4280D7", + "tertiary": "#3373CC", + "quaternary": "#3373CC" + }, + "looks": { + "primary": "#9966FF", + "secondary": "#855CD6", + "tertiary": "#774DCB", + "quaternary": "#774DCB" + }, + "sounds": { + "primary": "#CF63CF", + "secondary": "#C94FC9", + "tertiary": "#BD42BD", + "quaternary": "#BD42BD" + }, + "control": { + "primary": "#FFAB19", + "secondary": "#EC9C13", + "tertiary": "#CF8B17", + "quaternary": "#CF8B17" + }, + "event": { + "primary": "#FFBF00", + "secondary": "#E6AC00", + "tertiary": "#CC9900", + "quaternary": "#CC9900" + }, + "sensing": { + "primary": "#5CB1D6", + "secondary": "#47A8D1", + "tertiary": "#2E8EB8", + "quaternary": "#2E8EB8" + }, + "pen": { + "primary": "#0fBD8C", + "secondary": "#0DA57A", + "tertiary": "#0B8E69", + "quaternary": "#0B8E69" + }, + "operators": { + "primary": "#59C059", + "secondary": "#46B946", + "tertiary": "#389438", + "quaternary": "#389438" + }, + "data": { + "primary": "#FF8C1A", + "secondary": "#FF8000", + "tertiary": "#DB6E00", + "quaternary": "#DB6E00" + }, + // This is not a new category, but rather for differentiation + // between lists and scalar variables. + "data_lists": { + "primary": "#FF661A", + "secondary": "#FF5500", + "tertiary": "#E64D00", + "quaternary": "#E64D00" + }, + "more": { + "primary": "#FF6680", + "secondary": "#FF4D6A", + "tertiary": "#FF3355", + "quaternary": "#FF3355" + }, + "text": "#FFFFFF", + "workspace": "#F9F9F9", + "toolboxHover": "#4C97FF", + "toolboxSelected": "#e9eef2", + "toolboxText": "#575E75", + "toolbox": "#FFFFFF", + "flyout": "#F9F9F9", + "scrollbar": "#CECDCE", + "scrollbarHover": '#CECDCE', + "textField": "#FFFFFF", + "textFieldText": "#575E75", + "insertionMarker": "#000000", + "insertionMarkerOpacity": 0.2, + "dragShadowOpacity": 0.3, + "stackGlow": "#FFF200", + "stackGlowSize": 4, + "stackGlowOpacity": 1, + "replacementGlow": "#FFFFFF", + "replacementGlowSize": 2, + "replacementGlowOpacity": 1, + "colourPickerStroke": "#FFFFFF", + // CSS colours: support RGBA + "fieldShadow": "rgba(0,0,0,0.1)", + "dropDownShadow": "rgba(0, 0, 0, .3)", + "numPadBackground": "#547AB2", + "numPadBorder": "#435F91", + "numPadActiveBackground": "#435F91", + "numPadText": "white", // Do not use hex here, it cannot be inlined with data-uri SVG + "valueReportBackground": "#FFFFFF", + "valueReportBorder": "#AAAAAA", + "menuHover": "rgba(0, 0, 0, 0.2)", + }; const Colours = { - // SVG colours: these must be specificed in #RRGGBB style - // To add an opacity, this must be specified as a separate property (for SVG fill-opacity) - "motion": { - "primary": "#4C97FF", - "secondary": "#4280D7", - "tertiary": "#3373CC", - "quaternary": "#3373CC" - }, - "looks": { - "primary": "#9966FF", - "secondary": "#855CD6", - "tertiary": "#774DCB", - "quaternary": "#774DCB" - }, - "sounds": { - "primary": "#CF63CF", - "secondary": "#C94FC9", - "tertiary": "#BD42BD", - "quaternary": "#BD42BD" - }, - "control": { - "primary": "#FFAB19", - "secondary": "#EC9C13", - "tertiary": "#CF8B17", - "quaternary": "#CF8B17" - }, - "event": { - "primary": "#FFBF00", - "secondary": "#E6AC00", - "tertiary": "#CC9900", - "quaternary": "#CC9900" - }, - "sensing": { - "primary": "#5CB1D6", - "secondary": "#47A8D1", - "tertiary": "#2E8EB8", - "quaternary": "#2E8EB8" - }, - "pen": { - "primary": "#0fBD8C", - "secondary": "#0DA57A", - "tertiary": "#0B8E69", - "quaternary": "#0B8E69" - }, - "operators": { - "primary": "#59C059", - "secondary": "#46B946", - "tertiary": "#389438", - "quaternary": "#389438" - }, - "data": { - "primary": "#FF8C1A", - "secondary": "#FF8000", - "tertiary": "#DB6E00", - "quaternary": "#DB6E00" - }, - // This is not a new category, but rather for differentiation - // between lists and scalar variables. - "data_lists": { - "primary": "#FF661A", - "secondary": "#FF5500", - "tertiary": "#E64D00", - "quaternary": "#E64D00" - }, - "more": { - "primary": "#FF6680", - "secondary": "#FF4D6A", - "tertiary": "#FF3355", - "quaternary": "#FF3355" - }, - "text": "#FFFFFF", - "workspace": "#F9F9F9", - "toolboxHover": "#4C97FF", - "toolboxSelected": "#e9eef2", - "toolboxText": "#575E75", - "toolbox": "#FFFFFF", - "flyout": "#F9F9F9", - "scrollbar": "#CECDCE", - "scrollbarHover": '#CECDCE', - "textField": "#FFFFFF", - "textFieldText": "#575E75", - "insertionMarker": "#000000", - "insertionMarkerOpacity": 0.2, - "dragShadowOpacity": 0.3, - "stackGlow": "#FFF200", - "stackGlowSize": 4, - "stackGlowOpacity": 1, - "replacementGlow": "#FFFFFF", - "replacementGlowSize": 2, - "replacementGlowOpacity": 1, - "colourPickerStroke": "#FFFFFF", - // CSS colours: support RGBA - "fieldShadow": "rgba(0,0,0,0.1)", - "dropDownShadow": "rgba(0, 0, 0, .3)", - "numPadBackground": "#547AB2", - "numPadBorder": "#435F91", - "numPadActiveBackground": "#435F91", - "numPadText": "white", // Do not use hex here, it cannot be inlined with data-uri SVG - "valueReportBackground": "#FFFFFF", - "valueReportBorder": "#AAAAAA", - "menuHover": "rgba(0, 0, 0, 0.2)", + ...cssColours, overrideColours: function(colours) { // Colour overrides provided by the injection if (colours) { @@ -148,4 +153,21 @@ const Colours = { } }; +function varify(coloursObj, prefix = '--colour') { + return Object.keys(coloursObj).map(key => { + const colour = coloursObj[key]; + if (typeof colour === 'string') { + return `${prefix}-${key}: ${colour};`; + } else { + return varify(colour, `${prefix}-${key}`); + } + }).join('\n'); +} + +const cssVariables = `:root { + ${varify(cssColours)} +}`; + +Blockly.Css.register(cssVariables); + export {Colours}; diff --git a/core/css.js b/core/css.js index 03c6bab0f1..f7b608451c 100644 --- a/core/css.js +++ b/core/css.js @@ -17,1007 +17,904 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +import * as Blockly from 'blockly/core'; + +const styles = ` + .blocklySvg { + background-color: var(--colour-workspace); + outline: none; + overflow: hidden; /* IE overflows by default. */ + position: absolute; + display: block; + } -/** - * @fileoverview Inject Blockly's CSS synchronously. - * @author fraser@google.com (Neil Fraser) - */ -'use strict'; - -/** - * @name Blockly.Css - * @namespace - */ -goog.provide('Blockly.Css'); - -goog.require('Blockly.Colours'); + /* Necessary to position the drag surface */ + .blocklyRelativeWrapper { + position: relative; + width: 100%; + height: 100%; + } -goog.require('goog.userAgent'); + .blocklyWidgetDiv { + display: none; + position: absolute; + z-index: 99999; /* big value for bootstrap3 compatibility */ + } -/** - * List of cursors. - * @enum {string} - */ -Blockly.Css.Cursor = { - OPEN: 'handopen', - CLOSED: 'handclosed', - DELETE: 'handdelete' -}; + .injectionDiv { + height: 100%; + position: relative; + overflow: hidden; /* So blocks in drag surface disappear at edges */ + touch-action: none + } -/** - * Current cursor (cached value). - * @type {string} - * @private - */ -Blockly.Css.currentCursor_ = ''; + .blocklyNonSelectable { + user-select: none; + -moz-user-select: none; + -webkit-user-select: none; + -ms-user-select: none; + } -/** - * Large stylesheet added by Blockly.Css.inject. - * @type {Element} - * @private - */ -Blockly.Css.styleSheet_ = null; + .blocklyWidgetDiv.fieldTextInput { + overflow: hidden; + border: 1px solid; + box-sizing: border-box; + transform-origin: 0 0; + -ms-transform-origin: 0 0; + -moz-transform-origin: 0 0; + -webkit-transform-origin: 0 0; + } -/** - * Path to media directory, with any trailing slash removed. - * @type {string} - * @private - */ -Blockly.Css.mediaPath_ = ''; + .blocklyWidgetDiv.fieldTextInput.removableTextInput { + overflow: visible; + } -/** - * Inject the CSS into the DOM. This is preferable over using a regular CSS - * file since: - * a) It loads synchronously and doesn't force a redraw later. - * b) It speeds up loading by not blocking on a separate HTTP transfer. - * c) The CSS content may be made dynamic depending on init options. - * @param {boolean} hasCss If false, don't inject CSS - * (providing CSS becomes the document's responsibility). - * @param {string} pathToMedia Path from page to the Blockly media directory. - */ -Blockly.Css.inject = function(hasCss, pathToMedia) { - // Clear the CSS if it has already been injected. - if (Blockly.Css.styleSheet_) { - document.head.removeChild(Blockly.Css.styleSheet_.ownerNode); - } - // Placeholder for cursor rule. Must be first rule (index 0). - var text = '.blocklyDraggable {}\n'; - if (hasCss) { - text += Blockly.Css.CONTENT.join('\n'); - if (Blockly.FieldDate) { - text += Blockly.FieldDate.CSS.join('\n'); - } - } - // Strip off any trailing slash (either Unix or Windows). - Blockly.Css.mediaPath_ = pathToMedia.replace(/[\\\/]$/, ''); - text = text.replace(/<<>>/g, Blockly.Css.mediaPath_); - // Dynamically replace colours in the CSS text, in case they have - // been set at run-time injection. - // Process longer colour properties first to handle common prefixes. - var compareByLength = function(a, b) { return b.length - a.length; }; - var colourProperties = Object.keys(Blockly.Colours).sort(compareByLength); - for (var i = 0, colourProperty; colourProperty = colourProperties[i]; i++) { - // Replace all - text = text.replace( - new RegExp('\\$colour\\_' + colourProperty, 'g'), - Blockly.Colours[colourProperty] - ); - } - - // Inject CSS tag at start of head. - var cssNode = document.createElement('style'); - document.head.insertBefore(cssNode, document.head.firstChild); - - var cssTextNode = document.createTextNode(text); - cssNode.appendChild(cssTextNode); - Blockly.Css.styleSheet_ = cssNode.sheet; -}; + .blocklyTextDropDownArrow { + position: absolute; + } -/** - * Set the cursor to be displayed when over something draggable. - * See See https://github.com/google/blockly/issues/981 for context. - * @param {Blockly.Css.Cursor} cursor Enum. - * @deprecated April 2017. - */ -Blockly.Css.setCursor = function(cursor) { - console.warn('Deprecated call to Blockly.Css.setCursor.' + - 'See https://github.com/google/blockly/issues/981 for context'); -}; + .blocklyTextRemoveIcon { + position: absolute; + width: 24px; + height: 24px; + top: -40px; + left: 50%; + margin-left: -12px; + cursor: pointer; + } -/** - * Array making up the CSS content for Blockly. - */ -Blockly.Css.CONTENT = [ - '.blocklySvg {', - 'background-color: $colour_workspace;', - 'outline: none;', - 'overflow: hidden;', /* IE overflows by default. */ - 'position: absolute;', - 'display: block;', - '}', + .blocklyNonSelectable { + user-select: none; + -moz-user-select: none; + -webkit-user-select: none; + -ms-user-select: none; + } - /* Necessary to position the drag surface */ - '.blocklyRelativeWrapper {', - 'position: relative;', - 'width: 100%;', - 'height: 100%;', - '}', - - '.blocklyWidgetDiv {', - 'display: none;', - 'position: absolute;', - 'z-index: 99999;', /* big value for bootstrap3 compatibility */ - '}', - - '.injectionDiv {', - 'height: 100%;', - 'position: relative;', - 'overflow: hidden;', /* So blocks in drag surface disappear at edges */ - 'touch-action: none', - '}', - - '.blocklyNonSelectable {', - 'user-select: none;', - '-moz-user-select: none;', - '-webkit-user-select: none;', - '-ms-user-select: none;', - '}', - - '.blocklyWidgetDiv.fieldTextInput {', - 'overflow: hidden;', - 'border: 1px solid;', - 'box-sizing: border-box;', - 'transform-origin: 0 0;', - '-ms-transform-origin: 0 0;', - '-moz-transform-origin: 0 0;', - '-webkit-transform-origin: 0 0;', - '}', - - '.blocklyWidgetDiv.fieldTextInput.removableTextInput {', - 'overflow: visible;', - '}', - - '.blocklyTextDropDownArrow {', - 'position: absolute;', - '}', - - '.blocklyTextRemoveIcon {', - 'position: absolute;', - 'width: 24px;', - 'height: 24px;', - 'top: -40px;', - 'left: 50%;', - 'margin-left: -12px;', - 'cursor: pointer;', - '}', - - '.blocklyNonSelectable {', - 'user-select: none;', - '-moz-user-select: none;', - '-webkit-user-select: none;', - '-ms-user-select: none;', - '}', - - '.blocklyWsDragSurface {', - 'display: none;', - 'position: absolute;', - 'top: 0;', - 'left: 0;', - '}', + .blocklyWsDragSurface { + display: none; + position: absolute; + top: 0; + left: 0; + } /* Added as a separate rule with multiple classes to make it more specific than a bootstrap rule that selects svg:root. See issue #1275 for context. */ - '.blocklyWsDragSurface.blocklyOverflowVisible {', - 'overflow: visible;', - '}', - - '.blocklyBlockDragSurface {', - 'display: none;', - 'position: absolute;', - 'top: 0;', - 'left: 0;', - 'right: 0;', - 'bottom: 0;', - 'overflow: visible !important;', - 'z-index: 50;', /* Display above the toolbox */ - '}', - - '.blocklyTooltipDiv {', - 'background-color: #ffffc7;', - 'border: 1px solid #ddc;', - 'box-shadow: 4px 4px 20px 1px rgba(0,0,0,.15);', - 'color: #000;', - 'display: none;', - 'font-family: "Helvetica Neue", Helvetica, sans-serif;', - 'font-size: 9pt;', - 'opacity: 0.9;', - 'padding: 2px;', - 'position: absolute;', - 'z-index: 100000;', /* big value for bootstrap3 compatibility */ - '}', - - '.blocklyDropDownDiv {', - 'position: fixed;', - 'left: 0;', - 'top: 0;', - 'z-index: 1000;', - 'display: none;', - 'border: 1px solid;', - 'border-radius: 4px;', - 'box-shadow: 0px 0px 8px 1px ' + Blockly.Colours.dropDownShadow + ';', - 'padding: 4px;', - '-webkit-user-select: none;', - 'min-height: 15px', - '}', - - '.blocklyDropDownContent {', - 'max-height: 300px;', // @todo: spec for maximum height. - 'overflow: auto;', - '}', - - '.blocklyDropDownArrow {', - 'position: absolute;', - 'left: 0;', - 'top: 0;', - 'width: 16px;', - 'height: 16px;', - 'z-index: -1;', - 'background-color: inherit;', - 'border-color: inherit;', - '}', - - '.blocklyDropDownButton {', - 'display: inline-block;', - 'float: left;', - 'padding: 0;', - 'margin: 4px;', - 'border-radius: 4px;', - 'outline: none;', - 'border: 1px solid;', - 'transition: box-shadow .1s;', - 'cursor: pointer;', - '}', - - '.blocklyDropDownButtonHover {', - 'box-shadow: 0px 0px 0px 4px ' + Blockly.Colours.fieldShadow + ';', - '}', - - '.blocklyDropDownButton:active {', - 'box-shadow: 0px 0px 0px 6px ' + Blockly.Colours.fieldShadow + ';', - '}', - - '.blocklyDropDownButton > img {', - 'width: 80%;', - 'height: 80%;', - 'margin-top: 5%', - '}', - - '.blocklyDropDownPlaceholder {', - 'display: inline-block;', - 'float: left;', - 'padding: 0;', - 'margin: 4px;', - '}', - - '.blocklyNumPadButton {', - 'display: inline-block;', - 'float: left;', - 'padding: 0;', - 'width: 48px;', - 'height: 48px;', - 'margin: 4px;', - 'border-radius: 4px;', - 'background: $colour_numPadBackground;', - 'color: $colour_numPadText;', - 'outline: none;', - 'border: 1px solid $colour_numPadBorder;', - 'cursor: pointer;', - 'font-weight: 600;', - 'font-family: "Helvetica Neue", Helvetica, sans-serif;', - 'font-size: 12pt;', - '-webkit-tap-highlight-color: rgba(0,0,0,0);', - '}', - - '.blocklyNumPadButton > img {', - 'margin-top: 10%;', - 'width: 80%;', - 'height: 80%;', - '}', - - '.blocklyNumPadButton:active {', - 'background: $colour_numPadActiveBackground;', - '-webkit-tap-highlight-color: rgba(0,0,0,0);', - '}', - - '.arrowTop {', - 'border-top: 1px solid;', - 'border-left: 1px solid;', - 'border-top-left-radius: 4px;', - 'border-color: inherit;', - '}', - - '.arrowBottom {', - 'border-bottom: 1px solid;', - 'border-right: 1px solid;', - 'border-bottom-right-radius: 4px;', - 'border-color: inherit;', - '}', - - '.valueReportBox {', - 'min-width: 50px;', - 'max-width: 300px;', - 'max-height: 200px;', - 'overflow: auto;', - 'word-wrap: break-word;', - 'text-align: center;', - 'font-family: "Helvetica Neue", Helvetica, sans-serif;', - 'font-size: .8em;', - '}', - - '.blocklyResizeSE {', - 'cursor: se-resize;', - 'fill: #aaa;', - '}', - - '.blocklyResizeSW {', - 'cursor: sw-resize;', - 'fill: #aaa;', - '}', - - '.blocklyResizeLine {', - 'stroke: #888;', - 'stroke-width: 1;', - '}', - - '.blocklyHighlightedConnectionPath {', - 'fill: none;', - 'stroke: #fc3;', - 'stroke-width: 4px;', - '}', - - '.blocklyPath {', - 'stroke-width: 1px;', - '}', - - '.blocklySelected>.blocklyPath {', - // 'stroke: #fc3;', - // 'stroke-width: 3px;', - '}', - - '.blocklySelected>.blocklyPathLight {', - 'display: none;', - '}', - - '.blocklyDraggable {', + .blocklyWsDragSurface.blocklyOverflowVisible { + overflow: visible; + } + + .blocklyBlockDragSurface { + display: none; + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + overflow: visible !important; + z-index: 50; /* Display above the toolbox */ + } + + .blocklyTooltipDiv { + background-color: #ffffc7; + border: 1px solid #ddc; + box-shadow: 4px 4px 20px 1px rgba(0,0,0,.15); + color: #000; + display: none; + font-family: "Helvetica Neue", Helvetica, sans-serif; + font-size: 9pt; + opacity: 0.9; + padding: 2px; + position: absolute; + z-index: 100000; /* big value for bootstrap3 compatibility */ + } + + .blocklyDropDownDiv { + position: fixed; + left: 0; + top: 0; + z-index: 1000; + display: none; + border: 1px solid; + border-radius: 4px; + box-shadow: 0px 0px 8px 1px var(--colour-dropDownShadow); + padding: 4px; + -webkit-user-select: none; + min-height: 15px + } + + .blocklyDropDownContent { + max-height: 300px; // @todo: spec for maximum height. + overflow: auto; + } + + .blocklyDropDownArrow { + position: absolute; + left: 0; + top: 0; + width: 16px; + height: 16px; + z-index: -1; + background-color: inherit; + border-color: inherit; + } + + .blocklyDropDownButton { + display: inline-block; + float: left; + padding: 0; + margin: 4px; + border-radius: 4px; + outline: none; + border: 1px solid; + transition: box-shadow .1s; + cursor: pointer; + } + + .blocklyDropDownButtonHover { + box-shadow: 0px 0px 0px 4px var(--colour-fieldShadow); + } + + .blocklyDropDownButton:active { + box-shadow: 0px 0px 0px 6px var(--colour-fieldShadow); + } + + .blocklyDropDownButton > img { + width: 80%; + height: 80%; + margin-top: 5% + } + + .blocklyDropDownPlaceholder { + display: inline-block; + float: left; + padding: 0; + margin: 4px; + } + + .blocklyNumPadButton { + display: inline-block; + float: left; + padding: 0; + width: 48px; + height: 48px; + margin: 4px; + border-radius: 4px; + background: var(--colour-numPadBackground); + color: var(--colour-numPadText); + outline: none; + border: 1px solid var(--colour-numPadBorder); + cursor: pointer; + font-weight: 600; + font-family: "Helvetica Neue", Helvetica, sans-serif; + font-size: 12pt; + -webkit-tap-highlight-color: rgba(0,0,0,0); + } + + .blocklyNumPadButton > img { + margin-top: 10%; + width: 80%; + height: 80%; + } + + .blocklyNumPadButton:active { + background: var(--colour-numPadActiveBackground); + -webkit-tap-highlight-color: rgba(0,0,0,0); + } + + .arrowTop { + border-top: 1px solid; + border-left: 1px solid; + border-top-left-radius: 4px; + border-color: inherit; + } + + .arrowBottom { + border-bottom: 1px solid; + border-right: 1px solid; + border-bottom-right-radius: 4px; + border-color: inherit; + } + + .valueReportBox { + min-width: 50px; + max-width: 300px; + max-height: 200px; + overflow: auto; + word-wrap: break-word; + text-align: center; + font-family: "Helvetica Neue", Helvetica, sans-serif; + font-size: .8em; + } + + .blocklyResizeSE { + cursor: se-resize; + fill: #aaa; + } + + .blocklyResizeSW { + cursor: sw-resize; + fill: #aaa; + } + + .blocklyResizeLine { + stroke: #888; + stroke-width: 1; + } + + .blocklyHighlightedConnectionPath { + fill: none; + stroke: #fc3; + stroke-width: 4px; + } + + .blocklyPath { + stroke-width: 1px; + } + + .blocklySelected>.blocklyPath { + // stroke: #fc3; + // stroke-width: 3px; + } + + .blocklySelected>.blocklyPathLight { + display: none; + } + + .blocklyDraggable { /* backup for browsers (e.g. IE11) that don't support grab */ - 'cursor: url("<<>>/handopen.cur"), auto;', - 'cursor: grab;', - 'cursor: -webkit-grab;', - 'cursor: -moz-grab;', - '}', + cursor: url("<<>>/handopen.cur"), auto; + cursor: grab; + cursor: -webkit-grab; + cursor: -moz-grab; + } - '.blocklyDragging {', + .blocklyDragging { /* backup for browsers (e.g. IE11) that don't support grabbing */ - 'cursor: url("<<>>/handclosed.cur"), auto;', - 'cursor: grabbing;', - 'cursor: -webkit-grabbing;', - 'cursor: -moz-grabbing;', - '}', + cursor: url("<<>>/handclosed.cur"), auto; + cursor: grabbing; + cursor: -webkit-grabbing; + cursor: -moz-grabbing; + } /* Changes cursor on mouse down. Not effective in Firefox because of https://bugzilla.mozilla.org/show_bug.cgi?id=771241 */ - '.blocklyDraggable:active {', + .blocklyDraggable:active { /* backup for browsers (e.g. IE11) that don't support grabbing */ - 'cursor: url("<<>>/handclosed.cur"), auto;', - 'cursor: grabbing;', - 'cursor: -webkit-grabbing;', - 'cursor: -moz-grabbing;', - '}', + cursor: url("<<>>/handclosed.cur"), auto; + cursor: grabbing; + cursor: -webkit-grabbing; + cursor: -moz-grabbing; + } /* Change the cursor on the whole drag surface in case the mouse gets ahead of block during a drag. This way the cursor is still a closed hand. */ - '.blocklyBlockDragSurface .blocklyDraggable {', + .blocklyBlockDragSurface .blocklyDraggable { /* backup for browsers (e.g. IE11) that don't support grabbing */ - 'cursor: url("<<>>/handclosed.cur"), auto;', - 'cursor: grabbing;', - 'cursor: -webkit-grabbing;', - 'cursor: -moz-grabbing;', - '}', - - '.blocklyDragging.blocklyDraggingDelete {', - 'cursor: url("<<>>/handdelete.cur"), auto;', - '}', - - '.blocklyDragging.blocklyDraggingMouseThrough {', - 'pointer-events: none;', - '}', - - '.blocklyToolboxDelete {', - 'cursor: url("<<>>/handdelete.cur"), auto;', - '}', - - '.blocklyToolboxGrab {', - 'cursor: url("<<>>/handclosed.cur"), auto;', - 'cursor: grabbing;', - 'cursor: -webkit-grabbing;', - '}', - - '.blocklyDragging>.blocklyPath,', - '.blocklyDragging>.blocklyPathLight {', - 'fill-opacity: 1.0;', - 'stroke-opacity: 1.0;', - '}', - - '.blocklyDragging>.blocklyPath {', - '}', - - '.blocklyDisabled>.blocklyPath {', - 'fill-opacity: .5;', - 'stroke-opacity: .5;', - '}', - - '.blocklyInsertionMarker>.blocklyPath {', - 'stroke: none;', - '}', - - '.blocklyText {', - 'fill: $colour_text;', - 'font-family: "Helvetica Neue", Helvetica, sans-serif;', - 'font-size: 12pt;', - 'font-weight: 500;', - '}', - - '.blocklyTextTruncated {', - 'font-size: 11pt;', - '}', - - '.blocklyNonEditableText>text {', - 'pointer-events: none;', - '}', - '.blocklyNonEditableText>text,', - '.blocklyEditableText>text {', - 'fill: $colour_textFieldText;', - '}', - - '.blocklyEditableText>.blocklyEditableLabel {', - 'fill: #fff;', - '}', - - '.blocklyDropdownText {', - 'fill: $colour_text !important;', - '}', - - '.blocklyBubbleText {', - 'fill: $colour_textFieldText;', - '}', - '.blocklyFlyout {', - 'position: absolute;', - 'z-index: 20;', - '}', - '.blocklyFlyoutButton {', - 'fill: none;', - 'pointer-events: all;', - '}', - - '.blocklyFlyoutButtonBackground {', - 'stroke: #c6c6c6;', - '}', - - '.blocklyFlyoutButton .blocklyText {', - 'fill: $colour_textFieldText;', - '}', - - '.blocklyFlyoutButtonShadow {', - 'fill: transparent;', - '}', - - '.blocklyFlyoutButton:hover {', - 'fill: white;', - 'cursor: pointer;', - '}', - - '.blocklyFlyoutLabel {', - 'cursor: default;', - '}', - - '.blocklyFlyoutLabelBackground {', - 'opacity: 0;', - '}', - - '.blocklyTouchTargetBackground {', - 'fill: transparent;', - 'cursor: pointer;', - '}', - - '.blocklyFlyoutLabelText {', - 'font-family: "Helvetica Neue", Helvetica, sans-serif;', - 'font-size: 14pt;', - 'fill: #575E75;', - 'font-weight: bold;', - '}', + cursor: url("<<>>/handclosed.cur"), auto; + cursor: grabbing; + cursor: -webkit-grabbing; + cursor: -moz-grabbing; + } + + .blocklyDragging.blocklyDraggingDelete { + cursor: url("<<>>/handdelete.cur"), auto; + } + + .blocklyDragging.blocklyDraggingMouseThrough { + pointer-events: none; + } + + .blocklyToolboxDelete { + cursor: url("<<>>/handdelete.cur"), auto; + } + + .blocklyToolboxGrab { + cursor: url("<<>>/handclosed.cur"), auto; + cursor: grabbing; + cursor: -webkit-grabbing; + } + + .blocklyDragging>.blocklyPath, + .blocklyDragging>.blocklyPathLight { + fill-opacity: 1.0; + stroke-opacity: 1.0; + } + + .blocklyDragging>.blocklyPath { + } + + .blocklyDisabled>.blocklyPath { + fill-opacity: .5; + stroke-opacity: .5; + } + + .blocklyInsertionMarker>.blocklyPath { + stroke: none; + } + + .blocklyText { + fill: var(--colour-text); + font-family: "Helvetica Neue", Helvetica, sans-serif; + font-size: 12pt; + font-weight: 500; + } + + .blocklyTextTruncated { + font-size: 11pt; + } + + .blocklyNonEditableText>text { + pointer-events: none; + } + .blocklyNonEditableText>text, + .blocklyEditableText>text { + fill: var(--colour-textFieldText); + } + + .blocklyEditableText>.blocklyEditableLabel { + fill: #fff; + } + + .blocklyDropdownText { + fill: $colour_text !important; + } + + .blocklyBubbleText { + fill: var(--colour-textFieldText); + } + .blocklyFlyout { + position: absolute; + z-index: 20; + } + .blocklyFlyoutButton { + fill: none; + pointer-events: all; + } + + .blocklyFlyoutButtonBackground { + stroke: #c6c6c6; + } + + .blocklyFlyoutButton .blocklyText { + fill: var(--colour-textFieldText); + } + + .blocklyFlyoutButtonShadow { + fill: transparent; + } + + .blocklyFlyoutButton:hover { + fill: white; + cursor: pointer; + } + + .blocklyFlyoutLabel { + cursor: default; + } + + .blocklyFlyoutLabelBackground { + opacity: 0; + } + + .blocklyTouchTargetBackground { + fill: transparent; + cursor: pointer; + } + + .zelos-renderer.scratch-theme .blocklyFlyoutLabelText { + font-family: "Helvetica Neue", Helvetica, sans-serif; + font-size: 14pt; + fill: #575E75; + font-weight: bold; + } /* Don't allow users to select text. It gets annoying when trying to drag a block and selected text moves instead. */ - '.blocklySvg text, .blocklyBlockDragSurface text, .blocklyFlyout text, .blocklyToolboxDiv text {', - 'user-select: none;', - '-moz-user-select: none;', - '-webkit-user-select: none;', - 'cursor: inherit;', - '}', - - '.blocklyHidden {', - 'display: none;', - '}', - - '.blocklyFieldDropdown:not(.blocklyHidden) {', - 'display: block;', - '}', - - '.blocklyIconGroup {', - 'cursor: default;', - '}', - - '.blocklyIconGroup:not(:hover),', - '.blocklyIconGroupReadonly {', - 'opacity: .6;', - '}', - - '.blocklyIconShape {', - 'fill: #00f;', - 'stroke: #fff;', - 'stroke-width: 1px;', - '}', - - '.blocklyIconSymbol {', - 'fill: #fff;', - '}', - - '.blocklyMinimalBody {', - 'margin: 0;', - 'padding: 0;', - '}', - - '.blocklyCommentForeignObject {', - 'position: relative;', - 'z-index: 0;', - '}', - - '.blocklyCommentRect {', - 'fill: #E7DE8E;', - 'stroke: #bcA903;', - 'stroke-width: 1px', - '}', - - '.blocklyCommentTarget {', - 'fill: transparent;', - 'stroke: #bcA903;', - '}', - - '.blocklyCommentTargetFocused {', - 'fill: none;', - '}', - - '.blocklyCommentHandleTarget {', - 'fill: none;', - '}', - - '.blocklyCommentHandleTargetFocused {', - 'fill: transparent;', - '}', - - '.blocklyFocused>.blocklyCommentRect {', - 'fill: #B9B272;', - 'stroke: #B9B272;', - '}', - - '.blocklySelected>.blocklyCommentTarget {', - 'stroke: #fc3;', - 'stroke-width: 3px;', - '}', - - - '.blocklyCommentTextarea {', - 'background-color: #fef49c;', - 'border: 0;', - 'outline: 0;', - 'margin: 0;', - 'padding: 3px;', - 'resize: none;', - 'display: block;', - 'overflow: hidden;', - '}', - - '.blocklyCommentDeleteIcon {', - 'cursor: pointer;', - 'fill: #000;', - 'display: none', - '}', - - '.blocklySelected > .blocklyCommentDeleteIcon {', - 'display: block', - '}', - - '.blocklyDeleteIconShape {', - 'fill: #000;', - 'stroke: #000;', - 'stroke-width: 1px;', - '}', - - '.blocklyDeleteIconShape.blocklyDeleteIconHighlighted {', - 'stroke: #fc3;', - '}', + .blocklySvg text, .blocklyBlockDragSurface text, .blocklyFlyout text, .blocklyToolboxDiv text { + user-select: none; + -moz-user-select: none; + -webkit-user-select: none; + cursor: inherit; + } + + .blocklyHidden { + display: none; + } + + .blocklyFieldDropdown:not(.blocklyHidden) { + display: block; + } + + .blocklyIconGroup { + cursor: default; + } + + .blocklyIconGroup:not(:hover), + .blocklyIconGroupReadonly { + opacity: .6; + } + + .blocklyIconShape { + fill: #00f; + stroke: #fff; + stroke-width: 1px; + } + + .blocklyIconSymbol { + fill: #fff; + } + + .blocklyMinimalBody { + margin: 0; + padding: 0; + } + + .blocklyCommentForeignObject { + position: relative; + z-index: 0; + } + + .blocklyCommentRect { + fill: #E7DE8E; + stroke: #bcA903; + stroke-width: 1px + } + + .blocklyCommentTarget { + fill: transparent; + stroke: #bcA903; + } + + .blocklyCommentTargetFocused { + fill: none; + } + + .blocklyCommentHandleTarget { + fill: none; + } + + .blocklyCommentHandleTargetFocused { + fill: transparent; + } + + .blocklyFocused>.blocklyCommentRect { + fill: #B9B272; + stroke: #B9B272; + } + + .blocklySelected>.blocklyCommentTarget { + stroke: #fc3; + stroke-width: 3px; + } + + + .blocklyCommentTextarea { + background-color: #fef49c; + border: 0; + outline: 0; + margin: 0; + padding: 3px; + resize: none; + display: block; + overflow: hidden; + } + + .blocklyCommentDeleteIcon { + cursor: pointer; + fill: #000; + display: none + } + + .blocklySelected > .blocklyCommentDeleteIcon { + display: block + } + + .blocklyDeleteIconShape { + fill: #000; + stroke: #000; + stroke-width: 1px; + } + + .blocklyDeleteIconShape.blocklyDeleteIconHighlighted { + stroke: #fc3; + } // Scratch Comments - '.scratchCommentForeignObject {', - 'position: relative;', - '}', - - '.scratchCommentBody {', - 'background-color: #fef49c;', - 'border-radius: 4px;', - '}', - - '.scratchCommentRect {', - 'fill: #fef49c;', - '}', - - '.scratchCommentTarget {', - 'fill: transparent;', - '}', - - '.scratchWorkspaceCommentBorder {', - 'stroke: #bcA903;', - 'stroke-width: 1px;', - '}', - - '.scratchCommentTargetFocused {', - 'fill: none;', - '}', - - '.scratchCommentTopBar {', - 'fill: #000000;', - 'fill-opacity: 0.1', - '}', - - '.scratchCommentText {', - 'font-family: "Helvetica Neue", Helvetica, sans-serif;', - 'font-size: 12pt;', - 'font-weight: 400;', - '}', - - '.scratchCommentTextarea {', - 'background-color: #fef49c;', - 'border: 0;', - 'outline: 0;', - 'padding: 0;', - 'resize: none;', - 'overflow: hidden;', - '}', - - '.scratchCommentTextarea::placeholder {', - 'color: rgba(0,0,0,0.5);', - 'font-style: italic;', - '}', - - '.scratchCommentResizeSE {', - 'cursor: se-resize;', - 'fill: transparent;', - '}', - - '.scratchCommentResizeSW {', - 'cursor: sw-resize;', - 'fill: transparent;', - '}', - - '.blocklyHtmlInput {', - 'border: none;', - 'font-family: "Helvetica Neue", Helvetica, sans-serif;', - 'font-size: 12pt;', - 'height: 100%;', - 'margin: 0;', - 'outline: none;', - 'box-sizing: border-box;', - 'width: 100%;', - 'text-align: center;', - 'color: $colour_textFieldText;', - 'font-weight: 500;', - '}', - - '.blocklyMainBackground {', - 'stroke-width: 1;', - 'stroke: #c6c6c6;', /* Equates to #ddd due to border being off-pixel. */ - '}', - - '.blocklyMutatorBackground {', - 'fill: #fff;', - 'stroke: #ddd;', - 'stroke-width: 1;', - '}', - - '.blocklyFlyoutBackground {', - 'fill: $colour_flyout;', - 'fill-opacity: .8;', - '}', - - '.blocklyMainWorkspaceScrollbar {', - 'z-index: 20;', - '}', - - '.blocklyFlyoutScrollbar {', - 'z-index: 30;', - '}', - - '.blocklyScrollbarHorizontal, .blocklyScrollbarVertical {', - 'position: absolute;', - 'outline: none;', - '}', - - '.blocklyScrollbarBackground {', - 'opacity: 0;', - '}', - - '.blocklyScrollbarHandle {', - 'fill: $colour_scrollbar;', - '}', - - '.blocklyScrollbarBackground:hover+.blocklyScrollbarHandle,', - '.blocklyScrollbarHandle:hover {', - 'fill: $colour_scrollbarHover;', - '}', - - '.blocklyZoom>image {', - 'opacity: 1;', - '}', + .scratchCommentForeignObject { + position: relative; + } + + .scratchCommentBody { + background-color: #fef49c; + border-radius: 4px; + } + + .scratchCommentRect { + fill: #fef49c; + } + + .scratchCommentTarget { + fill: transparent; + } + + .scratchWorkspaceCommentBorder { + stroke: #bcA903; + stroke-width: 1px; + } + + .scratchCommentTargetFocused { + fill: none; + } + + .scratchCommentTopBar { + fill: #000000; + fill-opacity: 0.1 + } + + .scratchCommentText { + font-family: "Helvetica Neue", Helvetica, sans-serif; + font-size: 12pt; + font-weight: 400; + } + + .scratchCommentTextarea { + background-color: #fef49c; + border: 0; + outline: 0; + padding: 0; + resize: none; + overflow: hidden; + } + + .scratchCommentTextarea::placeholder { + color: rgba(0,0,0,0.5); + font-style: italic; + } + + .scratchCommentResizeSE { + cursor: se-resize; + fill: transparent; + } + + .scratchCommentResizeSW { + cursor: sw-resize; + fill: transparent; + } + + .blocklyHtmlInput { + border: none; + font-family: "Helvetica Neue", Helvetica, sans-serif; + font-size: 12pt; + height: 100%; + margin: 0; + outline: none; + box-sizing: border-box; + width: 100%; + text-align: center; + color: var(--colour-textFieldText); + font-weight: 500; + } + + .blocklyMainBackground { + stroke-width: 1; + stroke: #c6c6c6; /* Equates to #ddd due to border being off-pixel. */ + } + + .blocklyMutatorBackground { + fill: #fff; + stroke: #ddd; + stroke-width: 1; + } + + .blocklyFlyoutBackground { + fill: var(--colour-flyout); + fill-opacity: .8; + } + + .blocklyMainWorkspaceScrollbar { + z-index: 20; + } + + .blocklyFlyoutScrollbar { + z-index: 30; + } + + .blocklyScrollbarHorizontal, .blocklyScrollbarVertical { + position: absolute; + outline: none; + } + + .blocklyScrollbarBackground { + opacity: 0; + } + + .blocklyScrollbarHandle { + fill: var(--colour-scrollbar); + } + + .blocklyScrollbarBackground:hover+.blocklyScrollbarHandle, + .blocklyScrollbarHandle:hover { + fill: var(--colour-scrollbarHover); + } + + .blocklyZoom>image { + opacity: 1; + } /* Darken flyout scrollbars due to being on a grey background. */ /* By contrast, workspace scrollbars are on a white background. */ - '.blocklyFlyout .blocklyScrollbarHandle {', - 'fill: #bbb;', - '}', - - '.blocklyFlyout .blocklyScrollbarBackground:hover+.blocklyScrollbarHandle,', - '.blocklyFlyout .blocklyScrollbarHandle:hover {', - 'fill: #aaa;', - '}', - - '.blocklyInvalidInput {', - 'background: #faa;', - '}', - - '.blocklyAngleCircle {', - 'stroke: ' + Blockly.Colours.motion.tertiary + ';', - 'stroke-width: 1;', - 'fill: ' + Blockly.Colours.motion.secondary + ';', - '}', - - '.blocklyAngleCenterPoint {', - 'stroke: #fff;', - 'stroke-width: 1;', - 'fill: #fff;', - '}', - - '.blocklyAngleDragHandle {', - 'stroke: #fff;', - 'stroke-width: 5;', - 'stroke-opacity: 0.25;', - 'fill: #fff;', - 'cursor: pointer;', - '}', - - '.blocklyAngleDragArrow {', - 'pointer-events: none', - '}', - - '.blocklyAngleMarks {', - 'stroke: #fff;', - 'stroke-width: 1;', - 'stroke-opacity: 0.5;', - '}', - - '.blocklyAngleGauge {', - 'fill: #fff;', - 'fill-opacity: 0.20;', - '}', - - '.blocklyAngleLine {', - 'stroke: #fff;', - 'stroke-width: 1;', - 'stroke-linecap: round;', - 'pointer-events: none;', - '}', - - '.blocklyContextMenu {', - 'border-radius: 4px;', - 'max-height: 100%;', - '}', - - '.blocklyDropdownMenu {', - 'padding: 0 !important;', - '}', - - '.blocklyDropDownNumPad {', - 'background-color: $colour_numPadBackground;', - '}', + .blocklyFlyout .blocklyScrollbarHandle { + fill: #bbb; + } + + .blocklyFlyout .blocklyScrollbarBackground:hover+.blocklyScrollbarHandle, + .blocklyFlyout .blocklyScrollbarHandle:hover { + fill: #aaa; + } + + .blocklyInvalidInput { + background: #faa; + } + + .blocklyAngleCircle { + stroke: var(--colour-motion-tertiary); + stroke-width: 1; + fill: var(--colour-motion-secondary); + } + + .blocklyAngleCenterPoint { + stroke: #fff; + stroke-width: 1; + fill: #fff; + } + + .blocklyAngleDragHandle { + stroke: #fff; + stroke-width: 5; + stroke-opacity: 0.25; + fill: #fff; + cursor: pointer; + } + + .blocklyAngleDragArrow { + pointer-events: none + } + + .blocklyAngleMarks { + stroke: #fff; + stroke-width: 1; + stroke-opacity: 0.5; + } + + .blocklyAngleGauge { + fill: #fff; + fill-opacity: 0.20; + } + + .blocklyAngleLine { + stroke: #fff; + stroke-width: 1; + stroke-linecap: round; + pointer-events: none; + } + + .blocklyContextMenu { + border-radius: 4px; + max-height: 100%; + } + + .blocklyDropdownMenu { + padding: 0 !important; + } + + .blocklyDropDownNumPad { + background-color: var(--colour-numPadBackground); + } /* Override the default Closure URL. */ - '.blocklyWidgetDiv .goog-option-selected .goog-menuitem-checkbox,', - '.blocklyWidgetDiv .goog-option-selected .goog-menuitem-icon {', - 'background: url(<<>>/sprites.png) no-repeat -48px -16px !important;', - '}', + .blocklyWidgetDiv .goog-option-selected .goog-menuitem-checkbox, + .blocklyWidgetDiv .goog-option-selected .goog-menuitem-icon { + background: url(<<>>/sprites.png) no-repeat -48px -16px !important; + } /* Category tree in Toolbox. */ - '.blocklyToolboxDiv {', - 'background-color: $colour_toolbox;', - 'color: $colour_toolboxText;', - 'overflow-x: visible;', - 'overflow-y: auto;', - 'position: absolute;', - 'font-family: "Helvetica Neue", Helvetica, sans-serif;', - 'z-index: 40;', /* so blocks go over toolbox when dragging */ - '-webkit-tap-highlight-color: transparent;', /* issue #1345 */ - '}', - - '.blocklyTreeRoot {', - 'padding: 4px 0;', - '}', - - '.blocklyTreeRoot:focus {', - 'outline: none;', - '}', - - '.blocklyTreeRow {', - 'height: 22px;', - 'line-height: 22px;', - 'margin-bottom: 3px;', - 'padding-right: 8px;', - 'white-space: nowrap;', - '}', - - '.blocklyHorizontalTree {', - 'float: left;', - 'margin: 1px 5px 8px 0;', - '}', - - '.blocklyHorizontalTreeRtl {', - 'float: right;', - 'margin: 1px 0 8px 5px;', - '}', - - '.blocklyToolboxDiv[dir="RTL"] .blocklyTreeRow {', - 'margin-left: 8px;', - '}', - - '.blocklyTreeRow:not(.blocklyTreeSelected):hover {', - 'background-color: #e4e4e4;', - '}', - - '.blocklyTreeSeparator {', - 'border-bottom: solid #e5e5e5 1px;', - 'height: 0;', - 'margin: 5px 0;', - '}', - - '.blocklyTreeSeparatorHorizontal {', - 'border-right: solid #e5e5e5 1px;', - 'width: 0;', - 'padding: 5px 0;', - 'margin: 0 5px;', - '}', - - '.blocklyTreeIcon {', - 'background-image: url(<<>>/sprites.png);', - 'height: 16px;', - 'vertical-align: middle;', - 'width: 16px;', - '}', - - '.blocklyTreeIconClosedLtr {', - 'background-position: -32px -1px;', - '}', - - '.blocklyTreeIconClosedRtl {', - 'background-position: 0px -1px;', - '}', - - '.blocklyTreeIconOpen {', - 'background-position: -16px -1px;', - '}', - - '.blocklyTreeSelected>.blocklyTreeIconClosedLtr {', - 'background-position: -32px -17px;', - '}', - - '.blocklyTreeSelected>.blocklyTreeIconClosedRtl {', - 'background-position: 0px -17px;', - '}', - - '.blocklyTreeSelected>.blocklyTreeIconOpen {', - 'background-position: -16px -17px;', - '}', - - '.blocklyTreeIconNone,', - '.blocklyTreeSelected>.blocklyTreeIconNone {', - 'background-position: -48px -1px;', - '}', - - '.blocklyTreeLabel {', - 'cursor: default;', - 'font-family: "Helvetica Neue", Helvetica, sans-serif;', - 'font-size: 16px;', - 'padding: 0 3px;', - 'vertical-align: middle;', - '}', - - '.blocklyToolboxDelete .blocklyTreeLabel {', - 'cursor: url("<<>>/handdelete.cur"), auto;', - '}', - - '.blocklyTreeSelected .blocklyTreeLabel {', - 'color: #fff;', - '}', - - '.blocklyDropDownDiv .goog-slider-horizontal {', - 'margin: 8px;', - 'height: 22px;', - 'width: 150px;', - 'position: relative;', - 'outline: none;', - 'border-radius: 11px;', - 'margin-bottom: 20px;', - '}', - - '.blocklyDropDownDiv .goog-slider-horizontal .goog-slider-thumb {', - 'width: 26px;', - 'height: 26px;', - 'top: -1px;', - 'position: absolute;', - 'background-color: white;', - 'border-radius: 100%;', - '-webkit-box-shadow: 0 0 0 4px rgba(0, 0, 0, 0.15);', - '-moz-box-shadow: 0 0 0 4px rgba(0, 0, 0, 0.15);', - 'box-shadow: 0 0 0 4px rgba(0, 0, 0, 0.15);', - '}', - - '.scratchEyedropper {', - 'background: none;', - 'outline: none;', - 'border: none;', - 'width: 100%;', - 'text-align: center;', - 'border-top: 1px solid #ddd;', - 'padding-top: 5px;', - 'cursor: pointer;', - '}', - - '.scratchColourPickerLabel {', - 'font-family: "Helvetica Neue", Helvetica, sans-serif;', - 'font-size: 0.65rem;', - 'color: $colour_toolboxText;', - 'margin: 8px;', - '}', - - '.scratchColourPickerLabelText {', - 'font-weight: bold;', - '}', - - '.scratchColourPickerReadout {', - 'margin-left: 10px;', - '}', - - '.scratchMatrixButtonDiv {', - 'width: 50%;', - 'text-align: center;', - 'float: left;', - '}', - - '.scratchNotePickerKeyLabel {', - 'font-family: "Helvetica Neue", Helvetica, sans-serif;', - 'font-size: 0.75rem;', - 'fill: $colour_textFieldText;', - 'pointer-events: none;', - '}', + .blocklyToolboxDiv { + background-color: var(--colour-toolbox); + color: var(--colour-toolboxText); + overflow-x: visible; + overflow-y: auto; + position: absolute; + font-family: "Helvetica Neue", Helvetica, sans-serif; + z-index: 40; /* so blocks go over toolbox when dragging */ + -webkit-tap-highlight-color: transparent; /* issue #1345 */ + padding: 0; + } + + .blocklyTreeRoot { + padding: 4px 0; + } + + .blocklyTreeRoot:focus { + outline: none; + } + + .blocklyTreeRow { + line-height: 22px; + margin: 0; + padding: 0.375rem 0px; + white-space: nowrap; + cursor: pointer; + } + + .blocklyHorizontalTree { + float: left; + margin: 1px 5px 8px 0; + } + + .blocklyHorizontalTreeRtl { + float: right; + margin: 1px 0 8px 5px; + } + + .blocklyToolboxDiv[dir="RTL"] .blocklyTreeRow { + margin-left: 8px; + } + + .blocklyTreeRow:hover { + color: var(--colour-toolboxHover); + } + + .blocklyTreeSeparator { + display: none; + } + + .blocklyTreeSeparatorHorizontal { + border-right: solid #e5e5e5 1px; + width: 0; + padding: 5px 0; + margin: 0 5px; + } + + .blocklyTreeIcon { + background-image: url(<<>>/sprites.png); + height: 16px; + vertical-align: middle; + width: 16px; + } + + .blocklyTreeIconClosedLtr { + background-position: -32px -1px; + } + + .blocklyTreeIconClosedRtl { + background-position: 0px -1px; + } + + .blocklyTreeIconOpen { + background-position: -16px -1px; + } + + .blocklyTreeSelected>.blocklyTreeIconClosedLtr { + background-position: -32px -17px; + } + + .blocklyTreeSelected>.blocklyTreeIconClosedRtl { + background-position: 0px -17px; + } + + .blocklyTreeSelected>.blocklyTreeIconOpen { + background-position: -16px -17px; + } + + .blocklyTreeIconNone, + .blocklyTreeSelected>.blocklyTreeIconNone { + background-position: -48px -1px; + } + + .blocklyTreeLabel { + cursor: default; + font-family: "Helvetica Neue", Helvetica, sans-serif; + font-size: .65rem; + padding: 0 3px; + vertical-align: middle; + width: 60px; + text-align: center; + } + + .blocklyTreeSelected .blocklyTreeLabel { + color: inherit; + } + + .blocklyToolboxDelete .blocklyTreeLabel { + cursor: url("<<>>/handdelete.cur"), auto; + } + + .blocklyTreeSelected { + background-color: var(--colour-toolboxSelected); + } + + .blocklyDropDownDiv .goog-slider-horizontal { + margin: 8px; + height: 22px; + width: 150px; + position: relative; + outline: none; + border-radius: 11px; + margin-bottom: 20px; + } + + .blocklyDropDownDiv .goog-slider-horizontal .goog-slider-thumb { + width: 26px; + height: 26px; + top: -1px; + position: absolute; + background-color: white; + border-radius: 100%; + -webkit-box-shadow: 0 0 0 4px rgba(0, 0, 0, 0.15); + -moz-box-shadow: 0 0 0 4px rgba(0, 0, 0, 0.15); + box-shadow: 0 0 0 4px rgba(0, 0, 0, 0.15); + } + + .scratchEyedropper { + background: none; + outline: none; + border: none; + width: 100%; + text-align: center; + border-top: 1px solid #ddd; + padding-top: 5px; + cursor: pointer; + } + + .scratchColourPickerLabel { + font-family: "Helvetica Neue", Helvetica, sans-serif; + font-size: 0.65rem; + color: var(--colour-toolboxText); + margin: 8px; + } + + .scratchColourPickerLabelText { + font-weight: bold; + } + + .scratchColourPickerReadout { + margin-left: 10px; + } + + .scratchMatrixButtonDiv { + width: 50%; + text-align: center; + float: left; + } + + .scratchNotePickerKeyLabel { + font-family: "Helvetica Neue", Helvetica, sans-serif; + font-size: 0.75rem; + fill: var(--colour-textFieldText); + pointer-events: none; + } /* Copied from: goog/css/menu.css */ /* @@ -1033,28 +930,28 @@ Blockly.Css.CONTENT = [ * @author attila@google.com (Attila Bodis) */ - '.blocklyWidgetDiv .goog-menu {', - 'background: #fff;', - 'border-color: #ccc #666 #666 #ccc;', - 'border-style: solid;', - 'border-width: 1px;', - 'cursor: default;', - 'font: normal 13px "Helvetica Neue", Helvetica, sans-serif;', - 'margin: 0;', - 'outline: none;', - 'padding: 4px 0;', - 'position: absolute;', - 'overflow-y: auto;', - 'overflow-x: hidden;', - 'z-index: 20000;', /* Arbitrary, but some apps depend on it... */ - '}', - - '.blocklyDropDownDiv .goog-menu {', - 'cursor: default;', - 'font: normal 13px "Helvetica Neue", Helvetica, sans-serif;', - 'outline: none;', - 'z-index: 20000;', /* Arbitrary, but some apps depend on it... */ - '}', + .blocklyWidgetDiv .goog-menu { + background: #fff; + border-color: #ccc #666 #666 #ccc; + border-style: solid; + border-width: 1px; + cursor: default; + font: normal 13px "Helvetica Neue", Helvetica, sans-serif; + margin: 0; + outline: none; + padding: 4px 0; + position: absolute; + overflow-y: auto; + overflow-x: hidden; + z-index: 20000; /* Arbitrary, but some apps depend on it... */ + } + + .blocklyDropDownDiv .goog-menu { + cursor: default; + font: normal 13px "Helvetica Neue", Helvetica, sans-serif; + outline: none; + z-index: 20000; /* Arbitrary, but some apps depend on it... */ + } /* Copied from: goog/css/menuitem.css */ /* @@ -1085,165 +982,165 @@ Blockly.Css.CONTENT = [ * on the BiDi flipping by the CSS compiler. That's why we're not adding the * #noflip to .goog-menuitem. */ - '.blocklyWidgetDiv .goog-menuitem {', - 'color: #000;', - 'font: normal 13px "Helvetica Neue", Helvetica, sans-serif;', - 'list-style: none;', - 'margin: 0;', + .blocklyWidgetDiv .goog-menuitem { + color: #000; + font: normal 13px "Helvetica Neue", Helvetica, sans-serif; + list-style: none; + margin: 0; /* 28px on the left for icon or checkbox; 7em on the right for shortcut. */ - 'padding: 4px 7em 4px 28px;', - 'white-space: nowrap;', - '}', - - '.blocklyDropDownDiv .goog-menuitem {', - 'color: $colour_text;', - 'font: normal 13px "Helvetica Neue", Helvetica, sans-serif;', - 'font-weight: bold;', - 'list-style: none;', - 'margin: 0;', - 'min-height: 24px;', + padding: 4px 7em 4px 28px; + white-space: nowrap; + } + + .blocklyDropDownDiv .goog-menuitem { + color: var(--colour-text); + font: normal 13px "Helvetica Neue", Helvetica, sans-serif; + font-weight: bold; + list-style: none; + margin: 0; + min-height: 24px; /* 28px on the left for icon or checkbox; 7em on the right for shortcut. */ - 'padding: 4px 7em 4px 28px;', - 'white-space: nowrap;', - '}', + padding: 4px 7em 4px 28px; + white-space: nowrap; + } /* BiDi override for the resting state. */ /* #noflip */ - '.blocklyWidgetDiv .goog-menuitem.goog-menuitem-rtl, ', - '.blocklyDropDownDiv .goog-menuitem.goog-menuitem-rtl {', + .blocklyWidgetDiv .goog-menuitem.goog-menuitem-rtl, , + .blocklyDropDownDiv .goog-menuitem.goog-menuitem-rtl { /* Flip left/right padding for BiDi. */ - 'padding-left: 7em;', - 'padding-right: 28px;', - '}', + padding-left: 7em; + padding-right: 28px; + } /* If a menu doesn't have checkable items or items with icons, remove padding. */ - '.blocklyWidgetDiv .goog-menu-nocheckbox .goog-menuitem,', - '.blocklyWidgetDiv .goog-menu-noicon .goog-menuitem, ', - '.blocklyDropDownDiv .goog-menu-nocheckbox .goog-menuitem,', - '.blocklyDropDownDiv .goog-menu-noicon .goog-menuitem { ', - 'padding-left: 12px;', - '}', + .blocklyWidgetDiv .goog-menu-nocheckbox .goog-menuitem, + .blocklyWidgetDiv .goog-menu-noicon .goog-menuitem, , + .blocklyDropDownDiv .goog-menu-nocheckbox .goog-menuitem, + .blocklyDropDownDiv .goog-menu-noicon .goog-menuitem { , + padding-left: 12px; + } /* * If a menu doesn't have items with shortcuts, leave just enough room for * submenu arrows, if they are rendered. */ - '.blocklyWidgetDiv .goog-menu-noaccel .goog-menuitem, ', - '.blocklyDropDownDiv .goog-menu-noaccel .goog-menuitem {', - 'padding-right: 20px;', - '}', + .blocklyWidgetDiv .goog-menu-noaccel .goog-menuitem, , + .blocklyDropDownDiv .goog-menu-noaccel .goog-menuitem { + padding-right: 20px; + } - '.blocklyWidgetDiv .goog-menuitem-content ', - '.blocklyDropDownDiv .goog-menuitem-content {', - 'color: #000;', - 'font: normal 13px "Helvetica Neue", Helvetica, sans-serif;', - '}', + .blocklyWidgetDiv .goog-menuitem-content , + .blocklyDropDownDiv .goog-menuitem-content { + color: #000; + font: normal 13px "Helvetica Neue", Helvetica, sans-serif; + } /* State: disabled. */ - '.blocklyWidgetDiv .goog-menuitem-disabled .goog-menuitem-accel,', - '.blocklyWidgetDiv .goog-menuitem-disabled .goog-menuitem-content, ', - '.blocklyDropDownDiv .goog-menuitem-disabled .goog-menuitem-accel,', - '.blocklyDropDownDiv .goog-menuitem-disabled .goog-menuitem-content {', - 'color: #ccc !important;', - '}', - - '.blocklyWidgetDiv .goog-menuitem-disabled .goog-menuitem-icon, ', - '.blocklyDropDownDiv .goog-menuitem-disabled .goog-menuitem-icon {', - 'opacity: 0.3;', - '-moz-opacity: 0.3;', - 'filter: alpha(opacity=30);', - '}', + .blocklyWidgetDiv .goog-menuitem-disabled .goog-menuitem-accel, + .blocklyWidgetDiv .goog-menuitem-disabled .goog-menuitem-content, , + .blocklyDropDownDiv .goog-menuitem-disabled .goog-menuitem-accel, + .blocklyDropDownDiv .goog-menuitem-disabled .goog-menuitem-content { + color: #ccc !important; + } + + .blocklyWidgetDiv .goog-menuitem-disabled .goog-menuitem-icon, , + .blocklyDropDownDiv .goog-menuitem-disabled .goog-menuitem-icon { + opacity: 0.3; + -moz-opacity: 0.3; + filter: alpha(opacity=30); + } /* State: hover. */ - '.blocklyWidgetDiv .goog-menuitem-highlight,', - '.blocklyWidgetDiv .goog-menuitem-hover {', - 'background-color: #d6e9f8;', - /* Use an explicit top and bottom border so that the selection is visible', + .blocklyWidgetDiv .goog-menuitem-highlight, + .blocklyWidgetDiv .goog-menuitem-hover { + background-color: #d6e9f8; + /* Use an explicit top and bottom border so that the selection is visible * in high contrast mode. */ - 'border-color: #d6e9f8;', - 'border-style: dotted;', - 'border-width: 1px 0;', - 'padding-bottom: 3px;', - 'padding-top: 3px;', - '}', - - '.blocklyDropDownDiv .goog-menuitem-highlight,', - '.blocklyDropDownDiv .goog-menuitem-hover {', - 'background-color: $colour_menuHover;', - '}', + border-color: #d6e9f8; + border-style: dotted; + border-width: 1px 0; + padding-bottom: 3px; + padding-top: 3px; + } + + .blocklyDropDownDiv .goog-menuitem-highlight, + .blocklyDropDownDiv .goog-menuitem-hover { + background-color: var(--colour-menuHover); + } /* State: selected/checked. */ - '.blocklyWidgetDiv .goog-menuitem-checkbox,', - '.blocklyWidgetDiv .goog-menuitem-icon, ', - '.blocklyDropDownDiv .goog-menuitem-checkbox,', - '.blocklyDropDownDiv .goog-menuitem-icon {', - 'background-repeat: no-repeat;', - 'height: 16px;', - 'left: 6px;', - 'position: absolute;', - 'right: auto;', - 'vertical-align: middle;', - 'width: 16px;', - '}', - - '.blocklyWidgetDiv .goog-option-selected .goog-menuitem-checkbox,', - '.blocklyWidgetDiv .goog-option-selected .goog-menuitem-icon,', - '.blocklyDropDownDiv .goog-option-selected .goog-menuitem-checkbox,', - '.blocklyDropDownDiv .goog-option-selected .goog-menuitem-icon {', + .blocklyWidgetDiv .goog-menuitem-checkbox, + .blocklyWidgetDiv .goog-menuitem-icon, , + .blocklyDropDownDiv .goog-menuitem-checkbox, + .blocklyDropDownDiv .goog-menuitem-icon { + background-repeat: no-repeat; + height: 16px; + left: 6px; + position: absolute; + right: auto; + vertical-align: middle; + width: 16px; + } + + .blocklyWidgetDiv .goog-option-selected .goog-menuitem-checkbox, + .blocklyWidgetDiv .goog-option-selected .goog-menuitem-icon, + .blocklyDropDownDiv .goog-option-selected .goog-menuitem-checkbox, + .blocklyDropDownDiv .goog-option-selected .goog-menuitem-icon { /* Client apps may override the URL at which they serve the sprite. */ - 'background: url(<<>>/sprites.png) no-repeat -48px -16px !important;', - 'position: static;', /* Scroll with the menu. */ - 'float: left;', - 'margin-left: -24px;', - '}', + background: url(<<>>/sprites.png) no-repeat -48px -16px !important; + position: static; /* Scroll with the menu. */ + float: left; + margin-left: -24px; + } /* BiDi override for the selected/checked state. */ /* #noflip */ - '.blocklyWidgetDiv .goog-menuitem-rtl .goog-menuitem-checkbox,', - '.blocklyWidgetDiv .goog-menuitem-rtl .goog-menuitem-icon,', - '.blocklyDropDownDiv .goog-menuitem-rtl .goog-menuitem-checkbox,', - '.blocklyDropDownDiv .goog-menuitem-rtl .goog-menuitem-icon {', + .blocklyWidgetDiv .goog-menuitem-rtl .goog-menuitem-checkbox, + .blocklyWidgetDiv .goog-menuitem-rtl .goog-menuitem-icon, + .blocklyDropDownDiv .goog-menuitem-rtl .goog-menuitem-checkbox, + .blocklyDropDownDiv .goog-menuitem-rtl .goog-menuitem-icon { /* Flip left/right positioning. */ - 'float: right;', - 'margin-right: -24px;', - '}', + float: right; + margin-right: -24px; + } /* Keyboard shortcut ("accelerator") style. */ - '.blocklyWidgetDiv .goog-menuitem-accel, ', - '.blocklyDropDownDiv .goog-menuitem-accel {', - 'color: #999;', + .blocklyWidgetDiv .goog-menuitem-accel, , + .blocklyDropDownDiv .goog-menuitem-accel { + color: #999; /* Keyboard shortcuts are untranslated; always left-to-right. */ /* #noflip */ - 'direction: ltr;', - 'left: auto;', - 'padding: 0 6px;', - 'position: absolute;', - 'right: 0;', - 'text-align: right;', - '}', + direction: ltr; + left: auto; + padding: 0 6px; + position: absolute; + right: 0; + text-align: right; + } /* BiDi override for shortcut style. */ /* #noflip */ - '.blocklyWidgetDiv .goog-menuitem-rtl .goog-menuitem-accel, ', - '.blocklyDropDownDiv .goog-menuitem-rtl .goog-menuitem-accel {', + .blocklyWidgetDiv .goog-menuitem-rtl .goog-menuitem-accel, , + .blocklyDropDownDiv .goog-menuitem-rtl .goog-menuitem-accel { /* Flip left/right positioning and text alignment. */ - 'left: 0;', - 'right: auto;', - 'text-align: left;', - '}', + left: 0; + right: auto; + text-align: left; + } /* Mnemonic styles. */ - '.blocklyWidgetDiv .goog-menuitem-mnemonic-hint, ', - '.blocklyDropDownDiv .goog-menuitem-mnemonic-hint {', - 'text-decoration: underline;', - '}', - - '.blocklyWidgetDiv .goog-menuitem-mnemonic-separator, ', - '.blocklyDropDownDiv .goog-menuitem-mnemonic-separator {', - 'color: #999;', - 'font-size: 12px;', - 'padding-left: 4px;', - '}', + .blocklyWidgetDiv .goog-menuitem-mnemonic-hint, , + .blocklyDropDownDiv .goog-menuitem-mnemonic-hint { + text-decoration: underline; + } + + .blocklyWidgetDiv .goog-menuitem-mnemonic-separator, , + .blocklyDropDownDiv .goog-menuitem-mnemonic-separator { + color: #999; + font-size: 12px; + padding-left: 4px; + } /* Copied from: goog/css/menuseparator.css */ /* @@ -1259,93 +1156,94 @@ Blockly.Css.CONTENT = [ * @author attila@google.com (Attila Bodis) */ - '.blocklyWidgetDiv .goog-menuseparator, ', - '.blocklyDropDownDiv .goog-menuseparator {', - 'border-top: 1px solid #ccc;', - 'margin: 4px 0;', - 'padding: 0;', - '}', - - '.blocklyFlyoutCheckbox {', - 'fill: white;', - 'stroke: #c8c8c8;', - '}', - - '.checked > .blocklyFlyoutCheckbox {', - 'fill: ' + Blockly.Colours.motion.primary + ';', - 'stroke: ' + Blockly.Colours.motion.tertiary + ';', - '}', - - '.blocklyFlyoutCheckboxPath {', - 'fill: transparent;', - 'stroke: white;', - 'stroke-width: 3;', - 'stroke-linecap: round;', - 'stroke-linejoin: round;', - '}', - - '.scratchCategoryMenu {', - 'width: 60px;', - 'background: $colour_toolbox;', - 'color: $colour_toolboxText;', - 'font-size: .7rem;', - 'user-select: none;', - '-webkit-user-select: none;', - '-moz-user-select: none;', - '-ms-user-select: none;', - '}', - - '.scratchCategoryMenuHorizontal {', - 'width: 100%;', - 'height: 50px;', - 'background: $colour_toolbox;', - 'color: $colour_toolboxText;', - 'font-size: .7em;', - 'user-select: none;', - '-webkit-user-select: none;', - '-moz-user-select: none;', - '-ms-user-select: none;', - '}', - - '.scratchCategoryMenuHorizontal .scratchCategoryMenuRow {', - 'float: left;', - 'margin: 3px;', - '}', - - '.scratchCategoryMenuRow {', - '}', - - '.scratchCategoryMenuItem {', - 'padding: 0.375rem 0px;', - 'cursor: pointer;', - 'text-align: center;', - '}', - - '.scratchCategoryMenuHorizontal .scratchCategoryMenuItem {', - 'padding: 6px 5px;', - '}', - - '.scratchCategoryMenuItem.categorySelected {', - 'background: $colour_toolboxSelected;', - '}', - - '.scratchCategoryItemBubble {', - 'width: 1.25rem;', - 'height: 1.25rem;', - 'border: 1px solid;', - 'border-radius: 100%;', - 'margin: 0 auto 0.125rem;', - '}', - - '.scratchCategoryItemIcon {', - 'width: 1.25rem;', - 'height: 1.25rem;', - 'margin: 0 auto 0.125rem;', - 'background-size: 100%;', - '}', - - '.scratchCategoryMenuItem:hover {', - 'color: $colour_toolboxHover !important;', - '}', - '' -]; + .blocklyWidgetDiv .goog-menuseparator, , + .blocklyDropDownDiv .goog-menuseparator { + border-top: 1px solid #ccc; + margin: 4px 0; + padding: 0; + } + + .blocklyFlyoutCheckbox { + fill: white; + stroke: #c8c8c8; + } + + .checked > .blocklyFlyoutCheckbox { + fill: var(--colour-motion-primary); + stroke: var(--colour-motion-tertiary); + } + + .blocklyFlyoutCheckboxPath { + fill: transparent; + stroke: white; + stroke-width: 3; + stroke-linecap: round; + stroke-linejoin: round; + } + + .scratchCategoryMenu { + width: 60px; + background: var(--colour-toolbox); + color: var(--colour-toolboxText); + font-size: .7rem; + user-select: none; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + } + + .scratchCategoryMenuHorizontal { + width: 100%; + height: 50px; + background: var(--colour-toolbox); + color: var(--colour-toolboxText); + font-size: .7em; + user-select: none; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + } + + .scratchCategoryMenuHorizontal .scratchCategoryMenuRow { + float: left; + margin: 3px; + } + + .scratchCategoryMenuRow { + } + + .scratchCategoryMenuItem { + padding: 0.375rem 0px; + cursor: pointer; + text-align: center; + } + + .scratchCategoryMenuHorizontal .scratchCategoryMenuItem { + padding: 6px 5px; + } + + .scratchCategoryMenuItem.categorySelected { + background: var(--colour-toolboxSelected); + } + + .scratchCategoryItemBubble { + width: 1.25rem; + height: 1.25rem; + border: 1px solid; + border-radius: 100%; + margin: 0 auto 0.125rem; + } + + .scratchCategoryItemIcon { + width: 1.25rem; + height: 1.25rem; + margin: 0 auto 0.125rem; + background-size: 100%; + } + + .scratchCategoryMenuItem:hover { + color: $colour_toolboxHover !important; + } +`; + +Blockly.Css.register(styles); diff --git a/src/index.js b/src/index.js index bd0320177a..b51d0a97e2 100644 --- a/src/index.js +++ b/src/index.js @@ -16,6 +16,7 @@ import '../blocks_vertical/operators.js'; import '../blocks_vertical/sensing.js'; import '../blocks_vertical/sound.js'; import * as scratchBlocksUtils from '../core/scratch_blocks_utils.js'; +import '../core/css.js'; import { ContinuousToolbox, ContinuousFlyout, @@ -38,4 +39,6 @@ export function inject(container, options) { }); const workspace = Blockly.inject(container, options); return workspace; -} \ No newline at end of file +} + +Blockly.Scrollbar.scrollbarThickness = Blockly.Touch.TOUCH_ENABLED ? 14 : 11; From c548298f3b9cf6baa0c27fdb54b5336538d4abf0 Mon Sep 17 00:00:00 2001 From: Aaron Dodson Date: Mon, 22 Apr 2024 15:01:18 -0700 Subject: [PATCH 019/130] fix: hide disable and inline inputs contextual menu items (#35) --- src/index.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/index.js b/src/index.js index b51d0a97e2..62f8b7ab2e 100644 --- a/src/index.js +++ b/src/index.js @@ -42,3 +42,5 @@ export function inject(container, options) { } Blockly.Scrollbar.scrollbarThickness = Blockly.Touch.TOUCH_ENABLED ? 14 : 11; +Blockly.ContextMenuRegistry.registry.unregister('blockDisable'); +Blockly.ContextMenuRegistry.registry.unregister('blockInline'); From 6bbbdf763ba43d3dc0af7bad15478f848455f4df Mon Sep 17 00:00:00 2001 From: Aaron Dodson Date: Mon, 22 Apr 2024 15:49:50 -0700 Subject: [PATCH 020/130] fix: use Scratch-style text blocks (#37) --- blocks_common/text.js | 20 ++++++-------------- src/index.js | 1 + 2 files changed, 7 insertions(+), 14 deletions(-) diff --git a/blocks_common/text.js b/blocks_common/text.js index 484475d642..aa66f2059b 100644 --- a/blocks_common/text.js +++ b/blocks_common/text.js @@ -22,15 +22,8 @@ * @fileoverview Text blocks for Blockly. * @author fraser@google.com (Neil Fraser) */ -'use strict'; - -goog.provide('Blockly.Blocks.texts'); - -goog.require('Blockly.Blocks'); - -goog.require('Blockly.Colours'); - -goog.require('Blockly.constants'); +import * as Blockly from 'blockly'; +import {Colours} from '../core/colours.js'; Blockly.Blocks['text'] = { /** @@ -47,11 +40,10 @@ Blockly.Blocks['text'] = { } ], "output": "String", - "outputShape": Blockly.OUTPUT_SHAPE_ROUND, - "colour": Blockly.Colours.textField, - "colourSecondary": Blockly.Colours.textField, - "colourTertiary": Blockly.Colours.textField, - "colourQuaternary": Blockly.Colours.textField + "colour": Colours.textField, + "colourSecondary": Colours.textField, + "colourTertiary": Colours.textField, + "colourQuaternary": Colours.textField }); } }; diff --git a/src/index.js b/src/index.js index 62f8b7ab2e..ac7110eebc 100644 --- a/src/index.js +++ b/src/index.js @@ -6,6 +6,7 @@ import * as Blockly from 'blockly/core'; import '../blocks_common/math.js'; +import '../blocks_common/text.js'; import '../blocks_vertical/vertical_extensions.js'; import '../blocks_vertical/control.js'; import '../blocks_vertical/data.js'; From 7f70f09e11972be8a6ee512323a0a39a52ef0452 Mon Sep 17 00:00:00 2001 From: Aaron Dodson Date: Tue, 23 Apr 2024 09:45:06 -0700 Subject: [PATCH 021/130] fix: don't hide the drag surface (#38) --- core/css.js | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/core/css.js b/core/css.js index f7b608451c..dbbde9f5e8 100644 --- a/core/css.js +++ b/core/css.js @@ -103,17 +103,6 @@ const styles = ` overflow: visible; } - .blocklyBlockDragSurface { - display: none; - position: absolute; - top: 0; - left: 0; - right: 0; - bottom: 0; - overflow: visible !important; - z-index: 50; /* Display above the toolbox */ - } - .blocklyTooltipDiv { background-color: #ffffc7; border: 1px solid #ddc; From 13647eb36439926e82cbe847a643f592702690ab Mon Sep 17 00:00:00 2001 From: Aaron Dodson Date: Wed, 24 Apr 2024 11:33:09 -0700 Subject: [PATCH 022/130] fix: add support for Scratch-style procedures (#39) * refactor: move procedures.js into src * fix: add support for Scratch-style procedures * chore: remove errant logging * refactor: remove underscore from exported callback attribute --- blocks_vertical/procedures.js | 306 ++++++++++++------------ blocks_vertical/vertical_extensions.js | 7 +- core/field_textinput_removable.js | 107 ++++----- src/constants.js | 21 ++ src/index.js | 2 + {core => src}/procedures.js | 315 ++++++------------------- 6 files changed, 293 insertions(+), 465 deletions(-) rename {core => src}/procedures.js (54%) diff --git a/blocks_vertical/procedures.js b/blocks_vertical/procedures.js index 1d2d2153a6..941acb8d5e 100644 --- a/blocks_vertical/procedures.js +++ b/blocks_vertical/procedures.js @@ -21,14 +21,10 @@ /** * @fileoverview Procedure blocks for Scratch. */ -'use strict'; -goog.provide('Blockly.ScratchBlocks.ProcedureUtils'); - -goog.require('Blockly.Blocks'); -goog.require('Blockly.Colours'); -goog.require('Blockly.constants'); -goog.require('Blockly.ScratchBlocks.VerticalExtensions'); +import * as Blockly from 'blockly/core'; +import {Colours} from '../core/colours.js'; +import {FieldTextInputRemovable} from '../core/field_textinput_removable.js'; // Serialization and deserialization. @@ -38,13 +34,13 @@ goog.require('Blockly.ScratchBlocks.VerticalExtensions'); * @return {!Element} XML storage element. * @this Blockly.Block */ -Blockly.ScratchBlocks.ProcedureUtils.callerMutationToDom = function() { +function callerMutationToDom() { var container = document.createElement('mutation'); container.setAttribute('proccode', this.procCode_); container.setAttribute('argumentids', JSON.stringify(this.argumentIds_)); container.setAttribute('warp', JSON.stringify(this.warp_)); return container; -}; +} /** * Parse XML to restore the (non-editable) name and arguments of a procedure @@ -52,14 +48,14 @@ Blockly.ScratchBlocks.ProcedureUtils.callerMutationToDom = function() { * @param {!Element} xmlElement XML storage element. * @this Blockly.Block */ -Blockly.ScratchBlocks.ProcedureUtils.callerDomToMutation = function(xmlElement) { +function callerDomToMutation(xmlElement) { this.procCode_ = xmlElement.getAttribute('proccode'); this.generateShadows_ = JSON.parse(xmlElement.getAttribute('generateshadows')); this.argumentIds_ = JSON.parse(xmlElement.getAttribute('argumentids')); this.warp_ = JSON.parse(xmlElement.getAttribute('warp')); this.updateDisplay_(); -}; +} /** * Create XML to represent the (non-editable) name and arguments of a @@ -69,7 +65,7 @@ Blockly.ScratchBlocks.ProcedureUtils.callerDomToMutation = function(xmlElement) * @return {!Element} XML storage element. * @this Blockly.Block */ -Blockly.ScratchBlocks.ProcedureUtils.definitionMutationToDom = function( +function definitionMutationToDom( opt_generateShadows) { var container = document.createElement('mutation'); @@ -83,7 +79,7 @@ Blockly.ScratchBlocks.ProcedureUtils.definitionMutationToDom = function( JSON.stringify(this.argumentDefaults_)); container.setAttribute('warp', JSON.stringify(this.warp_)); return container; -}; +} /** * Parse XML to restore the (non-editable) name and arguments of a @@ -91,7 +87,7 @@ Blockly.ScratchBlocks.ProcedureUtils.definitionMutationToDom = function( * @param {!Element} xmlElement XML storage element. * @this Blockly.Block */ -Blockly.ScratchBlocks.ProcedureUtils.definitionDomToMutation = function(xmlElement) { +function definitionDomToMutation(xmlElement) { this.procCode_ = xmlElement.getAttribute('proccode'); this.warp_ = JSON.parse(xmlElement.getAttribute('warp')); @@ -106,7 +102,7 @@ Blockly.ScratchBlocks.ProcedureUtils.definitionDomToMutation = function(xmlEleme if (this.updateArgumentReporterNames_) { this.updateArgumentReporterNames_(prevArgIds, prevDisplayNames); } -}; +} // End of serialization and deserialization. @@ -118,9 +114,9 @@ Blockly.ScratchBlocks.ProcedureUtils.definitionDomToMutation = function(xmlEleme * @return {string} Procedure name. * @this Blockly.Block */ -Blockly.ScratchBlocks.ProcedureUtils.getProcCode = function() { +function getProcCode() { return this.procCode_; -}; +} /** * Update the block's structure and appearance to match the internally stored @@ -128,7 +124,7 @@ Blockly.ScratchBlocks.ProcedureUtils.getProcCode = function() { * @private * @this Blockly.Block */ -Blockly.ScratchBlocks.ProcedureUtils.updateDisplay_ = function() { +function updateDisplay_() { var wasRendered = this.rendered; this.rendered = false; @@ -143,7 +139,7 @@ Blockly.ScratchBlocks.ProcedureUtils.updateDisplay_ = function() { this.initSvg(); this.render(); } -}; +} /** * Disconnect old blocks from all value inputs on this block, but hold onto them @@ -155,7 +151,7 @@ Blockly.ScratchBlocks.ProcedureUtils.updateDisplay_ = function() { * @private * @this Blockly.Block */ -Blockly.ScratchBlocks.ProcedureUtils.disconnectOldBlocks_ = function() { +function disconnectOldBlocks_() { // Remove old stuff var connectionMap = {}; for (var i = 0, input; input = this.inputList[i]; i++) { @@ -167,17 +163,13 @@ Blockly.ScratchBlocks.ProcedureUtils.disconnectOldBlocks_ = function() { }; connectionMap[input.name] = saveInfo; - // Remove the shadow DOM, then disconnect the block. Otherwise a shadow - // block will respawn instantly, and we'd have to remove it when we remove - // the input. - input.connection.setShadowDom(null); if (target) { input.connection.disconnect(); } } } return connectionMap; -}; +} /** * Remove all inputs on the block, including dummy inputs. @@ -185,14 +177,14 @@ Blockly.ScratchBlocks.ProcedureUtils.disconnectOldBlocks_ = function() { * @private * @this Blockly.Block */ -Blockly.ScratchBlocks.ProcedureUtils.removeAllInputs_ = function() { +function removeAllInputs_() { // Delete inputs directly instead of with block.removeInput to avoid splicing // out of the input list at every index. for (var i = 0, input; input = this.inputList[i]; i++) { input.dispose(); } this.inputList = []; -}; +} /** * Create all inputs specified by the new procCode, and populate them with @@ -202,7 +194,7 @@ Blockly.ScratchBlocks.ProcedureUtils.removeAllInputs_ = function() { * @private * @this Blockly.Block */ -Blockly.ScratchBlocks.ProcedureUtils.createAllInputs_ = function(connectionMap) { +function createAllInputs_(connectionMap) { // Split the proc into components, by %n, %b, and %s (ignoring escaped). var procComponents = this.procCode_.split(/(?=[^\\]%[nbs])/); procComponents = procComponents.map(function(c) { @@ -234,7 +226,7 @@ Blockly.ScratchBlocks.ProcedureUtils.createAllInputs_ = function(connectionMap) } this.addProcedureLabel_(labelText.replace(/\\%/, '%')); } -}; +} /** * Delete all shadow blocks in the given map. @@ -244,7 +236,7 @@ Blockly.ScratchBlocks.ProcedureUtils.createAllInputs_ = function(connectionMap) * @private * @this Blockly.Block */ -Blockly.ScratchBlocks.ProcedureUtils.deleteShadows_ = function(connectionMap) { +function deleteShadows_(connectionMap) { // Get rid of all of the old shadow blocks if they aren't connected. if (connectionMap) { for (var id in connectionMap) { @@ -260,7 +252,7 @@ Blockly.ScratchBlocks.ProcedureUtils.deleteShadows_ = function(connectionMap) { } } } -}; +} // End of shared code. /** @@ -269,9 +261,9 @@ Blockly.ScratchBlocks.ProcedureUtils.deleteShadows_ = function(connectionMap) { * @param {string} text The label text. * @private */ -Blockly.ScratchBlocks.ProcedureUtils.addLabelField_ = function(text) { +function addLabelField_(text) { this.appendDummyInput().appendField(text); -}; +} /** * Add a label editor with the given text to a procedures_declaration @@ -280,12 +272,12 @@ Blockly.ScratchBlocks.ProcedureUtils.addLabelField_ = function(text) { * @param {string} text The label text. * @private */ -Blockly.ScratchBlocks.ProcedureUtils.addLabelEditor_ = function(text) { +function addLabelEditor_(text) { if (text) { - this.appendDummyInput(Blockly.utils.genUid()). - appendField(new Blockly.FieldTextInputRemovable(text)); + this.appendDummyInput(Blockly.utils.idGenerator.genUid()). + appendField(new FieldTextInputRemovable(text)); } -}; +} /** * Build a DOM node representing a shadow block of the given type. @@ -294,7 +286,7 @@ Blockly.ScratchBlocks.ProcedureUtils.addLabelEditor_ = function(text) { * @private * @this Blockly.Block */ -Blockly.ScratchBlocks.ProcedureUtils.buildShadowDom_ = function(type) { +function buildShadowDom_(type) { var shadowDom = goog.dom.createDom('shadow'); if (type == 'n') { var shadowType = 'math_number'; @@ -310,7 +302,7 @@ Blockly.ScratchBlocks.ProcedureUtils.buildShadowDom_ = function(type) { fieldDom.setAttribute('name', fieldName); shadowDom.appendChild(fieldDom); return shadowDom; -}; +} /** * Create a new shadow block and attach it to the given input. @@ -320,7 +312,7 @@ Blockly.ScratchBlocks.ProcedureUtils.buildShadowDom_ = function(type) { * @private * @this Blockly.Block */ -Blockly.ScratchBlocks.ProcedureUtils.attachShadow_ = function(input, +function attachShadow_(input, argumentType) { if (argumentType == 'n' || argumentType == 's') { var blockType = argumentType == 'n' ? 'math_number' : 'text'; @@ -341,11 +333,11 @@ Blockly.ScratchBlocks.ProcedureUtils.attachShadow_ = function(input, Blockly.Events.enable(); } if (Blockly.Events.isEnabled()) { - Blockly.Events.fire(new Blockly.Events.BlockCreate(newBlock)); + Blockly.Events.fire(new (Blockly.Events.get(Blockly.Events.BLOCK_CREATE))(newBlock)); } newBlock.outputConnection.connect(input.connection); } -}; +} /** * Create a new argument reporter block. @@ -357,7 +349,7 @@ Blockly.ScratchBlocks.ProcedureUtils.attachShadow_ = function(input, * @private * @this Blockly.Block */ -Blockly.ScratchBlocks.ProcedureUtils.createArgumentReporter_ = function( +function createArgumentReporter_( argumentType, displayName) { if (argumentType == 'n' || argumentType == 's') { var blockType = 'argument_reporter_string_number'; @@ -377,10 +369,10 @@ Blockly.ScratchBlocks.ProcedureUtils.createArgumentReporter_ = function( Blockly.Events.enable(); } if (Blockly.Events.isEnabled()) { - Blockly.Events.fire(new Blockly.Events.BlockCreate(newBlock)); + Blockly.Events.fire(new (Blockly.Events.get(Blockly.Events.BLOCK_CREATE))(newBlock)); } return newBlock; -}; +} /** * Populate the argument by attaching the correct child block or shadow to the @@ -394,7 +386,7 @@ Blockly.ScratchBlocks.ProcedureUtils.createArgumentReporter_ = function( * @private * @this Blockly.Block */ -Blockly.ScratchBlocks.ProcedureUtils.populateArgumentOnCaller_ = function(type, +function populateArgumentOnCaller_(type, index, connectionMap, id, input) { var oldBlock = null; var oldShadow = null; @@ -416,7 +408,7 @@ Blockly.ScratchBlocks.ProcedureUtils.populateArgumentOnCaller_ = function(type, } else if (this.generateShadows_) { this.attachShadow_(input, type); } -}; +} /** * Populate the argument by attaching the correct argument reporter to the given @@ -431,7 +423,7 @@ Blockly.ScratchBlocks.ProcedureUtils.populateArgumentOnCaller_ = function(type, * @private * @this Blockly.Block */ -Blockly.ScratchBlocks.ProcedureUtils.populateArgumentOnPrototype_ = function( +function populateArgumentOnPrototype_( type, index, connectionMap, id, input) { var oldBlock = null; if (connectionMap && (id in connectionMap)) { @@ -439,8 +431,7 @@ Blockly.ScratchBlocks.ProcedureUtils.populateArgumentOnPrototype_ = function( oldBlock = saveInfo['block']; } - var oldTypeMatches = - Blockly.ScratchBlocks.ProcedureUtils.checkOldTypeMatches_(oldBlock, type); + var oldTypeMatches = checkOldTypeMatches_(oldBlock, type); var displayName = this.displayNames_[index]; // Decide which block to attach. @@ -456,7 +447,7 @@ Blockly.ScratchBlocks.ProcedureUtils.populateArgumentOnPrototype_ = function( // Attach the block. input.connection.connect(argumentReporter.outputConnection); -}; +} /** * Populate the argument by attaching the correct argument editor to the given @@ -471,7 +462,7 @@ Blockly.ScratchBlocks.ProcedureUtils.populateArgumentOnPrototype_ = function( * @private * @this Blockly.Block */ -Blockly.ScratchBlocks.ProcedureUtils.populateArgumentOnDeclaration_ = function( +function populateArgumentOnDeclaration_( type, index, connectionMap, id, input) { var oldBlock = null; @@ -483,8 +474,7 @@ Blockly.ScratchBlocks.ProcedureUtils.populateArgumentOnDeclaration_ = function( // TODO: This always returns false, because it checks for argument reporter // blocks instead of argument editor blocks. Create a new version for argument // editors. - var oldTypeMatches = - Blockly.ScratchBlocks.ProcedureUtils.checkOldTypeMatches_(oldBlock, type); + var oldTypeMatches = checkOldTypeMatches_(oldBlock, type); var displayName = this.displayNames_[index]; // Decide which block to attach. @@ -498,7 +488,7 @@ Blockly.ScratchBlocks.ProcedureUtils.populateArgumentOnDeclaration_ = function( // Attach the block. input.connection.connect(argumentEditor.outputConnection); -}; +} /** * Check whether the type of the old block corresponds to the given argument @@ -507,7 +497,7 @@ Blockly.ScratchBlocks.ProcedureUtils.populateArgumentOnDeclaration_ = function( * @param {string} type The argument type. One of 'n', 'n', or 's'. * @return {boolean} True if the type matches, false otherwise. */ -Blockly.ScratchBlocks.ProcedureUtils.checkOldTypeMatches_ = function(oldBlock, +function checkOldTypeMatches_(oldBlock, type) { if (!oldBlock) { return false; @@ -520,7 +510,7 @@ Blockly.ScratchBlocks.ProcedureUtils.checkOldTypeMatches_ = function(oldBlock, return true; } return false; -}; +} /** * Create an argument editor. @@ -534,7 +524,7 @@ Blockly.ScratchBlocks.ProcedureUtils.checkOldTypeMatches_ = function(oldBlock, * @private * @this Blockly.Block */ -Blockly.ScratchBlocks.ProcedureUtils.createArgumentEditor_ = function( +function createArgumentEditor_( argumentType, displayName) { Blockly.Events.disable(); try { @@ -547,22 +537,22 @@ Blockly.ScratchBlocks.ProcedureUtils.createArgumentEditor_ = function( newBlock.setShadow(true); if (!this.isInsertionMarker()) { newBlock.initSvg(); - newBlock.render(false); + newBlock.queueRender(); } } finally { Blockly.Events.enable(); } if (Blockly.Events.isEnabled()) { - Blockly.Events.fire(new Blockly.Events.BlockCreate(newBlock)); + Blockly.Events.fire(new (Blockly.Events.get(Blockly.Events.BLOCK_CREATE))(newBlock)); } return newBlock; -}; +} /** * Update the serializable information on the block based on the existing inputs * and their text. */ -Blockly.ScratchBlocks.ProcedureUtils.updateDeclarationProcCode_ = function() { +function updateDeclarationProcCode_() { this.procCode_ = ''; this.displayNames_ = []; this.argumentIds_ = []; @@ -588,13 +578,13 @@ Blockly.ScratchBlocks.ProcedureUtils.updateDeclarationProcCode_ = function() { 'Unexpected input type on a procedure mutator root: ' + input.type); } } -}; +} /** * Focus on the last argument editor or label editor on the block. * @private */ -Blockly.ScratchBlocks.ProcedureUtils.focusLastEditor_ = function() { +function focusLastEditor_() { if (this.inputList.length > 0) { var newInput = this.inputList[this.inputList.length - 1]; if (newInput.type == Blockly.DUMMY_INPUT) { @@ -605,73 +595,73 @@ Blockly.ScratchBlocks.ProcedureUtils.focusLastEditor_ = function() { target.getField('TEXT').showEditor_(); } } -}; +} /** * Externally-visible function to add a label to the procedure declaration. * @public */ -Blockly.ScratchBlocks.ProcedureUtils.addLabelExternal = function() { +function addLabelExternal() { Blockly.WidgetDiv.hide(true); this.procCode_ = this.procCode_ + ' label text'; this.updateDisplay_(); this.focusLastEditor_(); -}; +} /** * Externally-visible function to add a boolean argument to the procedure * declaration. * @public */ -Blockly.ScratchBlocks.ProcedureUtils.addBooleanExternal = function() { +function addBooleanExternal() { Blockly.WidgetDiv.hide(true); this.procCode_ = this.procCode_ + ' %b'; this.displayNames_.push('boolean'); - this.argumentIds_.push(Blockly.utils.genUid()); + this.argumentIds_.push(Blockly.utils.idGenerator.genUid()); this.argumentDefaults_.push('false'); this.updateDisplay_(); this.focusLastEditor_(); -}; +} /** * Externally-visible function to add a string/number argument to the procedure * declaration. * @public */ -Blockly.ScratchBlocks.ProcedureUtils.addStringNumberExternal = function() { +function addStringNumberExternal() { Blockly.WidgetDiv.hide(true); this.procCode_ = this.procCode_ + ' %s'; this.displayNames_.push('number or text'); - this.argumentIds_.push(Blockly.utils.genUid()); + this.argumentIds_.push(Blockly.utils.idGenerator.genUid()); this.argumentDefaults_.push(''); this.updateDisplay_(); this.focusLastEditor_(); -}; +} /** * Externally-visible function to get the warp on procedure declaration. * @return {boolean} The value of the warp_ property. * @public */ -Blockly.ScratchBlocks.ProcedureUtils.getWarp = function() { +function getWarp() { return this.warp_; -}; +} /** * Externally-visible function to set the warp on procedure declaration. * @param {boolean} warp The value of the warp_ property. * @public */ -Blockly.ScratchBlocks.ProcedureUtils.setWarp = function(warp) { +function setWarp(warp) { this.warp_ = warp; -}; +} /** * Callback to remove a field, only for the declaration block. * @param {Blockly.Field} field The field being removed. * @public */ -Blockly.ScratchBlocks.ProcedureUtils.removeFieldCallback = function(field) { +function removeFieldCallback(field) { // Do not delete if there is only one input if (this.inputList.length === 1) { return; @@ -681,7 +671,7 @@ Blockly.ScratchBlocks.ProcedureUtils.removeFieldCallback = function(field) { var input = this.inputList[n]; if (input.connection) { var target = input.connection.targetBlock(); - if (target.getField(field.name) == field) { + if (field.name && target.getField(field.name) == field) { inputNameToRemove = input.name; } } else { @@ -698,19 +688,19 @@ Blockly.ScratchBlocks.ProcedureUtils.removeFieldCallback = function(field) { this.onChangeFn(); this.updateDisplay_(); } -}; +} /** * Callback to pass removeField up to the declaration block from arguments. * @param {Blockly.Field} field The field being removed. * @public */ -Blockly.ScratchBlocks.ProcedureUtils.removeArgumentCallback_ = function( +function removeArgumentCallback_( field) { if (this.parentBlock_ && this.parentBlock_.removeFieldCallback) { this.parentBlock_.removeFieldCallback(field); } -}; +} /** * Update argument reporter field values after an edit to the prototype mutation @@ -725,7 +715,7 @@ Blockly.ScratchBlocks.ProcedureUtils.removeArgumentCallback_ = function( * @param {!Array} prevDisplayNames The previous argument names. * @this Blockly.Block */ -Blockly.ScratchBlocks.ProcedureUtils.updateArgumentReporterNames_ = function(prevArgIds, prevDisplayNames) { +function updateArgumentReporterNames_(prevArgIds, prevDisplayNames) { var nameChanges = []; var argReporters = []; var definitionBlock = this.getParent(); @@ -766,7 +756,7 @@ Blockly.ScratchBlocks.ProcedureUtils.updateArgumentReporterNames_ = function(pre block.setFieldValue(nameChange.newName, 'VALUE'); } } -}; +} Blockly.Blocks['procedures_definition'] = { /** @@ -799,24 +789,25 @@ Blockly.Blocks['procedures_call'] = { this.procCode_ = ''; this.argumentIds_ = []; this.warp_ = false; + + // Shared. + this.getProcCode = getProcCode.bind(this); + this.removeAllInputs_ = removeAllInputs_.bind(this); + this.disconnectOldBlocks_ = disconnectOldBlocks_.bind(this); + this.deleteShadows_ = deleteShadows_.bind(this); + this.createAllInputs_ = createAllInputs_.bind(this); + this.updateDisplay_ = updateDisplay_.bind(this); + + // Exist on all three blocks, but have different implementations. + this.mutationToDom = callerMutationToDom.bind(this); + this.domToMutation = callerDomToMutation.bind(this); + this.populateArgument_ = populateArgumentOnCaller_.bind(this); + this.addProcedureLabel_ = addLabelField_.bind(this); + + // Only exists on the external caller. + this.attachShadow_ = attachShadow_.bind(this); + this.buildShadowDom_ = buildShadowDom_.bind(this); }, - // Shared. - getProcCode: Blockly.ScratchBlocks.ProcedureUtils.getProcCode, - removeAllInputs_: Blockly.ScratchBlocks.ProcedureUtils.removeAllInputs_, - disconnectOldBlocks_: Blockly.ScratchBlocks.ProcedureUtils.disconnectOldBlocks_, - deleteShadows_: Blockly.ScratchBlocks.ProcedureUtils.deleteShadows_, - createAllInputs_: Blockly.ScratchBlocks.ProcedureUtils.createAllInputs_, - updateDisplay_: Blockly.ScratchBlocks.ProcedureUtils.updateDisplay_, - - // Exist on all three blocks, but have different implementations. - mutationToDom: Blockly.ScratchBlocks.ProcedureUtils.callerMutationToDom, - domToMutation: Blockly.ScratchBlocks.ProcedureUtils.callerDomToMutation, - populateArgument_: Blockly.ScratchBlocks.ProcedureUtils.populateArgumentOnCaller_, - addProcedureLabel_: Blockly.ScratchBlocks.ProcedureUtils.addLabelField_, - - // Only exists on the external caller. - attachShadow_: Blockly.ScratchBlocks.ProcedureUtils.attachShadow_, - buildShadowDom_: Blockly.ScratchBlocks.ProcedureUtils.buildShadowDom_ }; Blockly.Blocks['procedures_prototype'] = { @@ -836,24 +827,24 @@ Blockly.Blocks['procedures_prototype'] = { this.argumentIds_ = []; this.argumentDefaults_ = []; this.warp_ = false; + + // Shared. + this.getProcCode = getProcCode.bind(this); + this.removeAllInputs_ = removeAllInputs_.bind(this); + this.disconnectOldBlocks_ = disconnectOldBlocks_.bind(this); + this.deleteShadows_ = deleteShadows_.bind(this); + this.createAllInputs_ = createAllInputs_.bind(this); + this.updateDisplay_ = updateDisplay_.bind(this); + // Exist on all three blocks, but have different implementations. + this.mutationToDom = definitionMutationToDom.bind(this); + this.domToMutation = definitionDomToMutation.bind(this); + this.populateArgument_ = populateArgumentOnPrototype_.bind(this); + this.addProcedureLabel_ = addLabelField_.bind(this); + + // Only exists on procedures_prototype. + this.createArgumentReporter_ = createArgumentReporter_.bind(this); + this.updateArgumentReporterNames_ = updateArgumentReporterNames_.bind(this); }, - // Shared. - getProcCode: Blockly.ScratchBlocks.ProcedureUtils.getProcCode, - removeAllInputs_: Blockly.ScratchBlocks.ProcedureUtils.removeAllInputs_, - disconnectOldBlocks_: Blockly.ScratchBlocks.ProcedureUtils.disconnectOldBlocks_, - deleteShadows_: Blockly.ScratchBlocks.ProcedureUtils.deleteShadows_, - createAllInputs_: Blockly.ScratchBlocks.ProcedureUtils.createAllInputs_, - updateDisplay_: Blockly.ScratchBlocks.ProcedureUtils.updateDisplay_, - - // Exist on all three blocks, but have different implementations. - mutationToDom: Blockly.ScratchBlocks.ProcedureUtils.definitionMutationToDom, - domToMutation: Blockly.ScratchBlocks.ProcedureUtils.definitionDomToMutation, - populateArgument_: Blockly.ScratchBlocks.ProcedureUtils.populateArgumentOnPrototype_, - addProcedureLabel_: Blockly.ScratchBlocks.ProcedureUtils.addLabelField_, - - // Only exists on procedures_prototype. - createArgumentReporter_: Blockly.ScratchBlocks.ProcedureUtils.createArgumentReporter_, - updateArgumentReporterNames_: Blockly.ScratchBlocks.ProcedureUtils.updateArgumentReporterNames_ }; Blockly.Blocks['procedures_declaration'] = { @@ -871,33 +862,34 @@ Blockly.Blocks['procedures_declaration'] = { this.argumentIds_ = []; this.argumentDefaults_ = []; this.warp_ = false; + + // Shared. + this.getProcCode = getProcCode.bind(this); + this.removeAllInputs_ = removeAllInputs_.bind(this); + this.disconnectOldBlocks_ = disconnectOldBlocks_.bind(this); + this.deleteShadows_ = deleteShadows_.bind(this); + this.createAllInputs_ = createAllInputs_.bind(this); + this.updateDisplay_ = updateDisplay_.bind(this); + + // Exist on all three blocks, but have different implementations. + this.mutationToDom = definitionMutationToDom.bind(this); + this.domToMutation = definitionDomToMutation.bind(this); + this.populateArgument_ = populateArgumentOnDeclaration_.bind(this); + this.addProcedureLabel_ = addLabelEditor_.bind(this); + + // Exist on declaration and arguments editors, with different implementations. + this.removeFieldCallback = removeFieldCallback.bind(this); + + // Only exist on procedures_declaration. + this.createArgumentEditor_ = createArgumentEditor_.bind(this); + this.focusLastEditor_ = focusLastEditor_.bind(this); + this.getWarp = getWarp.bind(this); + this.setWarp = setWarp.bind(this); + this.addLabelExternal = addLabelExternal.bind(this); + this.addBooleanExternal = addBooleanExternal.bind(this); + this.addStringNumberExternal = addStringNumberExternal.bind(this); + this.onChangeFn = updateDeclarationProcCode_.bind(this); }, - // Shared. - getProcCode: Blockly.ScratchBlocks.ProcedureUtils.getProcCode, - removeAllInputs_: Blockly.ScratchBlocks.ProcedureUtils.removeAllInputs_, - disconnectOldBlocks_: Blockly.ScratchBlocks.ProcedureUtils.disconnectOldBlocks_, - deleteShadows_: Blockly.ScratchBlocks.ProcedureUtils.deleteShadows_, - createAllInputs_: Blockly.ScratchBlocks.ProcedureUtils.createAllInputs_, - updateDisplay_: Blockly.ScratchBlocks.ProcedureUtils.updateDisplay_, - - // Exist on all three blocks, but have different implementations. - mutationToDom: Blockly.ScratchBlocks.ProcedureUtils.definitionMutationToDom, - domToMutation: Blockly.ScratchBlocks.ProcedureUtils.definitionDomToMutation, - populateArgument_: Blockly.ScratchBlocks.ProcedureUtils.populateArgumentOnDeclaration_, - addProcedureLabel_: Blockly.ScratchBlocks.ProcedureUtils.addLabelEditor_, - - // Exist on declaration and arguments editors, with different implementations. - removeFieldCallback: Blockly.ScratchBlocks.ProcedureUtils.removeFieldCallback, - - // Only exist on procedures_declaration. - createArgumentEditor_: Blockly.ScratchBlocks.ProcedureUtils.createArgumentEditor_, - focusLastEditor_: Blockly.ScratchBlocks.ProcedureUtils.focusLastEditor_, - getWarp: Blockly.ScratchBlocks.ProcedureUtils.getWarp, - setWarp: Blockly.ScratchBlocks.ProcedureUtils.setWarp, - addLabelExternal: Blockly.ScratchBlocks.ProcedureUtils.addLabelExternal, - addBooleanExternal: Blockly.ScratchBlocks.ProcedureUtils.addBooleanExternal, - addStringNumberExternal: Blockly.ScratchBlocks.ProcedureUtils.addStringNumberExternal, - onChangeFn: Blockly.ScratchBlocks.ProcedureUtils.updateDeclarationProcCode_ }; Blockly.Blocks['argument_reporter_boolean'] = { @@ -940,15 +932,16 @@ Blockly.Blocks['argument_editor_boolean'] = { "text": "foo" } ], - "colour": Blockly.Colours.textField, - "colourSecondary": Blockly.Colours.textField, - "colourTertiary": Blockly.Colours.textField, - "colourQuaternary": Blockly.Colours.textField, + "colour": Colours.textField, + "colourSecondary": Colours.textField, + "colourTertiary": Colours.textField, + "colourQuaternary": Colours.textField, "extensions": ["output_boolean"] }); + + // Exist on declaration and arguments editors, with different implementations. + this.removeFieldCallback = removeArgumentCallback_.bind(this); }, - // Exist on declaration and arguments editors, with different implementations. - removeFieldCallback: Blockly.ScratchBlocks.ProcedureUtils.removeArgumentCallback_ }; Blockly.Blocks['argument_editor_string_number'] = { @@ -961,13 +954,14 @@ Blockly.Blocks['argument_editor_string_number'] = { "text": "foo" } ], - "colour": Blockly.Colours.textField, - "colourSecondary": Blockly.Colours.textField, - "colourTertiary": Blockly.Colours.textField, - "colourQuaternary": Blockly.Colours.textField, + "colour": Colours.textField, + "colourSecondary": Colours.textField, + "colourTertiary": Colours.textField, + "colourQuaternary": Colours.textField, "extensions": ["output_number", "output_string"] }); + + // Exist on declaration and arguments editors, with different implementations. + this.removeFieldCallback = removeArgumentCallback_.bind(this); }, - // Exist on declaration and arguments editors, with different implementations. - removeFieldCallback: Blockly.ScratchBlocks.ProcedureUtils.removeArgumentCallback_ }; diff --git a/blocks_vertical/vertical_extensions.js b/blocks_vertical/vertical_extensions.js index 9eb7504a66..54378d5e46 100644 --- a/blocks_vertical/vertical_extensions.js +++ b/blocks_vertical/vertical_extensions.js @@ -27,6 +27,7 @@ */ import * as Blockly from 'blockly/core'; import {Colours} from '../core/colours.js'; +import {ScratchProcedures} from '../src/procedures.js'; const VerticalExtensions = {}; /** @@ -158,7 +159,7 @@ VerticalExtensions.PROCEDURE_DEF_CONTEXTMENU = { */ customContextMenu: function(menuOptions) { // Add the edit option at the end. - menuOptions.push(Blockly.Procedures.makeEditOption(this)); + menuOptions.push(ScratchProcedures.makeEditOption(this)); // Find the delete option and update its callback to be specific to // functions. @@ -173,7 +174,7 @@ VerticalExtensions.PROCEDURE_DEF_CONTEXTMENU = { } var rootBlock = this; option.callback = function() { - var didDelete = Blockly.Procedures.deleteProcedureDefCallback( + var didDelete = ScratchProcedures.deleteProcedureDefCallback( procCode, rootBlock); if (!didDelete) { alert(Blockly.Msg.PROCEDURE_USED); @@ -207,7 +208,7 @@ VerticalExtensions.PROCEDURE_CALL_CONTEXTMENU = { * @this Blockly.Block */ customContextMenu: function(menuOptions) { - menuOptions.push(Blockly.Procedures.makeEditOption(this)); + menuOptions.push(ScratchProcedures.makeEditOption(this)); } }; diff --git a/core/field_textinput_removable.js b/core/field_textinput_removable.js index a37e071845..7549e9ff90 100644 --- a/core/field_textinput_removable.js +++ b/core/field_textinput_removable.js @@ -22,17 +22,7 @@ * @fileoverview Text input field with floating "remove" button. * @author pkaplan@media.mit.edu (Paul Kaplan) */ -'use strict'; - -goog.provide('Blockly.FieldTextInputRemovable'); - -goog.require('Blockly.BlockSvg.render'); -goog.require('Blockly.Colours'); -goog.require('Blockly.FieldTextInput'); -goog.require('Blockly.Msg'); -goog.require('Blockly.utils'); -goog.require('goog.dom'); -goog.require('goog.dom.TagName'); +import * as Blockly from 'blockly/core'; /** * Class for an editable text field displaying a deletion icon when selected. @@ -47,59 +37,54 @@ goog.require('goog.dom.TagName'); * @extends {Blockly.FieldTextInput} * @constructor */ -Blockly.FieldTextInputRemovable = function(text, opt_validator, opt_restrictor) { - Blockly.FieldTextInputRemovable.superClass_.constructor.call(this, text, - opt_validator, opt_restrictor); -}; -goog.inherits(Blockly.FieldTextInputRemovable, Blockly.FieldTextInput); - -/** - * Show the inline free-text editor on top of the text with the remove button. - * @private - */ -Blockly.FieldTextInputRemovable.prototype.showEditor_ = function() { - Blockly.FieldTextInputRemovable.superClass_.showEditor_.call(this); +export class FieldTextInputRemovable extends Blockly.FieldTextInput { + /** + * Show the inline free-text editor on top of the text with the remove button. + * @private + */ + showEditor_() { + super.showEditor_(); - var div = Blockly.WidgetDiv.DIV; - div.className += ' removableTextInput'; - var removeButton = - goog.dom.createDom(goog.dom.TagName.IMG, 'blocklyTextRemoveIcon'); - removeButton.setAttribute('src', - Blockly.mainWorkspace.options.pathToMedia + 'icons/remove.svg'); - this.removeButtonMouseWrapper_ = Blockly.bindEvent_(removeButton, - 'mousedown', this, this.removeCallback_); - div.appendChild(removeButton); -}; + const div = Blockly.WidgetDiv.getDiv(); + div.className += ' removableTextInput'; + const removeButton = document.createElement('img'); + removeButton.className = 'blocklyTextRemoveIcon'; + removeButton.setAttribute('src', + this.sourceBlock_.workspace.options.pathToMedia + 'icons/remove.svg'); + this.removeButtonMouseWrapper_ = Blockly.browserEvents.bind(removeButton, + 'mousedown', this, this.removeCallback_); + div.appendChild(removeButton); + } -/** - * Function to call when remove button is called. Checks for removeFieldCallback - * on sourceBlock and calls it if possible. - * @private - */ -Blockly.FieldTextInputRemovable.prototype.removeCallback_ = function() { - if (this.sourceBlock_ && this.sourceBlock_.removeFieldCallback) { - this.sourceBlock_.removeFieldCallback(this); - } else { - console.warn('Expected a source block with removeFieldCallback'); + /** + * Function to call when remove button is called. Checks for removeFieldCallback + * on sourceBlock and calls it if possible. + * @private + */ + removeCallback_() { + if (this.sourceBlock_ && this.sourceBlock_.removeFieldCallback) { + this.sourceBlock_.removeFieldCallback(this); + } else { + console.warn('Expected a source block with removeFieldCallback'); + } } -}; -/** - * Helper function to construct a FieldTextInputRemovable from a JSON arg object, - * dereferencing any string table references. - * @param {!Object} options A JSON object with options (text, class, and - * spellcheck). - * @returns {!Blockly.FieldTextInputRemovable} The new text input. - * @public - */ -Blockly.FieldTextInputRemovable.fromJson = function(options) { - var text = Blockly.utils.replaceMessageReferences(options['text']); - var field = new Blockly.FieldTextInputRemovable(text, options['class']); - if (typeof options['spellcheck'] == 'boolean') { - field.setSpellcheck(options['spellcheck']); + /** + * Helper function to construct a FieldTextInputRemovable from a JSON arg object, + * dereferencing any string table references. + * @param {!Object} options A JSON object with options (text, class, and + * spellcheck). + * @returns {!Blockly.FieldTextInputRemovable} The new text input. + * @public + */ + fromJson(options) { + const text = Blockly.utils.replaceMessageReferences(options['text']); + const field = new FieldTextInputRemovable(text, null, options); + if (typeof options['spellcheck'] == 'boolean') { + field.setSpellcheck(options['spellcheck']); + } + return field; } - return field; -}; +} -Blockly.Field.register( - 'field_input_removable', Blockly.FieldTextInputRemovable); +Blockly.fieldRegistry.register('field_input_removable', FieldTextInputRemovable); diff --git a/src/constants.js b/src/constants.js index 0d6f6e3a44..b1bf5d3da4 100644 --- a/src/constants.js +++ b/src/constants.js @@ -16,3 +16,24 @@ export {BROADCAST_MESSAGE_VARIABLE_TYPE}; */ const LIST_VARIABLE_TYPE = 'list'; export {LIST_VARIABLE_TYPE}; + +/* + * The type of all procedure definition blocks. + * @const {string} + */ +const PROCEDURES_DEFINITION_BLOCK_TYPE = 'procedures_definition'; +export {PROCEDURES_DEFINITION_BLOCK_TYPE}; + +/** + * The type of all procedure prototype blocks. + * @const {string} + */ +const PROCEDURES_PROTOTYPE_BLOCK_TYPE = 'procedures_prototype'; +export {PROCEDURES_PROTOTYPE_BLOCK_TYPE}; + +/** + * The type of all procedure call blocks. + * @const {string} + */ +const PROCEDURES_CALL_BLOCK_TYPE = 'procedures_call'; +export {PROCEDURES_CALL_BLOCK_TYPE}; diff --git a/src/index.js b/src/index.js index ac7110eebc..b77e2b5f79 100644 --- a/src/index.js +++ b/src/index.js @@ -14,6 +14,7 @@ import '../blocks_vertical/event.js'; import '../blocks_vertical/looks.js'; import '../blocks_vertical/motion.js'; import '../blocks_vertical/operators.js'; +import '../blocks_vertical/procedures.js'; import '../blocks_vertical/sensing.js'; import '../blocks_vertical/sound.js'; import * as scratchBlocksUtils from '../core/scratch_blocks_utils.js'; @@ -26,6 +27,7 @@ import { export * from 'blockly'; export * from './categories.js'; +export * from './procedures.js'; export * from '../core/colours.js'; export * from '../msg/scratch_msgs.js'; export {scratchBlocksUtils}; diff --git a/core/procedures.js b/src/procedures.js similarity index 54% rename from core/procedures.js rename to src/procedures.js index 5c4f81ef2e..0c471500c7 100644 --- a/core/procedures.js +++ b/src/procedures.js @@ -22,57 +22,10 @@ * @fileoverview Utility functions for handling procedures. * @author fraser@google.com (Neil Fraser) */ -'use strict'; -/** - * @name Blockly.Procedures - * @namespace - **/ -goog.provide('Blockly.Procedures'); - -goog.require('Blockly.Blocks'); -goog.require('Blockly.constants'); -goog.require('Blockly.Events.BlockChange'); -goog.require('Blockly.Field'); -goog.require('Blockly.Names'); -goog.require('Blockly.Workspace'); - - -/** - * Constant to separate procedure names from variables and generated functions - * when running generators. - * @deprecated Use Blockly.PROCEDURE_CATEGORY_NAME - */ -Blockly.Procedures.NAME_TYPE = Blockly.PROCEDURE_CATEGORY_NAME; - -/** - * Find all user-created procedure definitions in a workspace. - * @param {!Blockly.Workspace} root Root workspace. - * @return {!Array.>} Pair of arrays, the - * first contains procedures without return variables, the second with. - * Each procedure is defined by a three-element list of name, parameter - * list, and return value boolean. - */ -Blockly.Procedures.allProcedures = function(root) { - var blocks = root.getAllBlocks(); - var proceduresReturn = []; - var proceduresNoReturn = []; - for (var i = 0; i < blocks.length; i++) { - if (blocks[i].getProcedureDef) { - var tuple = blocks[i].getProcedureDef(); - if (tuple) { - if (tuple[2]) { - proceduresReturn.push(tuple); - } else { - proceduresNoReturn.push(tuple); - } - } - } - } - proceduresNoReturn.sort(Blockly.Procedures.procTupleComparator_); - proceduresReturn.sort(Blockly.Procedures.procTupleComparator_); - return [proceduresNoReturn, proceduresReturn]; -}; +import * as Blockly from 'blockly/core'; +import * as Constants from './constants.js'; +import * as scratchBlocksUtils from '../core/scratch_blocks_utils.js'; /** * Find all user-created procedure definition mutations in a workspace. @@ -80,11 +33,11 @@ Blockly.Procedures.allProcedures = function(root) { * @return {!Array.} Array of mutation xml elements. * @package */ -Blockly.Procedures.allProcedureMutations = function(root) { +function allProcedureMutations(root) { var blocks = root.getAllBlocks(); var mutations = []; for (var i = 0; i < blocks.length; i++) { - if (blocks[i].type == Blockly.PROCEDURES_PROTOTYPE_BLOCK_TYPE) { + if (blocks[i].type == Constants.PROCEDURES_PROTOTYPE_BLOCK_TYPE) { var mutation = blocks[i].mutationToDom(/* opt_generateShadows */ true); if (mutation) { mutations.push(mutation); @@ -92,7 +45,7 @@ Blockly.Procedures.allProcedureMutations = function(root) { } } return mutations; -}; +} /** * Sorts an array of procedure definition mutations alphabetically. @@ -101,144 +54,45 @@ Blockly.Procedures.allProcedureMutations = function(root) { * @return {!Array.} Sorted array of mutation xml elements. * @private */ -Blockly.Procedures.sortProcedureMutations_ = function(mutations) { +function sortProcedureMutations_(mutations) { var newMutations = mutations.slice(); newMutations.sort(function(a, b) { var procCodeA = a.getAttribute('proccode'); var procCodeB = b.getAttribute('proccode'); - return Blockly.scratchBlocksUtils.compareStrings(procCodeA, procCodeB); + return scratchBlocksUtils.compareStrings(procCodeA, procCodeB); }); return newMutations; -}; - -/** - * Comparison function for case-insensitive sorting of the first element of - * a tuple. - * @param {!Array} ta First tuple. - * @param {!Array} tb Second tuple. - * @return {number} -1, 0, or 1 to signify greater than, equality, or less than. - * @private - */ -Blockly.Procedures.procTupleComparator_ = function(ta, tb) { - return Blockly.scratchBlocksUtils.compareStrings(ta[0], tb[0]); -}; - -/** - * Ensure two identically-named procedures don't exist. - * @param {string} name Proposed procedure name. - * @param {!Blockly.Block} block Block to disambiguate. - * @return {string} Non-colliding name. - */ -Blockly.Procedures.findLegalName = function(name, block) { - if (block.isInFlyout) { - // Flyouts can have multiple procedures called 'do something'. - return name; - } - while (!Blockly.Procedures.isLegalName_(name, block.workspace, block)) { - // Collision with another procedure. - var r = name.match(/^(.*?)(\d+)$/); - if (!r) { - name += '2'; - } else { - name = r[1] + (parseInt(r[2], 10) + 1); - } - } - return name; -}; - -/** - * Does this procedure have a legal name? Illegal names include names of - * procedures already defined. - * @param {string} name The questionable name. - * @param {!Blockly.Workspace} workspace The workspace to scan for collisions. - * @param {Blockly.Block=} opt_exclude Optional block to exclude from - * comparisons (one doesn't want to collide with oneself). - * @return {boolean} True if the name is legal. - * @private - */ -Blockly.Procedures.isLegalName_ = function(name, workspace, opt_exclude) { - return !Blockly.Procedures.isNameUsed(name, workspace, opt_exclude); -}; - -/** - * Return if the given name is already a procedure name. - * @param {string} name The questionable name. - * @param {!Blockly.Workspace} workspace The workspace to scan for collisions. - * @param {Blockly.Block=} opt_exclude Optional block to exclude from - * comparisons (one doesn't want to collide with oneself). - * @return {boolean} True if the name is used, otherwise return false. - */ -Blockly.Procedures.isNameUsed = function(name, workspace, opt_exclude) { - var blocks = workspace.getAllBlocks(); - // Iterate through every block and check the name. - for (var i = 0; i < blocks.length; i++) { - if (blocks[i] == opt_exclude) { - continue; - } - if (blocks[i].getProcedureDef) { - var procName = blocks[i].getProcedureDef(); - if (Blockly.Names.equals(procName[0], name)) { - return false; - } - } - } - return true; -}; - -/** - * Rename a procedure. Called by the editable field. - * @param {string} name The proposed new name. - * @return {string} The accepted name. - * @this {Blockly.Field} - */ -Blockly.Procedures.rename = function(name) { - // Strip leading and trailing whitespace. Beyond this, all names are legal. - name = name.replace(/^[\s\xa0]+|[\s\xa0]+$/g, ''); - - // Ensure two identically-named procedures don't exist. - var legalName = Blockly.Procedures.findLegalName(name, this.sourceBlock_); - var oldName = this.text_; - if (oldName != name && oldName != legalName) { - // Rename any callers. - var blocks = this.sourceBlock_.workspace.getAllBlocks(); - for (var i = 0; i < blocks.length; i++) { - if (blocks[i].renameProcedure) { - blocks[i].renameProcedure(oldName, legalName); - } - } - } - return legalName; -}; +} /** * Construct the blocks required by the flyout for the procedure category. - * @param {!Blockly.Workspace} workspace The workspace contianing procedures. + * @param {!Blockly.Workspace} workspace The workspace containing procedures. * @return {!Array.} Array of XML block elements. */ -Blockly.Procedures.flyoutCategory = function(workspace) { +function getProceduresCategory(workspace) { var xmlList = []; - Blockly.Procedures.addCreateButton_(workspace, xmlList); + addCreateButton_(workspace, xmlList); // Create call blocks for each procedure defined in the workspace - var mutations = Blockly.Procedures.allProcedureMutations(workspace); - mutations = Blockly.Procedures.sortProcedureMutations_(mutations); + var mutations = allProcedureMutations(workspace); + mutations = sortProcedureMutations_(mutations); for (var i = 0; i < mutations.length; i++) { var mutation = mutations[i]; // // // - var block = goog.dom.createDom('block'); + var block = document.createElement('block'); block.setAttribute('type', 'procedures_call'); block.setAttribute('gap', 16); block.appendChild(mutation); xmlList.push(block); } return xmlList; -}; +} /** * Create the "Make a Block..." button. @@ -246,18 +100,18 @@ Blockly.Procedures.flyoutCategory = function(workspace) { * @param {!Array.} xmlList Array of XML block elements to add to. * @private */ -Blockly.Procedures.addCreateButton_ = function(workspace, xmlList) { - var button = goog.dom.createDom('button'); +function addCreateButton_(workspace, xmlList) { + var button = document.createElement('button'); var msg = Blockly.Msg.NEW_PROCEDURE; var callbackKey = 'CREATE_PROCEDURE'; var callback = function() { - Blockly.Procedures.createProcedureDefCallback_(workspace); + createProcedureDefCallback_(workspace); }; button.setAttribute('text', msg); button.setAttribute('callbackKey', callbackKey); workspace.registerButtonCallback(callbackKey, callback); xmlList.push(button); -}; +} /** * Find all callers of a named procedure. @@ -271,7 +125,7 @@ Blockly.Procedures.addCreateButton_ = function(workspace, xmlList) { * @return {!Array.} Array of caller blocks. * @package */ -Blockly.Procedures.getCallers = function(name, ws, definitionRoot, +function getCallers(name, ws, definitionRoot, allowRecursive) { var allBlocks = []; var topBlocks = ws.getTopBlocks(); @@ -288,7 +142,7 @@ Blockly.Procedures.getCallers = function(name, ws, definitionRoot, var callers = []; for (var i = 0; i < allBlocks.length; i++) { var block = allBlocks[i]; - if (block.type == Blockly.PROCEDURES_CALL_BLOCK_TYPE ) { + if (block.type == Constants.PROCEDURES_CALL_BLOCK_TYPE ) { var procCode = block.getProcCode(); if (procCode && procCode == name) { callers.push(block); @@ -296,7 +150,7 @@ Blockly.Procedures.getCallers = function(name, ws, definitionRoot, } } return callers; -}; +} /** * Find and edit all callers with a procCode using a new mutation. @@ -305,11 +159,11 @@ Blockly.Procedures.getCallers = function(name, ws, definitionRoot, * @param {!Element} mutation New mutation for the callers. * @package */ -Blockly.Procedures.mutateCallersAndPrototype = function(name, ws, mutation) { - var defineBlock = Blockly.Procedures.getDefineBlock(name, ws); - var prototypeBlock = Blockly.Procedures.getPrototypeBlock(name, ws); +function mutateCallersAndPrototype(name, ws, mutation) { + var defineBlock = getDefineBlock(name, ws); + var prototypeBlock = getPrototypeBlock(name, ws); if (defineBlock && prototypeBlock) { - var callers = Blockly.Procedures.getCallers(name, + var callers = getCallers(name, defineBlock.workspace, defineBlock, true /* allowRecursive */); callers.push(prototypeBlock); Blockly.Events.setGroup(true); @@ -328,7 +182,7 @@ Blockly.Procedures.mutateCallersAndPrototype = function(name, ws, mutation) { } else { alert('No define block on workspace'); // TODO decide what to do about this. } -}; +} /** * Find the definition block for the named procedure. @@ -337,11 +191,11 @@ Blockly.Procedures.mutateCallersAndPrototype = function(name, ws, mutation) { * @return {Blockly.Block} The procedure definition block, or null not found. * @package */ -Blockly.Procedures.getDefineBlock = function(procCode, workspace) { +function getDefineBlock(procCode, workspace) { // Assume that a procedure definition is a top block. var blocks = workspace.getTopBlocks(false); for (var i = 0; i < blocks.length; i++) { - if (blocks[i].type == Blockly.PROCEDURES_DEFINITION_BLOCK_TYPE) { + if (blocks[i].type == Constants.PROCEDURES_DEFINITION_BLOCK_TYPE) { var prototypeBlock = blocks[i].getInput('custom_block').connection.targetBlock(); if (prototypeBlock.getProcCode && prototypeBlock.getProcCode() == procCode) { return blocks[i]; @@ -349,7 +203,7 @@ Blockly.Procedures.getDefineBlock = function(procCode, workspace) { } } return null; -}; +} /** * Find the prototype block for the named procedure. @@ -358,20 +212,20 @@ Blockly.Procedures.getDefineBlock = function(procCode, workspace) { * @return {Blockly.Block} The procedure prototype block, or null not found. * @package */ -Blockly.Procedures.getPrototypeBlock = function(procCode, workspace) { - var defineBlock = Blockly.Procedures.getDefineBlock(procCode, workspace); +function getPrototypeBlock(procCode, workspace) { + var defineBlock = getDefineBlock(procCode, workspace); if (defineBlock) { return defineBlock.getInput('custom_block').connection.targetBlock(); } return null; -}; +} /** * Create a mutation for a brand new custom procedure. * @return {Element} The mutation for a new custom procedure * @package */ -Blockly.Procedures.newProcedureMutation = function() { +function newProcedureMutation() { var mutationText = '' + '' + '' + ''; - return Blockly.Xml.textToDom(mutationText).firstChild; -}; + return Blockly.utils.xml.textToDom(mutationText).firstChild; +} /** * Callback to create a new procedure custom command block. * @param {!Blockly.Workspace} workspace The workspace to create the new procedure on. * @private */ -Blockly.Procedures.createProcedureDefCallback_ = function(workspace) { - Blockly.Procedures.externalProcedureDefCallback( - Blockly.Procedures.newProcedureMutation(), - Blockly.Procedures.createProcedureCallbackFactory_(workspace) +function createProcedureDefCallback_(workspace) { + ScratchProcedures.externalProcedureDefCallback( + newProcedureMutation(), + createProcedureCallbackFactory_(workspace) ); -}; +} /** * Callback factory for adding a new custom procedure from a mutation. @@ -402,7 +256,7 @@ Blockly.Procedures.createProcedureDefCallback_ = function(workspace) { * @return {function(?Element)} callback for creating the new custom procedure. * @private */ -Blockly.Procedures.createProcedureCallbackFactory_ = function(workspace) { +function createProcedureCallbackFactory_(workspace) { return function(mutation) { if (mutation) { var blockText = '' + @@ -414,7 +268,7 @@ Blockly.Procedures.createProcedureCallbackFactory_ = function(workspace) { '' + '' + ''; - var blockDom = Blockly.Xml.textToDom(blockText).firstChild; + var blockDom = Blockly.utils.xml.textToDom(blockText).firstChild; Blockly.Events.setGroup(true); var block = Blockly.Xml.domToBlock(blockDom, workspace); var scale = workspace.scale; // To convert from pixel units to workspace units @@ -431,17 +285,17 @@ Blockly.Procedures.createProcedureCallbackFactory_ = function(workspace) { Blockly.Events.setGroup(false); } }; -}; +} /** * Callback to open the modal for editing custom procedures. * @param {!Blockly.Block} block The block that was right-clicked. * @private */ -Blockly.Procedures.editProcedureCallback_ = function(block) { +function editProcedureCallback_(block) { // Edit can come from one of three block types (call, define, prototype) // Normalize by setting the block to the prototype block for the procedure. - if (block.type == Blockly.PROCEDURES_DEFINITION_BLOCK_TYPE) { + if (block.type == Constants.PROCEDURES_DEFINITION_BLOCK_TYPE) { var input = block.getInput('custom_block'); if (!input) { alert('Bad input'); // TODO: Decide what to do about this. @@ -454,25 +308,25 @@ Blockly.Procedures.editProcedureCallback_ = function(block) { } var innerBlock = conn.targetBlock(); if (!innerBlock || - !innerBlock.type == Blockly.PROCEDURES_PROTOTYPE_BLOCK_TYPE) { + !innerBlock.type == Constants.PROCEDURES_PROTOTYPE_BLOCK_TYPE) { alert('Bad inner block'); // TODO: Decide what to do about this. return; } block = innerBlock; - } else if (block.type == Blockly.PROCEDURES_CALL_BLOCK_TYPE) { + } else if (block.type == Constants.PROCEDURES_CALL_BLOCK_TYPE) { // This is a call block, find the prototype corresponding to the procCode. // Make sure to search the correct workspace, call block can be in flyout. var workspaceToSearch = block.workspace.isFlyout ? block.workspace.targetWorkspace : block.workspace; - block = Blockly.Procedures.getPrototypeBlock( + block = getPrototypeBlock( block.getProcCode(), workspaceToSearch); } // Block now refers to the procedure prototype block, it is safe to proceed. - Blockly.Procedures.externalProcedureDefCallback( + ScratchProcedures.externalProcedureDefCallback( block.mutationToDom(), - Blockly.Procedures.editProcedureCallbackFactory_(block) + editProcedureCallbackFactory_(block) ); -}; +} /** * Callback factory for editing an existing custom procedure. @@ -480,22 +334,14 @@ Blockly.Procedures.editProcedureCallback_ = function(block) { * @return {function(?Element)} Callback for editing the custom procedure. * @private */ -Blockly.Procedures.editProcedureCallbackFactory_ = function(block) { +function editProcedureCallbackFactory_(block) { return function(mutation) { if (mutation) { - Blockly.Procedures.mutateCallersAndPrototype(block.getProcCode(), + mutateCallersAndPrototype(block.getProcCode(), block.workspace, mutation); } }; -}; - -/** - * Callback to create a new procedure custom command block. - * @public - */ -Blockly.Procedures.externalProcedureDefCallback = function(/** mutator, callback */) { - alert('External procedure editor must be override Blockly.Procedures.externalProcedureDefCallback'); -}; +} /** * Make a context menu option for editing a custom procedure. @@ -505,46 +351,16 @@ Blockly.Procedures.externalProcedureDefCallback = function(/** mutator, callback * @return {!Object} A menu option, containing text, enabled, and a callback. * @package */ -Blockly.Procedures.makeEditOption = function(block) { +function makeEditOption(block) { var editOption = { enabled: true, text: Blockly.Msg.EDIT_PROCEDURE, callback: function() { - Blockly.Procedures.editProcedureCallback_(block); + editProcedureCallback_(block); } }; return editOption; -}; - -/** - * Callback to show the procedure definition corresponding to a custom command - * block. - * TODO(#1136): Implement. - * @param {!Blockly.Block} block The block that was right-clicked. - * @private - */ -Blockly.Procedures.showProcedureDefCallback_ = function(block) { - alert('TODO(#1136): implement showing procedure definition (procCode was "' + - block.procCode_ + '")'); -}; - -/** - * Make a context menu option for showing the definition for a custom procedure, - * based on a right-click on a custom command block. - * @param {!Blockly.BlockSvg} block The block where the right-click originated. - * @return {!Object} A menu option, containing text, enabled, and a callback. - * @package - */ -Blockly.Procedures.makeShowDefinitionOption = function(block) { - var option = { - enabled: true, - text: Blockly.Msg.SHOW_PROCEDURE_DEFINITION, - callback: function() { - Blockly.Procedures.showProcedureDefCallback_(block); - } - }; - return option; -}; +} /** * Callback to try to delete a custom block definitions. @@ -554,9 +370,9 @@ Blockly.Procedures.makeShowDefinitionOption = function(block) { * @return {boolean} True if the custom procedure was deleted, false otherwise. * @package */ -Blockly.Procedures.deleteProcedureDefCallback = function(procCode, +function deleteProcedureDefCallback(procCode, definitionRoot) { - var callers = Blockly.Procedures.getCallers(procCode, + var callers = getCallers(procCode, definitionRoot.workspace, definitionRoot, false /* allowRecursive */); if (callers.length > 0) { return false; @@ -574,4 +390,13 @@ Blockly.Procedures.deleteProcedureDefCallback = function(procCode, workspace.refreshToolboxSelection_(); return true; +} + +const ScratchProcedures = { + externalProcedureDefCallback: null, + createProcedureDefCallback, + deleteProcedureDefCallback, + getProceduresCategory, + makeEditOption, }; +export {ScratchProcedures}; From 4e794f6503dfba1d12f9e99905660d305d34e309 Mon Sep 17 00:00:00 2001 From: Aaron Dodson Date: Wed, 24 Apr 2024 13:23:10 -0700 Subject: [PATCH 023/130] fix: remove underscore from a few createProcedureDefCallback calls (#40) --- src/procedures.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/procedures.js b/src/procedures.js index 0c471500c7..bc1c76c3b5 100644 --- a/src/procedures.js +++ b/src/procedures.js @@ -105,7 +105,7 @@ function addCreateButton_(workspace, xmlList) { var msg = Blockly.Msg.NEW_PROCEDURE; var callbackKey = 'CREATE_PROCEDURE'; var callback = function() { - createProcedureDefCallback_(workspace); + createProcedureDefCallback(workspace); }; button.setAttribute('text', msg); button.setAttribute('callbackKey', callbackKey); @@ -243,7 +243,7 @@ function newProcedureMutation() { * @param {!Blockly.Workspace} workspace The workspace to create the new procedure on. * @private */ -function createProcedureDefCallback_(workspace) { +function createProcedureDefCallback(workspace) { ScratchProcedures.externalProcedureDefCallback( newProcedureMutation(), createProcedureCallbackFactory_(workspace) From 300a1ce564a55cb65ef2e01792a0ba1149621c50 Mon Sep 17 00:00:00 2001 From: Aaron Dodson Date: Wed, 24 Apr 2024 15:04:20 -0700 Subject: [PATCH 024/130] fix: miscellaneous UI fixits (#41) --- core/css.js | 22 +++++++++++++++------- src/index.js | 4 ++++ src/scratch_continuous_category.js | 23 +++++++++++++++++++++++ 3 files changed, 42 insertions(+), 7 deletions(-) create mode 100644 src/scratch_continuous_category.js diff --git a/core/css.js b/core/css.js index dbbde9f5e8..f7c15db668 100644 --- a/core/css.js +++ b/core/css.js @@ -383,10 +383,6 @@ const styles = ` stroke: #c6c6c6; } - .blocklyFlyoutButton .blocklyText { - fill: var(--colour-textFieldText); - } - .blocklyFlyoutButtonShadow { fill: transparent; } @@ -416,6 +412,14 @@ const styles = ` font-weight: bold; } + .zelos-renderer.scratch-theme .blocklyText { + font-weight: 500; + } + + .zelos-renderer.scratch-theme .blocklyFlyoutButton .blocklyText { + fill: var(--colour-textFieldText); + } + /* Don't allow users to select text. It gets annoying when trying to drag a block and selected text moves instead. @@ -749,7 +753,7 @@ const styles = ` outline: none; } - .blocklyTreeRow { + .blocklyToolboxDiv .blocklyTreeRow { line-height: 22px; margin: 0; padding: 0.375rem 0px; @@ -933,6 +937,12 @@ const styles = ` overflow-y: auto; overflow-x: hidden; z-index: 20000; /* Arbitrary, but some apps depend on it... */ + box-sizing: content-box; + box-shadow: none; + } + + .blocklyWidgetDiv .blocklyMenu.blocklyFocused { + box-shadow: none; } .blocklyDropDownDiv .goog-menu { @@ -972,7 +982,6 @@ const styles = ` * #noflip to .goog-menuitem. */ .blocklyWidgetDiv .goog-menuitem { - color: #000; font: normal 13px "Helvetica Neue", Helvetica, sans-serif; list-style: none; margin: 0; @@ -1021,7 +1030,6 @@ const styles = ` .blocklyWidgetDiv .goog-menuitem-content , .blocklyDropDownDiv .goog-menuitem-content { - color: #000; font: normal 13px "Helvetica Neue", Helvetica, sans-serif; } diff --git a/src/index.js b/src/index.js index b77e2b5f79..b945430684 100644 --- a/src/index.js +++ b/src/index.js @@ -25,6 +25,8 @@ import { ContinuousMetrics, } from '@blockly/continuous-toolbox'; +import './scratch_continuous_category.js'; + export * from 'blockly'; export * from './categories.js'; export * from './procedures.js'; @@ -45,5 +47,7 @@ export function inject(container, options) { } Blockly.Scrollbar.scrollbarThickness = Blockly.Touch.TOUCH_ENABLED ? 14 : 11; +Blockly.FlyoutButton.TEXT_MARGIN_X = 40; +Blockly.FlyoutButton.TEXT_MARGIN_Y = 10; Blockly.ContextMenuRegistry.registry.unregister('blockDisable'); Blockly.ContextMenuRegistry.registry.unregister('blockInline'); diff --git a/src/scratch_continuous_category.js b/src/scratch_continuous_category.js new file mode 100644 index 0000000000..1a29b82118 --- /dev/null +++ b/src/scratch_continuous_category.js @@ -0,0 +1,23 @@ +import * as Blockly from 'blockly/core'; +import {ContinuousCategory} from '@blockly/continuous-toolbox'; + +class ScratchContinuousCategory extends ContinuousCategory { + createIconDom_() { + const icon = super.createIconDom_(); + icon.style.border = `1px solid ${this.toolboxItemDef_['secondaryColour']}`; + return icon; + } + + setSelected(isSelected) { + super.setSelected(isSelected); + // Prevent hardcoding the background color to grey. + this.rowDiv_.style.backgroundColor = ''; + } +} + +Blockly.registry.register( + Blockly.registry.Type.TOOLBOX_ITEM, + Blockly.ToolboxCategory.registrationName, + ScratchContinuousCategory, + true, +); \ No newline at end of file From 4f979828f1122d5cf314a8de464457ae8b925ed7 Mon Sep 17 00:00:00 2001 From: Aaron Dodson Date: Thu, 25 Apr 2024 15:39:48 -0700 Subject: [PATCH 025/130] fix: modernize and reenable the colour slider field (#42) * fix: modernize and reenable the colour slider field * refactor: clean up FieldColourSlider * refactor: extend the FieldColour Blockly plugin * refactor: remove redundant setting of colour on source block --- blocks_common/colour.js | 11 +- core/css.js | 34 ++ core/field_colour_slider.js | 598 +++++++++++++++++------------------- package-lock.json | 30 +- package.json | 1 + src/constants.js | 3 + src/index.js | 2 + 7 files changed, 341 insertions(+), 338 deletions(-) diff --git a/blocks_common/colour.js b/blocks_common/colour.js index 30be7523ac..c947329ce3 100644 --- a/blocks_common/colour.js +++ b/blocks_common/colour.js @@ -22,13 +22,8 @@ * @fileoverview Colour blocks for Blockly. * @author fraser@google.com (Neil Fraser) */ -'use strict'; - -goog.provide('Blockly.Blocks.colour'); - -goog.require('Blockly.Blocks'); - -goog.require('Blockly.constants'); +import * as Blockly from 'blockly'; +import * as Constants from '../src/constants.js'; /** * Pick a random colour. @@ -54,7 +49,7 @@ Blockly.Blocks['colour_picker'] = { "colour": randomColour() } ], - "outputShape": Blockly.OUTPUT_SHAPE_ROUND, + "outputShape": Constants.OUTPUT_SHAPE_ROUND, "output": "Colour" }); } diff --git a/core/css.js b/core/css.js index f7c15db668..6eb7d6d266 100644 --- a/core/css.js +++ b/core/css.js @@ -881,6 +881,10 @@ const styles = ` cursor: pointer; } + .scratchColourPicker { + width: min-content; + } + .scratchColourPickerLabel { font-family: "Helvetica Neue", Helvetica, sans-serif; font-size: 0.65rem; @@ -896,6 +900,36 @@ const styles = ` margin-left: 10px; } + .scratchColourSlider { + appearance: none; + margin: 8px; + height: 22px; + width: 150px; + position: relative; + outline: none; + border-radius: 11px; + margin-bottom: 20px; + } + + /* Combining this and the -moz equivalent below with a comma break the webkit version */ + .scratchColourSlider::-webkit-slider-thumb { + appearance: none; + background-color: #fff; + height: 26px; + width: 26px; + border-radius: 100%; + box-shadow: 0 0 0 4px rgba(0, 0, 0, 0.15); + } + + .scratchColourSlider::-moz-range-thumb { + appearance: none; + background-color: #fff; + height: 26px; + width: 26px; + border-radius: 100%; + box-shadow: 0 0 0 4px rgba(0, 0, 0, 0.15); + } + .scratchMatrixButtonDiv { width: 50%; text-align: center; diff --git a/core/field_colour_slider.js b/core/field_colour_slider.js index 331de6975a..c02e254179 100644 --- a/core/field_colour_slider.js +++ b/core/field_colour_slider.js @@ -22,17 +22,8 @@ * @fileoverview Colour input field. * @author fraser@google.com (Neil Fraser) */ -'use strict'; - -goog.provide('Blockly.FieldColourSlider'); - -goog.require('Blockly.Field'); -goog.require('Blockly.DropDownDiv'); -goog.require('goog.dom'); -goog.require('goog.events'); -goog.require('goog.style'); -goog.require('goog.color'); -goog.require('goog.ui.Slider'); +import * as Blockly from 'blockly/core'; +import {FieldColour} from '@blockly/field-colour'; /** * Class for a slider-based colour input field. @@ -45,343 +36,302 @@ goog.require('goog.ui.Slider'); * @extends {Blockly.Field} * @constructor */ -Blockly.FieldColourSlider = function(colour, opt_validator) { - Blockly.FieldColourSlider.superClass_.constructor.call(this, colour, opt_validator); - this.addArgType('colour'); - - // Flag to track whether or not the slider callbacks should execute - this.sliderCallbacksEnabled_ = false; -}; -goog.inherits(Blockly.FieldColourSlider, Blockly.Field); - -/** - * Construct a FieldColourSlider from a JSON arg object. - * @param {!Object} options A JSON object with options (colour). - * @returns {!Blockly.FieldColourSlider} The new field instance. - * @package - * @nocollapse - */ -Blockly.FieldColourSlider.fromJson = function(options) { - return new Blockly.FieldColourSlider(options['colour']); -}; - -/** - * Function to be called if eyedropper can be activated. - * If defined, an eyedropper button will be added to the color picker. - * The button calls this function with a callback to update the field value. - * BEWARE: This is not a stable API, so it is being marked as private. It may change. - * @private - */ -Blockly.FieldColourSlider.activateEyedropper_ = null; - -/** - * Path to the eyedropper svg icon. - */ -Blockly.FieldColourSlider.EYEDROPPER_PATH = 'eyedropper.svg'; - -/** - * Install this field on a block. - * @param {!Blockly.Block} block The block containing this field. - */ -Blockly.FieldColourSlider.prototype.init = function(block) { - if (this.fieldGroup_) { - // Colour slider has already been initialized once. - return; +export class FieldColourSlider extends FieldColour { + /** + * Function to be called if eyedropper can be activated. + * If defined, an eyedropper button will be added to the color picker. + * The button calls this function with a callback to update the field value. + * BEWARE: This is not a stable API, so it is being marked as private. It may change. + * @private + */ + static activateEyedropper_ = null; + + constructor(colour, opt_validator) { + super(colour, opt_validator); + + /** + * Path to the eyedropper svg icon. + */ + this.EYEDROPPER_PATH = 'eyedropper.svg'; + this.SERIALIZABLE = true; + this.EDITABLE = true; } - Blockly.FieldColourSlider.superClass_.init.call(this, block); - this.setValue(this.getValue()); -}; -/** - * Return the current colour. - * @return {string} Current colour in '#rrggbb' format. - */ -Blockly.FieldColourSlider.prototype.getValue = function() { - return this.colour_; -}; - -/** - * Set the colour. - * @param {string} colour The new colour in '#rrggbb' format. - */ -Blockly.FieldColourSlider.prototype.setValue = function(colour) { - if (this.sourceBlock_ && Blockly.Events.isEnabled() && - this.colour_ != colour) { - Blockly.Events.fire(new Blockly.Events.BlockChange( - this.sourceBlock_, 'field', this.name, this.colour_, colour)); + /** + * Construct a FieldColourSlider from a JSON arg object. + * @param {!Object} options A JSON object with options (colour). + * @returns {!Blockly.FieldColourSlider} The new field instance. + * @package + * @nocollapse + */ + static fromJson(options) { + return new FieldColourSlider(options['colour']); } - this.colour_ = colour; - if (this.sourceBlock_) { - // Set the colours to this value. - // The renderer expects to be able to use the secondary colour as the fill for a shadow. - this.sourceBlock_.setColour(colour, colour, this.sourceBlock_.getColourTertiary(), - this.sourceBlock_.getColourQuaternary()); + + doValueUpdate_(newValue) { + super.doValueUpdate_(newValue); + this.updateSliderHandles_(); + this.updateDom_(); } - this.updateSliderHandles_(); - this.updateDom_(); -}; -/** - * Create the hue, saturation or value CSS gradient for the slide backgrounds. - * @param {string} channel – Either "hue", "saturation" or "value". - * @return {string} Array colour hex colour stops for the given channel - * @private - */ -Blockly.FieldColourSlider.prototype.createColourStops_ = function(channel) { - var stops = []; - for(var n = 0; n <= 360; n += 20) { - switch (channel) { - case 'hue': - stops.push(goog.color.hsvToHex(n, this.saturation_, this.brightness_)); - break; - case 'saturation': - stops.push(goog.color.hsvToHex(this.hue_, n / 360, this.brightness_)); - break; - case 'brightness': - stops.push(goog.color.hsvToHex(this.hue_, this.saturation_, 255 * n / 360)); - break; - default: - throw new Error("Unknown channel for colour sliders: " + channel); + /** + * Create the hue, saturation or value CSS gradient for the slide backgrounds. + * @param {string} channel – Either "hue", "saturation" or "value". + * @return {string} Array colour hex colour stops for the given channel + * @private + */ + createColourStops_(channel) { + var stops = []; + for(var n = 0; n <= 360; n += 20) { + switch (channel) { + case 'hue': + stops.push(Blockly.utils.colour.hsvToHex(n, this.saturation_, this.brightness_)); + break; + case 'saturation': + stops.push(Blockly.utils.colour.hsvToHex(this.hue_, n / 360, this.brightness_)); + break; + case 'brightness': + stops.push(Blockly.utils.colour.hsvToHex(this.hue_, this.saturation_, 255 * n / 360)); + break; + default: + throw new Error("Unknown channel for colour sliders: " + channel); + } } + return stops; } - return stops; -}; -/** - * Set the gradient CSS properties for the given node and channel - * @param {Node} node - The DOM node the gradient will be set on. - * @param {string} channel – Either "hue", "saturation" or "value". - * @private - */ -Blockly.FieldColourSlider.prototype.setGradient_ = function(node, channel) { - var gradient = this.createColourStops_(channel).join(','); - goog.style.setStyle(node, 'background', - '-moz-linear-gradient(left, ' + gradient + ')'); - goog.style.setStyle(node, 'background', - '-webkit-linear-gradient(left, ' + gradient + ')'); - goog.style.setStyle(node, 'background', - '-o-linear-gradient(left, ' + gradient + ')'); - goog.style.setStyle(node, 'background', - '-ms-linear-gradient(left, ' + gradient + ')'); - goog.style.setStyle(node, 'background', - 'linear-gradient(left, ' + gradient + ')'); -}; + /** + * Set the gradient CSS properties for the given node and channel + * @param {Node} node - The DOM node the gradient will be set on. + * @param {string} channel – Either "hue", "saturation" or "value". + * @private + */ + setGradient_(node, channel) { + var gradient = this.createColourStops_(channel).join(','); + node.style['background'] = `linear-gradient(to right, ${gradient})`; + } -/** - * Update the readouts and slider backgrounds after value has changed. - * @private - */ -Blockly.FieldColourSlider.prototype.updateDom_ = function() { - if (this.hueSlider_) { - // Update the slider backgrounds - this.setGradient_(this.hueSlider_.getElement(), 'hue'); - this.setGradient_(this.saturationSlider_.getElement(), 'saturation'); - this.setGradient_(this.brightnessSlider_.getElement(), 'brightness'); + /** + * Update the readouts and slider backgrounds after value has changed. + * @private + */ + updateDom_() { + if (this.hueSlider_) { + // Update the slider backgrounds + this.setGradient_(this.hueSlider_, 'hue'); + this.setGradient_(this.saturationSlider_, 'saturation'); + this.setGradient_(this.brightnessSlider_, 'brightness'); + + // Update the readouts + this.hueReadout_.textContent = Math.floor(100 * this.hue_ / 360).toFixed(0); + this.saturationReadout_.textContent = Math.floor(100 * this.saturation_).toFixed(0); + this.brightnessReadout_.textContent = Math.floor(100 * this.brightness_ / 255).toFixed(0); + } + } - // Update the readouts - this.hueReadout_.textContent = Math.floor(100 * this.hue_ / 360).toFixed(0); - this.saturationReadout_.textContent = Math.floor(100 * this.saturation_).toFixed(0); - this.brightnessReadout_.textContent = Math.floor(100 * this.brightness_ / 255).toFixed(0); + /** + * Update the slider handle positions from the current field value. + * @private + */ + updateSliderHandles_() { + if (this.hueSlider_) { + this.hueSlider_.value = this.hue_; + this.saturationSlider_.value = this.saturation_; + this.brightnessSlider_.value = this.brightness_; + } } -}; -/** - * Update the slider handle positions from the current field value. - * @private - */ -Blockly.FieldColourSlider.prototype.updateSliderHandles_ = function() { - if (this.hueSlider_) { - // Don't let the following calls to setValue for each of the sliders - // trigger the slider callbacks (which then call setValue on this field again - // unnecessarily) - this.sliderCallbacksEnabled_ = false; - this.hueSlider_.setValue(this.hue_); - this.saturationSlider_.setValue(this.saturation_); - this.brightnessSlider_.setValue(this.brightness_); - this.sliderCallbacksEnabled_ = true; + /** + * Create label and readout DOM elements, returning the readout + * @param {string} labelText - Text for the label + * @return {Array} The container node and the readout node. + * @private + */ + createLabelDom_(labelText) { + var labelContainer = document.createElement('div'); + labelContainer.setAttribute('class', 'scratchColourPickerLabel'); + var readout = document.createElement('span'); + readout.setAttribute('class', 'scratchColourPickerReadout'); + var label = document.createElement('span'); + label.setAttribute('class', 'scratchColourPickerLabelText'); + label.textContent = labelText; + labelContainer.appendChild(label); + labelContainer.appendChild(readout); + return [labelContainer, readout]; } -}; -/** - * Get the text from this field. Used when the block is collapsed. - * @return {string} Current text. - */ -Blockly.FieldColourSlider.prototype.getText = function() { - var colour = this.colour_; - // Try to use #rgb format if possible, rather than #rrggbb. - var m = colour.match(/^#(.)\1(.)\2(.)\3$/); - if (m) { - colour = '#' + m[1] + m[2] + m[3]; + /** + * Factory for creating the different slider callbacks + * @param {string} channel - One of "hue", "saturation" or "brightness" + * @return {function} the callback for slider update + * @private + */ + sliderCallbackFactory_(channel) { + var thisField = this; + return function(event) { + var channelValue = event.target.value; + switch (channel) { + case 'hue': + thisField.hue_ = channelValue; + break; + case 'saturation': + thisField.saturation_ = channelValue; + break; + case 'brightness': + thisField.brightness_ = channelValue; + break; + } + var colour = Blockly.utils.colour.hsvToHex(thisField.hue_, thisField.saturation_, thisField.brightness_); + if (colour !== null) { + thisField.setValue(colour, true); + } + }; } - return colour; -}; -/** - * Create label and readout DOM elements, returning the readout - * @param {string} labelText - Text for the label - * @return {Array} The container node and the readout node. - * @private - */ -Blockly.FieldColourSlider.prototype.createLabelDom_ = function(labelText) { - var labelContainer = document.createElement('div'); - labelContainer.setAttribute('class', 'scratchColourPickerLabel'); - var readout = document.createElement('span'); - readout.setAttribute('class', 'scratchColourPickerReadout'); - var label = document.createElement('span'); - label.setAttribute('class', 'scratchColourPickerLabelText'); - label.textContent = labelText; - labelContainer.appendChild(label); - labelContainer.appendChild(readout); - return [labelContainer, readout]; -}; + /** + * Activate the eyedropper, passing in a callback for setting the field value. + * @private + */ + activateEyedropperInternal_() { + var thisField = this; + FieldColourSlider.activateEyedropper_(function(chosenColour) { + // Update the internal hue/saturation/brightness values so sliders update. + const components = Blockly.utils.colour.hexToRgb(chosenColour); + const {hue, saturation, value} = thisField.rgbToHsv(components[0], components[1], components[2]); + thisField.hue_ = hue; + thisField.saturation_ = saturation; + thisField.brightness_ = value; + thisField.setValue(chosenColour); + }); + } -/** - * Factory for creating the different slider callbacks - * @param {string} channel - One of "hue", "saturation" or "brightness" - * @return {function} the callback for slider update - * @private - */ -Blockly.FieldColourSlider.prototype.sliderCallbackFactory_ = function(channel) { - var thisField = this; - return function(event) { - if (!thisField.sliderCallbacksEnabled_) return; - var channelValue = event.target.getValue(); - switch (channel) { - case 'hue': - thisField.hue_ = channelValue; - break; - case 'saturation': - thisField.saturation_ = channelValue; - break; - case 'brightness': - thisField.brightness_ = channelValue; - break; - } - var colour = goog.color.hsvToHex(thisField.hue_, thisField.saturation_, thisField.brightness_); - if (thisField.sourceBlock_) { - // Call any validation function, and allow it to override. - colour = thisField.callValidator(colour); + /** + * Create hue, saturation and brightness sliders under the colour field. + * @private + */ + showEditor_() { + Blockly.DropDownDiv.hideWithoutAnimation(); + Blockly.DropDownDiv.clearContent(); + var div = Blockly.DropDownDiv.getContentDiv(); + div.className = 'scratchColourPicker'; + + // Init color component values that are used while the editor is open + // in order to keep the slider values stable. + const components = Blockly.utils.colour.hexToRgb(this.getValue()); + var {hue, saturation, value} = this.rgbToHsv(components[0], components[1], components[2]); + this.hue_ = hue; + this.saturation_ = saturation; + this.brightness_ = value; + + var hueElements = this.createLabelDom_(Blockly.Msg.COLOUR_HUE_LABEL); + div.appendChild(hueElements[0]); + this.hueReadout_ = hueElements[1]; + this.hueSlider_ = document.createElement('input'); + this.hueSlider_.type = 'range'; + this.hueSlider_.min = 0; + this.hueSlider_.max = 360; + this.hueSlider_.className = 'scratchColourSlider'; + div.appendChild(this.hueSlider_); + + var saturationElements = + this.createLabelDom_(Blockly.Msg.COLOUR_SATURATION_LABEL); + div.appendChild(saturationElements[0]); + this.saturationReadout_ = saturationElements[1]; + this.saturationSlider_ = document.createElement('input'); + this.saturationSlider_.type = 'range'; + this.saturationSlider_.step = 0.001; + this.saturationSlider_.min = 0; + this.saturationSlider_.max = 1.0; + this.saturationSlider_.className = 'scratchColourSlider'; + div.appendChild(this.saturationSlider_); + + var brightnessElements = + this.createLabelDom_(Blockly.Msg.COLOUR_BRIGHTNESS_LABEL); + div.appendChild(brightnessElements[0]); + this.brightnessReadout_ = brightnessElements[1]; + this.brightnessSlider_ = document.createElement('input'); + this.brightnessSlider_.type = 'range'; + this.brightnessSlider_.min = 0; + this.brightnessSlider_.max = 255; + this.brightnessSlider_.className = 'scratchColourSlider'; + div.appendChild(this.brightnessSlider_); + + if (FieldColourSlider.activateEyedropper_) { + var button = document.createElement('button'); + button.setAttribute('class', 'scratchEyedropper'); + var image = document.createElement('img'); + image.src = Blockly.getMainWorkspace().options.pathToMedia + this.EYEDROPPER_PATH; + button.appendChild(image); + div.appendChild(button); + this.eyedropperEventData_ = + Blockly.browserEvents.conditionalBind(button, 'click', this, + this.activateEyedropperInternal_); } - if (colour !== null) { - thisField.setValue(colour, true); - } - }; -}; - -/** - * Activate the eyedropper, passing in a callback for setting the field value. - * @private - */ -Blockly.FieldColourSlider.prototype.activateEyedropperInternal_ = function() { - var thisField = this; - Blockly.FieldColourSlider.activateEyedropper_(function(value) { - // Update the internal hue/saturation/brightness values so sliders update. - var hsv = goog.color.hexToHsv(value); - thisField.hue_ = hsv[0]; - thisField.saturation_ = hsv[1]; - thisField.brightness_ = hsv[2]; - thisField.setValue(value); - }); -}; - -/** - * Create hue, saturation and brightness sliders under the colour field. - * @private - */ -Blockly.FieldColourSlider.prototype.showEditor_ = function() { - Blockly.DropDownDiv.hideWithoutAnimation(); - Blockly.DropDownDiv.clearContent(); - var div = Blockly.DropDownDiv.getContentDiv(); - - // Init color component values that are used while the editor is open - // in order to keep the slider values stable. - var hsv = goog.color.hexToHsv(this.getValue()); - this.hue_ = hsv[0]; - this.saturation_ = hsv[1]; - this.brightness_ = hsv[2]; - - var hueElements = this.createLabelDom_(Blockly.Msg.COLOUR_HUE_LABEL); - div.appendChild(hueElements[0]); - this.hueReadout_ = hueElements[1]; - this.hueSlider_ = new goog.ui.Slider(); - this.hueSlider_.setUnitIncrement(5); - this.hueSlider_.setMinimum(0); - this.hueSlider_.setMaximum(360); - this.hueSlider_.setMoveToPointEnabled(true); - this.hueSlider_.render(div); - var saturationElements = - this.createLabelDom_(Blockly.Msg.COLOUR_SATURATION_LABEL); - div.appendChild(saturationElements[0]); - this.saturationReadout_ = saturationElements[1]; - this.saturationSlider_ = new goog.ui.Slider(); - this.saturationSlider_.setMoveToPointEnabled(true); - this.saturationSlider_.setUnitIncrement(0.01); - this.saturationSlider_.setStep(0.001); - this.saturationSlider_.setMinimum(0); - this.saturationSlider_.setMaximum(1.0); - this.saturationSlider_.render(div); + Blockly.DropDownDiv.setColour('#ffffff', '#dddddd'); + Blockly.DropDownDiv.showPositionedByBlock(this, this.sourceBlock_); - var brightnessElements = - this.createLabelDom_(Blockly.Msg.COLOUR_BRIGHTNESS_LABEL); - div.appendChild(brightnessElements[0]); - this.brightnessReadout_ = brightnessElements[1]; - this.brightnessSlider_ = new goog.ui.Slider(); - this.brightnessSlider_.setUnitIncrement(2); - this.brightnessSlider_.setMinimum(0); - this.brightnessSlider_.setMaximum(255); - this.brightnessSlider_.setMoveToPointEnabled(true); - this.brightnessSlider_.render(div); + // Set value updates the slider positions + // Do this before attaching callbacks to avoid extra events from initial set + this.setValue(this.getValue()); - if (Blockly.FieldColourSlider.activateEyedropper_) { - var button = document.createElement('button'); - button.setAttribute('class', 'scratchEyedropper'); - var image = document.createElement('img'); - image.src = Blockly.mainWorkspace.options.pathToMedia + Blockly.FieldColourSlider.EYEDROPPER_PATH; - button.appendChild(image); - div.appendChild(button); - Blockly.FieldColourSlider.eyedropperEventData_ = - Blockly.bindEventWithChecks_(button, 'click', this, - this.activateEyedropperInternal_); + this.hueChangeEventKey_ = Blockly.browserEvents.bind( + this.hueSlider_, 'input', this, this.sliderCallbackFactory_('hue')); + this.saturationChangeEventKey_ = Blockly.browserEvents.bind( + this.saturationSlider_, 'input', this, this.sliderCallbackFactory_('saturation')); + this.brightnessChangeEventKey_ = Blockly.browserEvents.bind( + this.brightnessSlider_, 'input', this, this.sliderCallbackFactory_('brightness')); } - Blockly.DropDownDiv.setColour('#ffffff', '#dddddd'); - Blockly.DropDownDiv.setCategory(this.sourceBlock_.parentBlock_.getCategory()); - Blockly.DropDownDiv.showPositionedByBlock(this, this.sourceBlock_); - - // Set value updates the slider positions - // Do this before attaching callbacks to avoid extra events from initial set - this.setValue(this.getValue()); - - // Enable callbacks for the sliders - this.sliderCallbacksEnabled_ = true; + dispose() { + if (this.hueChangeEventKey_) { + Blockly.browserEvents.unbind(this.hueChangeEventKey_); + } + if (this.saturationChangeEventKey_) { + Blockly.browserEvents.unbind(this.saturationChangeEventKey_); + } + if (this.brightnessChangeEventKey_) { + Blockly.browserEvents.unbind(this.brightnessChangeEventKey_); + } + if (this.eyedropperEventData_) { + Blockly.browserEvents.unbind(this.eyedropperEventData_); + } + Blockly.Events.setGroup(false); + super.dispose(); + } - Blockly.FieldColourSlider.hueChangeEventKey_ = goog.events.listen(this.hueSlider_, - goog.ui.Component.EventType.CHANGE, - this.sliderCallbackFactory_('hue')); - Blockly.FieldColourSlider.saturationChangeEventKey_ = goog.events.listen(this.saturationSlider_, - goog.ui.Component.EventType.CHANGE, - this.sliderCallbackFactory_('saturation')); - Blockly.FieldColourSlider.brightnessChangeEventKey_ = goog.events.listen(this.brightnessSlider_, - goog.ui.Component.EventType.CHANGE, - this.sliderCallbackFactory_('brightness')); -}; + // From Closure + rgbToHsv(red, green, blue) { + const max = Math.max(Math.max(red, green), blue); + const min = Math.min(Math.min(red, green), blue); + let hue; + let saturation; + const value = max; + if (min == max) { + hue = 0; + saturation = 0; + } else { + const delta = (max - min); + saturation = delta / max; + + if (red == max) { + hue = (green - blue) / delta; + } else if (green == max) { + hue = 2 + ((blue - red) / delta); + } else { + hue = 4 + ((red - green) / delta); + } + hue *= 60; + if (hue < 0) { + hue += 360; + } + if (hue > 360) { + hue -= 360; + } + } -Blockly.FieldColourSlider.prototype.dispose = function() { - if (Blockly.FieldColourSlider.hueChangeEventKey_) { - goog.events.unlistenByKey(Blockly.FieldColourSlider.hueChangeEventKey_); - } - if (Blockly.FieldColourSlider.saturationChangeEventKey_) { - goog.events.unlistenByKey(Blockly.FieldColourSlider.saturationChangeEventKey_); - } - if (Blockly.FieldColourSlider.brightnessChangeEventKey_) { - goog.events.unlistenByKey(Blockly.FieldColourSlider.brightnessChangeEventKey_); - } - if (Blockly.FieldColourSlider.eyedropperEventData_) { - Blockly.unbindEvent_(Blockly.FieldColourSlider.eyedropperEventData_); + return {hue, saturation, value}; } - Blockly.Events.setGroup(false); - Blockly.FieldColourSlider.superClass_.dispose.call(this); -}; +} -Blockly.Field.register('field_colour_slider', Blockly.FieldColourSlider); +Blockly.fieldRegistry.register('field_colour_slider', FieldColourSlider); diff --git a/package-lock.json b/package-lock.json index d3bd004fe9..159c22b5b1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,6 +10,7 @@ "license": "Apache-2.0", "dependencies": { "@blockly/continuous-toolbox": "^5.0.15", + "@blockly/field-colour": "^4.0.2", "blockly": "^10.0.0" }, "devDependencies": { @@ -132,6 +133,17 @@ "blockly": "^10.0.0" } }, + "node_modules/@blockly/field-colour": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@blockly/field-colour/-/field-colour-4.0.2.tgz", + "integrity": "sha512-3gQufdo+40uFHbHn6Kyyw1ZVbgQffC7Ko8erVD8BcQwPgnusYIMgrqjn86nv2vgCH2kwH1ilg6xJfkDdqc/asw==", + "engines": { + "node": ">=8.0.0" + }, + "peerDependencies": { + "blockly": "^10.4.3" + } + }, "node_modules/@commitlint/cli": { "version": "17.8.1", "resolved": "https://registry.npmjs.org/@commitlint/cli/-/cli-17.8.1.tgz", @@ -1334,9 +1346,9 @@ } }, "node_modules/blockly": { - "version": "10.3.0", - "resolved": "https://registry.npmjs.org/blockly/-/blockly-10.3.0.tgz", - "integrity": "sha512-+95241EVK5o80F3b/iDP61+LfwKwueqscRyh/JfGKPRA4Tlcg8nngu1DdMhOyVCy8Z58AyXuFJ+96+QlCFx5MQ==", + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/blockly/-/blockly-10.4.3.tgz", + "integrity": "sha512-+opfBmQnSiv7vTiY/TkDEBOslxUyfj8luS3S+qs1NnQKjInC+Waf2l9cNsMh9J8BMkmiCIT+Ed/3mmjIaL9wug==", "dependencies": { "jsdom": "22.1.0" } @@ -7116,6 +7128,12 @@ "integrity": "sha512-XXW+ETvPljsq9A5KdXO/aKnVbEIy+ANlgfQmPN9Vztl4U0NdQ3QvA/PtZRlZ6ISJdEkM4GnhTXOIIO+0qDqJ8w==", "requires": {} }, + "@blockly/field-colour": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@blockly/field-colour/-/field-colour-4.0.2.tgz", + "integrity": "sha512-3gQufdo+40uFHbHn6Kyyw1ZVbgQffC7Ko8erVD8BcQwPgnusYIMgrqjn86nv2vgCH2kwH1ilg6xJfkDdqc/asw==", + "requires": {} + }, "@commitlint/cli": { "version": "17.8.1", "resolved": "https://registry.npmjs.org/@commitlint/cli/-/cli-17.8.1.tgz", @@ -8135,9 +8153,9 @@ "dev": true }, "blockly": { - "version": "10.3.0", - "resolved": "https://registry.npmjs.org/blockly/-/blockly-10.3.0.tgz", - "integrity": "sha512-+95241EVK5o80F3b/iDP61+LfwKwueqscRyh/JfGKPRA4Tlcg8nngu1DdMhOyVCy8Z58AyXuFJ+96+QlCFx5MQ==", + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/blockly/-/blockly-10.4.3.tgz", + "integrity": "sha512-+opfBmQnSiv7vTiY/TkDEBOslxUyfj8luS3S+qs1NnQKjInC+Waf2l9cNsMh9J8BMkmiCIT+Ed/3mmjIaL9wug==", "requires": { "jsdom": "22.1.0" } diff --git a/package.json b/package.json index ab6450e05f..3f052b4f49 100644 --- a/package.json +++ b/package.json @@ -28,6 +28,7 @@ }, "dependencies": { "@blockly/continuous-toolbox": "^5.0.15", + "@blockly/field-colour": "^4.0.2", "blockly": "^10.0.0" } } diff --git a/src/constants.js b/src/constants.js index b1bf5d3da4..39cc18d098 100644 --- a/src/constants.js +++ b/src/constants.js @@ -37,3 +37,6 @@ export {PROCEDURES_PROTOTYPE_BLOCK_TYPE}; */ const PROCEDURES_CALL_BLOCK_TYPE = 'procedures_call'; export {PROCEDURES_CALL_BLOCK_TYPE}; + +const OUTPUT_SHAPE_ROUND = 2; +export {OUTPUT_SHAPE_ROUND}; diff --git a/src/index.js b/src/index.js index b945430684..500a560126 100644 --- a/src/index.js +++ b/src/index.js @@ -5,6 +5,7 @@ */ import * as Blockly from 'blockly/core'; +import '../blocks_common/colour.js'; import '../blocks_common/math.js'; import '../blocks_common/text.js'; import '../blocks_vertical/vertical_extensions.js'; @@ -31,6 +32,7 @@ export * from 'blockly'; export * from './categories.js'; export * from './procedures.js'; export * from '../core/colours.js'; +export * from '../core/field_colour_slider.js'; export * from '../msg/scratch_msgs.js'; export {scratchBlocksUtils}; From e603c67cf7c55ff09c292991ef6b9f9ac3aae0f9 Mon Sep 17 00:00:00 2001 From: Aaron Dodson Date: Fri, 26 Apr 2024 12:21:23 -0700 Subject: [PATCH 026/130] fix: reenable support for checkboxes in the flyout (#43) * fix: reenable support for checkboxes in the flyout * refactor: use a map instead of an object for storing checkboxes * chore: remove debugging code * refactor: improve variable names for checkbox position * chore: fix line wrapping indentation * refactor: don't store checkbox wrapper objects on blocks --- blocks_vertical/data.js | 4 +- blocks_vertical/looks.js | 6 +- blocks_vertical/motion.js | 6 +- blocks_vertical/sensing.js | 10 +- blocks_vertical/sound.js | 1 + src/checkable_continuous_flyout.js | 204 +++++++++++++++++++++++++++++ src/index.js | 5 +- 7 files changed, 221 insertions(+), 15 deletions(-) create mode 100644 src/checkable_continuous_flyout.js diff --git a/blocks_vertical/data.js b/blocks_vertical/data.js index e8754c305a..7e18f2fe7f 100644 --- a/blocks_vertical/data.js +++ b/blocks_vertical/data.js @@ -42,9 +42,9 @@ Blockly.Blocks['data_variable'] = { } ], "category": Categories.data, - "checkboxInFlyout": true, "extensions": ["contextMenu_getVariableBlock", "colours_data", "output_string"] }); + this.checkboxInFlyout = true; } }; @@ -158,8 +158,8 @@ Blockly.Blocks['data_listcontents'] = { ], "category": Categories.dataLists, "extensions": ["contextMenu_getListBlock", "colours_data_lists", "output_string"], - "checkboxInFlyout": true }); + this.checkboxInFlyout = true; } }; diff --git a/blocks_vertical/looks.js b/blocks_vertical/looks.js index d0f0a12b90..c2c276ff17 100644 --- a/blocks_vertical/looks.js +++ b/blocks_vertical/looks.js @@ -282,9 +282,9 @@ Blockly.Blocks['looks_size'] = { this.jsonInit({ "message0": Blockly.Msg.LOOKS_SIZE, "category": Categories.looks, - "checkboxInFlyout": true, "extensions": ["colours_looks", "output_number"] }); + this.checkboxInFlyout = true; } }; @@ -510,9 +510,9 @@ Blockly.Blocks['looks_backdropnumbername'] = { } ], "category": Categories.looks, - "checkboxInFlyout": true, "extensions": ["colours_looks", "output_number"] }); + this.checkboxInFlyout = true; } }; @@ -535,9 +535,9 @@ Blockly.Blocks['looks_costumenumbername'] = { } ], "category": Categories.looks, - "checkboxInFlyout": true, "extensions": ["colours_looks", "output_number"] }); + this.checkboxInFlyout = true; } }; diff --git a/blocks_vertical/motion.js b/blocks_vertical/motion.js index 156a941945..a64a715e7b 100644 --- a/blocks_vertical/motion.js +++ b/blocks_vertical/motion.js @@ -429,9 +429,9 @@ Blockly.Blocks['motion_xposition'] = { this.jsonInit({ "message0": Blockly.Msg.MOTION_XPOSITION, "category": Categories.motion, - "checkboxInFlyout": true, "extensions": ["colours_motion", "output_number"] }); + this.checkboxInFlyout = true; } }; @@ -444,9 +444,9 @@ Blockly.Blocks['motion_yposition'] = { this.jsonInit({ "message0": Blockly.Msg.MOTION_YPOSITION, "category": Categories.motion, - "checkboxInFlyout": true, "extensions": ["colours_motion", "output_number"] }); + this.checkboxInFlyout = true; } }; @@ -459,9 +459,9 @@ Blockly.Blocks['motion_direction'] = { this.jsonInit({ "message0": Blockly.Msg.MOTION_DIRECTION, "category": Categories.motion, - "checkboxInFlyout": true, "extensions": ["colours_motion", "output_number"] }); + this.checkboxInFlyout = true; } }; diff --git a/blocks_vertical/sensing.js b/blocks_vertical/sensing.js index 0fb53ef43f..dfd2ed103f 100644 --- a/blocks_vertical/sensing.js +++ b/blocks_vertical/sensing.js @@ -179,9 +179,9 @@ Blockly.Blocks['sensing_answer'] = { this.jsonInit({ "message0": Blockly.Msg.SENSING_ANSWER, "category": Categories.sensing, - "checkboxInFlyout": true, "extensions": ["colours_sensing", "output_number"] }); + this.checkboxInFlyout = true; } }; @@ -343,9 +343,9 @@ Blockly.Blocks['sensing_loudness'] = { this.jsonInit({ "message0": Blockly.Msg.SENSING_LOUDNESS, "category": Categories.sensing, - "checkboxInFlyout": true, "extensions": ["colours_sensing", "output_number"] }); + this.checkboxInFlyout = true; } }; @@ -374,9 +374,9 @@ Blockly.Blocks['sensing_timer'] = { this.jsonInit({ "message0": Blockly.Msg.SENSING_TIMER, "category": Categories.sensing, - "checkboxInFlyout": true, "extensions": ["colours_sensing", "output_number"] }); + this.checkboxInFlyout = true; } }; @@ -480,9 +480,9 @@ Blockly.Blocks['sensing_current'] = { } ], "category": Categories.sensing, - "checkboxInFlyout": true, "extensions": ["colours_sensing", "output_number"] }); + this.checkboxInFlyout = true; } }; @@ -509,9 +509,9 @@ Blockly.Blocks['sensing_username'] = { this.jsonInit({ "message0": Blockly.Msg.SENSING_USERNAME, "category": Categories.sensing, - "checkboxInFlyout": true, "extensions": ["colours_sensing", "output_number"] }); + this.checkboxInFlyout = true; } }; diff --git a/blocks_vertical/sound.js b/blocks_vertical/sound.js index fb39ed2eea..bdb5697e75 100644 --- a/blocks_vertical/sound.js +++ b/blocks_vertical/sound.js @@ -205,5 +205,6 @@ Blockly.Blocks['sound_volume'] = { "checkboxInFlyout": true, "extensions": ["colours_sounds", "output_number"] }); + this.checkboxInFlyout = true; } }; diff --git a/src/checkable_continuous_flyout.js b/src/checkable_continuous_flyout.js new file mode 100644 index 0000000000..b958ab633f --- /dev/null +++ b/src/checkable_continuous_flyout.js @@ -0,0 +1,204 @@ +import * as Blockly from 'blockly'; +import {ContinuousFlyout} from '@blockly/continuous-toolbox'; + +export class CheckableContinuousFlyout extends ContinuousFlyout { + /** + * Size of a checkbox next to a variable reporter. + * @type {number} + * @const + */ + static CHECKBOX_SIZE = 25; + + /** + * Amount of touchable padding around reporter checkboxes. + * @type {number} + * @const + */ + static CHECKBOX_TOUCH_PADDING = 12; + + /** + * SVG path data for checkmark in checkbox. + * @type {string} + * @const + */ + static CHECKMARK_PATH = + 'M' + CheckableContinuousFlyout.CHECKBOX_SIZE / 4 + + ' ' + CheckableContinuousFlyout.CHECKBOX_SIZE / 2 + + 'L' + 5 * CheckableContinuousFlyout.CHECKBOX_SIZE / 12 + + ' ' + 2 * CheckableContinuousFlyout.CHECKBOX_SIZE / 3 + + 'L' + 3 * CheckableContinuousFlyout.CHECKBOX_SIZE / 4 + + ' ' + CheckableContinuousFlyout.CHECKBOX_SIZE / 3; + + /** + * Size of the checkbox corner radius + * @type {number} + * @const + */ + static CHECKBOX_CORNER_RADIUS = 5; + + /** + * @type {number} + * @const + */ + static CHECKBOX_MARGIN = ContinuousFlyout.prototype.MARGIN; + + /** + * Total additional width of a row that contains a checkbox. + * @type {number} + * @const + */ + static CHECKBOX_SPACE_X = + CheckableContinuousFlyout.CHECKBOX_SIZE + + 2 * CheckableContinuousFlyout.CHECKBOX_MARGIN; + + + constructor(workspaceOptions) { + super(workspaceOptions); + CheckableContinuousFlyout.CHECKBOX_MARGIN = this.MARGIN; + + /** + * Map of checkboxes that correspond to monitored blocks. + * Each element is an object containing the SVG for the checkbox, a boolean + * for its checked state, and the block the checkbox is associated with. + * @type {!Object.} + * @private + */ + this.checkboxes_ = new Map(); + } + + show(flyoutDef) { + this.clearOldCheckboxes(); + super.show(flyoutDef); + } + + clearOldCheckboxes() { + for (const checkbox of this.checkboxes_.values()) { + checkbox.svgRoot.remove(); + } + this.checkboxes_.clear(); + } + + addBlockListeners_(root, block, rect) { + if (block.checkboxInFlyout) { + const coordinates = block.getRelativeToSurfaceXY(); + const checkbox = this.createCheckbox_( + block, coordinates.x, coordinates.y, block.getHeightWidth()); + let moveX = coordinates.x; + if (this.RTL) { + moveX -= (CheckableContinuousFlyout.CHECKBOX_SIZE + CheckableContinuousFlyout.CHECKBOX_MARGIN); + } else { + moveX += CheckableContinuousFlyout.CHECKBOX_SIZE + CheckableContinuousFlyout.CHECKBOX_MARGIN; + } + block.moveBy(moveX, 0); + this.listeners.push(Blockly.browserEvents.bind(checkbox.svgRoot, + 'mousedown', null, this.checkboxClicked_(checkbox))); + } + super.addBlockListeners_(root, block, rect); + } + + /** + * Respond to a click on a checkbox in the flyout. + * @param {!Object} checkboxObj An object containing the svg element of the + * checkbox, a boolean for the state of the checkbox, and the block the + * checkbox is associated with. + * @return {!Function} Function to call when checkbox is clicked. + * @private + */ + checkboxClicked_(checkboxObj) { + return function(e) { + this.setCheckboxState(checkboxObj.block.id, !checkboxObj.clicked); + // This event has been handled. No need to bubble up to the document. + e.stopPropagation(); + e.preventDefault(); + }.bind(this); + } + + /** + * Create and place a checkbox corresponding to the given block. + * @param {!Blockly.Block} block The block to associate the checkbox to. + * @param {number} cursorX The x position of the cursor during this layout pass. + * @param {number} cursorY The y position of the cursor during this layout pass. + * @param {!{height: number, width: number}} blockHW The height and width of the + * block. + * @private + */ + createCheckbox_(block, cursorX, cursorY, blockHW) { + var checkboxState = this.getCheckboxState(block.id); + var svgRoot = block.getSvgRoot(); + var extraSpace = CheckableContinuousFlyout.CHECKBOX_SIZE + CheckableContinuousFlyout.CHECKBOX_MARGIN; + var xOffset = this.RTL ? this.getWidth() / this.workspace_.scale - extraSpace : cursorX; + var yOffset = cursorY + blockHW.height / 2 - CheckableContinuousFlyout.CHECKBOX_SIZE / 2; + var touchMargin = CheckableContinuousFlyout.CHECKBOX_TOUCH_PADDING; + var checkboxGroup = Blockly.utils.dom.createSvgElement('g', + { + 'transform': `translate(${xOffset}, ${yOffset})`, + 'fill': 'transparent', + }, null); + Blockly.utils.dom.createSvgElement('rect', + { + 'class': 'blocklyFlyoutCheckbox', + 'height': CheckableContinuousFlyout.CHECKBOX_SIZE, + 'width': CheckableContinuousFlyout.CHECKBOX_SIZE, + 'rx': CheckableContinuousFlyout.CHECKBOX_CORNER_RADIUS, + 'ry': CheckableContinuousFlyout.CHECKBOX_CORNER_RADIUS + }, checkboxGroup); + Blockly.utils.dom.createSvgElement('path', + { + 'class': 'blocklyFlyoutCheckboxPath', + 'd': CheckableContinuousFlyout.CHECKMARK_PATH + }, checkboxGroup); + Blockly.utils.dom.createSvgElement('rect', + { + 'class': 'blocklyTouchTargetBackground', + 'x': -touchMargin + 'px', + 'y': -touchMargin + 'px', + 'height': CheckableContinuousFlyout.CHECKBOX_SIZE + 2 * touchMargin, + 'width': CheckableContinuousFlyout.CHECKBOX_SIZE + 2 * touchMargin, + }, checkboxGroup); + var checkboxObj = {svgRoot: checkboxGroup, clicked: checkboxState, block: block}; + + if (checkboxState) { + Blockly.utils.dom.addClass((checkboxObj.svgRoot), 'checked'); + } + + this.workspace_.getCanvas().insertBefore(checkboxGroup, svgRoot); + this.checkboxes_.set(block.id, checkboxObj); + return checkboxObj; + } + + /** + * Set the state of a checkbox by block ID. + * @param {string} blockId ID of the block whose checkbox should be set + * @param {boolean} value Value to set the checkbox to. + * @public + */ + setCheckboxState(blockId, value) { + var checkboxObj = this.checkboxes_.get(blockId); + if (!checkboxObj || checkboxObj.clicked === value) { + return; + } + + var oldValue = checkboxObj.clicked; + checkboxObj.clicked = value; + + if (checkboxObj.clicked) { + Blockly.utils.dom.addClass(checkboxObj.svgRoot, 'checked'); + } else { + Blockly.utils.dom.removeClass(checkboxObj.svgRoot, 'checked'); + } + + Blockly.Events.fire(new Blockly.Events.BlockChange( + checkboxObj.block, 'checkbox', null, oldValue, value)); + } + + /** + * Gets the checkbox state for a block + * @param {string} blockId The ID of the block in question. + * @return {boolean} Whether the block is checked. + * @public + */ + getCheckboxState() { + // Patched by scratch-gui in src/lib/blocks.js. + return false; + } +} diff --git a/src/index.js b/src/index.js index 500a560126..3e4031ca42 100644 --- a/src/index.js +++ b/src/index.js @@ -25,7 +25,7 @@ import { ContinuousFlyout, ContinuousMetrics, } from '@blockly/continuous-toolbox'; - +import {CheckableContinuousFlyout} from './checkable_continuous_flyout.js'; import './scratch_continuous_category.js'; export * from 'blockly'; @@ -35,12 +35,13 @@ export * from '../core/colours.js'; export * from '../core/field_colour_slider.js'; export * from '../msg/scratch_msgs.js'; export {scratchBlocksUtils}; +export {CheckableContinuousFlyout}; export function inject(container, options) { Object.assign(options, { plugins: { toolbox: ContinuousToolbox, - flyoutsVerticalToolbox: ContinuousFlyout, + flyoutsVerticalToolbox: CheckableContinuousFlyout, metricsManager: ContinuousMetrics, }, }); From 49663ed2f823ea45a04c0201d467d4e06e0d7078 Mon Sep 17 00:00:00 2001 From: Aaron Dodson Date: Fri, 26 Apr 2024 14:43:51 -0700 Subject: [PATCH 027/130] fix: more closely align flyout layout with Scratch (#45) --- src/checkable_continuous_flyout.js | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/checkable_continuous_flyout.js b/src/checkable_continuous_flyout.js index b958ab633f..fc2db632b1 100644 --- a/src/checkable_continuous_flyout.js +++ b/src/checkable_continuous_flyout.js @@ -54,6 +54,9 @@ export class CheckableContinuousFlyout extends ContinuousFlyout { constructor(workspaceOptions) { super(workspaceOptions); + this.tabWidth_ = 0; + this.MARGIN = 10; + this.GAP_Y = 8; CheckableContinuousFlyout.CHECKBOX_MARGIN = this.MARGIN; /** @@ -201,4 +204,8 @@ export class CheckableContinuousFlyout extends ContinuousFlyout { // Patched by scratch-gui in src/lib/blocks.js. return false; } + + getFlyoutScale() { + return 0.675; + } } From b53eaddcf2ca261ea5798f342e0ec600bf60ca19 Mon Sep 17 00:00:00 2001 From: Aaron Dodson Date: Fri, 26 Apr 2024 14:45:11 -0700 Subject: [PATCH 028/130] fix: display icons in the toolbox for extension categories (#47) --- core/css.js | 6 ++++++ src/scratch_continuous_category.js | 15 +++++++++++---- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/core/css.js b/core/css.js index 6eb7d6d266..2ec49ad874 100644 --- a/core/css.js +++ b/core/css.js @@ -1275,6 +1275,12 @@ const styles = ` .scratchCategoryMenuItem:hover { color: $colour_toolboxHover !important; } + + .categoryIconBubble { + margin: 0 auto 0.125rem; + width: 1.25rem; + height: 1.25rem; + } `; Blockly.Css.register(styles); diff --git a/src/scratch_continuous_category.js b/src/scratch_continuous_category.js index 1a29b82118..dac529127a 100644 --- a/src/scratch_continuous_category.js +++ b/src/scratch_continuous_category.js @@ -3,11 +3,18 @@ import {ContinuousCategory} from '@blockly/continuous-toolbox'; class ScratchContinuousCategory extends ContinuousCategory { createIconDom_() { - const icon = super.createIconDom_(); - icon.style.border = `1px solid ${this.toolboxItemDef_['secondaryColour']}`; - return icon; + if (this.toolboxItemDef_.iconURI) { + const icon = document.createElement('img'); + icon.src = this.toolboxItemDef_.iconURI; + icon.className = 'categoryIconBubble'; + return icon; + } else { + const icon = super.createIconDom_(); + icon.style.border = `1px solid ${this.toolboxItemDef_['secondaryColour']}`; + return icon; + } } - + setSelected(isSelected) { super.setSelected(isSelected); // Prevent hardcoding the background color to grey. From 48e931fa9de3e31b18f088557c2cbfd0738b4bc6 Mon Sep 17 00:00:00 2001 From: Aaron Dodson Date: Fri, 26 Apr 2024 15:13:46 -0700 Subject: [PATCH 029/130] fix: reenable the vertical separator field (#46) * fix: reenable the vertical separator field * refactor: clean up field_vertical_separator.js --- core/field_vertical_separator.js | 209 +++++++++++++------------------ src/index.js | 1 + 2 files changed, 88 insertions(+), 122 deletions(-) diff --git a/core/field_vertical_separator.js b/core/field_vertical_separator.js index cde897d61f..9d0b6d045c 100644 --- a/core/field_vertical_separator.js +++ b/core/field_vertical_separator.js @@ -22,140 +22,105 @@ * @fileoverview Vertical separator field. Draws a vertical line. * @author ericr@media.mit.edu (Eric Rosenbaum) */ -'use strict'; - -goog.provide('Blockly.FieldVerticalSeparator'); - -goog.require('Blockly.Field'); -goog.require('goog.dom'); -goog.require('goog.math.Size'); - +import * as Blockly from 'blockly/core'; /** * Class for a vertical separator line. * @extends {Blockly.Field} * @constructor */ -Blockly.FieldVerticalSeparator = function() { - this.sourceBlock_ = null; - this.width_ = 1; - this.height_ = Blockly.BlockSvg.ICON_SEPARATOR_HEIGHT; - this.size_ = new goog.math.Size(this.width_, this.height_); -}; -goog.inherits(Blockly.FieldVerticalSeparator, Blockly.Field); - -/** - * Construct a FieldVerticalSeparator from a JSON arg object. - * @param {!Object} _element A JSON object with options (unused, but passed in - * by Field.fromJson). - * @returns {!Blockly.FieldVerticalSeparator} The new field instance. - * @package - * @nocollapse - */ -Blockly.FieldVerticalSeparator.fromJson = function( - /* eslint-disable no-unused-vars */ _element - /* eslint-enable no-unused-vars */) { - return new Blockly.FieldVerticalSeparator(); -}; -/** - * Editable fields are saved by the XML renderer, non-editable fields are not. - */ -Blockly.FieldVerticalSeparator.prototype.EDITABLE = false; - -/** - * Install this field on a block. - */ -Blockly.FieldVerticalSeparator.prototype.init = function() { - if (this.fieldGroup_) { - // Image has already been initialized once. - return; +class FieldVerticalSeparator extends Blockly.Field { + constructor() { + super(Blockly.Field.SKIP_SETUP); + /** + * Editable fields are saved by the XML renderer, non-editable fields are not. + */ + this.EDITABLE = false; } - // Build the DOM. - /** @type {SVGElement} */ - this.fieldGroup_ = Blockly.utils.createSvgElement('g', {}, null); - if (!this.visible_) { - this.fieldGroup_.style.display = 'none'; - } - /** @type {SVGElement} */ - this.lineElement_ = Blockly.utils.createSvgElement('line', - { - 'stroke': this.sourceBlock_.getColourSecondary(), - 'stroke-linecap': 'round', - 'x1': 0, - 'y1': 0, - 'x2': 0, - 'y2': this.height_ - }, this.fieldGroup_); - - this.sourceBlock_.getSvgRoot().appendChild(this.fieldGroup_); -}; -/** - * Set the height of the line element, without adjusting the field's height. - * This allows the line's height to be changed without causing it to be - * centered with the new height (needed for correct rendering of hat blocks). - * @param {number} newHeight the new height for the line. - * @package - */ -Blockly.FieldVerticalSeparator.prototype.setLineHeight = function(newHeight) { - this.lineElement_.setAttribute('y2', newHeight); -}; + /** + * Construct a FieldVerticalSeparator from a JSON arg object. + * @param {!Object} _element A JSON object with options (unused, but passed in + * by Field.fromJson). + * @returns {!Blockly.FieldVerticalSeparator} The new field instance. + * @package + * @nocollapse + */ + static fromJson = function( + /* eslint-disable no-unused-vars */ _element + /* eslint-enable no-unused-vars */) { + return new FieldVerticalSeparator(); + } -/** - * Dispose of all DOM objects belonging to this text. - */ -Blockly.FieldVerticalSeparator.prototype.dispose = function() { - goog.dom.removeNode(this.fieldGroup_); - this.fieldGroup_ = null; - this.lineElement_ = null; -}; + /** + * Install this field on a block. + */ + initView() { + const height = 10 * this.getConstants().GRID_UNIT; + this.size_ = new Blockly.utils.Size(1, height); + + /** @type {SVGElement} */ + this.lineElement_ = Blockly.utils.dom.createSvgElement('line', + { + 'stroke': this.sourceBlock_.getColourSecondary(), + 'stroke-linecap': 'round', + 'x1': 0, + 'y1': 0, + 'x2': 0, + 'y2': height + }, this.fieldGroup_); + } -/** - * Get the value of this field. A no-op in this case. - * @return {string} null. - * @override - */ -Blockly.FieldVerticalSeparator.prototype.getValue = function() { - return null; -}; + /** + * Set the height of the line element, without adjusting the field's height. + * This allows the line's height to be changed without causing it to be + * centered with the new height (needed for correct rendering of hat blocks). + * @param {number} newHeight the new height for the line. + * @package + */ + setLineHeight(newHeight) { + this.lineElement_.setAttribute('y2', newHeight); + }; + + /** + * Get the value of this field. A no-op in this case. + * @return {string} null. + * @override + */ + getValue() { + return null; + } -/** - * Set the value of this field. A no-op in this case. - * @param {?string} src New value. - * @override - */ -Blockly.FieldVerticalSeparator.prototype.setValue = function( - /* eslint-disable no-unused-vars */ src - /* eslint-enable no-unused-vars */) { - return; -}; + getText() { + return ''; + } -/** - * Set the text of this field. A no-op in this case. - * @param {?string} alt New text. - * @override - */ -Blockly.FieldVerticalSeparator.prototype.setText = function( - /* eslint-disable no-unused-vars */ alt - /* eslint-enable no-unused-vars */) { - return; -}; + /** + * Set the value of this field. A no-op in this case. + * @param {?string} src New value. + * @override + */ + setValue( + /* eslint-disable no-unused-vars */ src + /* eslint-enable no-unused-vars */) { + return; + } -/** - * Separator lines are fixed width, no need to render. - * @private - */ -Blockly.FieldVerticalSeparator.prototype.render_ = function() { - // NOP -}; + /** + * Separator lines are fixed width, no need to render. + * @private + */ + render_() { + // NOP + } -/** - * Separator lines are fixed width, no need to update. - * @private - */ -Blockly.FieldVerticalSeparator.prototype.updateWidth = function() { - // NOP -}; + /** + * Separator lines are fixed width, no need to update. + * @private + */ + updateWidth() { + // NOP + } +} -Blockly.Field.register( - 'field_vertical_separator', Blockly.FieldVerticalSeparator); +Blockly.fieldRegistry.register('field_vertical_separator', FieldVerticalSeparator); diff --git a/src/index.js b/src/index.js index 3e4031ca42..537976bd12 100644 --- a/src/index.js +++ b/src/index.js @@ -20,6 +20,7 @@ import '../blocks_vertical/sensing.js'; import '../blocks_vertical/sound.js'; import * as scratchBlocksUtils from '../core/scratch_blocks_utils.js'; import '../core/css.js'; +import '../core/field_vertical_separator.js'; import { ContinuousToolbox, ContinuousFlyout, From de62d7752eb80f67a654ae2e87820ad4183e833d Mon Sep 17 00:00:00 2001 From: Aaron Dodson Date: Mon, 29 Apr 2024 13:17:57 -0700 Subject: [PATCH 030/130] fix: reenable the note block and picker field (#48) * fix: reenable the note block and picker field * refactor: clean up the field_note implementation --- blocks_common/note.js | 22 +- core/field_note.js | 1384 ++++++++++++++++++++--------------------- src/index.js | 2 + 3 files changed, 686 insertions(+), 722 deletions(-) diff --git a/blocks_common/note.js b/blocks_common/note.js index f51ca40f14..4fb673964b 100644 --- a/blocks_common/note.js +++ b/blocks_common/note.js @@ -22,15 +22,9 @@ * @fileoverview Note block. * @author ericr@media.mit.edu (Eric Rosenbaum) */ -'use strict'; - -goog.provide('Blockly.Blocks.note'); - -goog.require('Blockly.Blocks'); - -goog.require('Blockly.Colours'); - -goog.require('Blockly.constants'); +import * as Blockly from 'blockly/core'; +import {Colours} from '../core/colours.js'; +import * as Constants from '../src/constants.js'; Blockly.Blocks['note'] = { /** @@ -47,12 +41,12 @@ Blockly.Blocks['note'] = { "value": 60 } ], - "outputShape": Blockly.OUTPUT_SHAPE_ROUND, + "outputShape": Constants.OUTPUT_SHAPE_ROUND, "output": "Number", - "colour": Blockly.Colours.textField, - "colourSecondary": Blockly.Colours.textField, - "colourTertiary": Blockly.Colours.textField, - "colourQuaternary": Blockly.Colours.textField + "colour": Colours.textField, + "colourSecondary": Colours.textField, + "colourTertiary": Colours.textField, + "colourQuaternary": Colours.textField }); } }; diff --git a/core/field_note.js b/core/field_note.js index c3928062d9..b2b51a3960 100644 --- a/core/field_note.js +++ b/core/field_note.js @@ -22,14 +22,7 @@ * @fileoverview Note input field, for selecting a musical note on a piano. * @author ericr@media.mit.edu (Eric Rosenbaum) */ -'use strict'; - -goog.provide('Blockly.FieldNote'); - -goog.require('Blockly.DropDownDiv'); -goog.require('Blockly.FieldTextInput'); -goog.require('goog.math'); -goog.require('goog.userAgent'); +import * as Blockly from 'blockly/core'; /** * Class for a note input field, for selecting a musical note on a piano. @@ -42,809 +35,784 @@ goog.require('goog.userAgent'); * @extends {Blockly.FieldTextInput} * @constructor */ -Blockly.FieldNote = function(opt_value, opt_validator) { - opt_value = (opt_value && !isNaN(opt_value)) ? String(opt_value) : '0'; - Blockly.FieldNote.superClass_.constructor.call( - this, opt_value, opt_validator); - this.addArgType('note'); +export class FieldNote extends Blockly.FieldTextInput { + constructor(opt_value, opt_validator) { + opt_value = (opt_value && !isNaN(opt_value)) ? String(opt_value) : '0'; + super(opt_value, opt_validator); + + /** + * Width of the field. Computed when drawing it, and used for animation. + * @type {number} + * @private + */ + this.fieldEditorWidth_ = 0; + + /** + * Height of the field. Computed when drawing it. + * @type {number} + * @private + */ + this.fieldEditorHeight_ = 0; + + /** + * The piano SVG. + * @type {SVGElement} + * @private + */ + this.pianoSVG_ = null; + + /** + * Array of SVG elements representing the clickable piano keys. + * @type {!Array} + * @private + */ + this.keySVGs_ = []; + + /** + * Note name indicator at the top of the field. + * @type {SVGElement} + * @private + */ + this.noteNameText_ = null; + + /** + * Note name indicator on the low C key. + * @type {SVGElement} + * @private + */ + this.lowCText_ = null; + + /** + * Note name indicator on the low C key. + * @type {SVGElement} + * @private + */ + this.highCText_ = null; + + /** + * Octave number of the currently displayed range of keys. + * @type {number} + * @private + */ + this.displayedOctave_ = null; + + /** + * Current animation position of the piano SVG, as it shifts left or right to + * change octaves. + * @type {number} + * @private + */ + this.animationPos_ = 0; + + /** + * Target position for the animation as the piano SVG shifts left or right. + * @type {number} + * @private + */ + this.animationTarget_ = 0; + + /** + * A flag indicating that the mouse is currently down. Used in combination with + * mouse enter events to update the key selection while dragging. + * @type {boolean} + * @private + */ + this.mouseIsDown_ = false; + + /** + * An array of wrappers for mouse down events on piano keys. + * @type {!Array.} + * @private + */ + this.mouseDownWrappers_ = []; + + /** + * A wrapper for the mouse up event. + * @type {!Array.} + * @private + */ + this.mouseUpWrapper_ = null; + + /** + * An array of wrappers for mouse enter events on piano keys. + * @type {!Array.} + * @private + */ + this.mouseEnterWrappers_ = []; + + /** + * A wrapper for the mouse down event on the octave down button. + * @type {!Array.} + * @private + */ + this.octaveDownMouseDownWrapper_ = null; + + /** + * A wrapper for the mouse down event on the octave up button. + * @type {!Array.} + * @private + */ + this.octaveUpMouseDownWrapper_ = null; + } + + /** + * Inset in pixels of content displayed in the field, caused by parent properties. + * The inset is actually determined by the CSS property blocklyDropDownDiv- it is + * the sum of the padding and border thickness. + */ + static INSET = 5; /** - * Width of the field. Computed when drawing it, and used for animation. + * Height of the top area of the field, in px. * @type {number} - * @private + * @const */ - this.fieldEditorWidth_ = 0; + static TOP_MENU_HEIGHT = 32 - FieldNote.INSET; /** - * Height of the field. Computed when drawing it. + * Padding on the top and sides of the field, in px. * @type {number} - * @private + * @const */ - this.fieldEditorHeight_ = 0; + static EDGE_PADDING = 1; /** - * The piano SVG. - * @type {SVGElement} - * @private + * Height of the drop shadow on the piano, in px. + * @type {number} + * @const */ - this.pianoSVG_ = null; + static SHADOW_HEIGHT = 4; /** - * Array of SVG elements representing the clickable piano keys. - * @type {!Array} - * @private + * Color for the shadow on the piano. + * @type {string} + * @const */ - this.keySVGs_ = []; + static SHADOW_COLOR = '#000'; /** - * Note name indicator at the top of the field. - * @type {SVGElement} - * @private + * Opacity for the shadow on the piano. + * @type {string} + * @const */ - this.noteNameText_ = null; + static SHADOW_OPACITY = .2; /** - * Note name indicator on the low C key. - * @type {SVGElement} - * @private + * A color for the white piano keys. + * @type {string} + * @const */ - this.lowCText_ = null; + static WHITE_KEY_COLOR = '#FFFFFF'; /** - * Note name indicator on the low C key. - * @type {SVGElement} - * @private + * A color for the black piano keys. + * @type {string} + * @const */ - this.highCText_ = null; + static BLACK_KEY_COLOR = '#323133'; /** - * Octave number of the currently displayed range of keys. - * @type {number} - * @private + * A color for stroke around black piano keys. + * @type {string} + * @const */ - this.displayedOctave_ = null; + static BLACK_KEY_STROKE = '#555555'; /** - * Current animation position of the piano SVG, as it shifts left or right to - * change octaves. - * @type {number} - * @private + * A color for the selected state of a piano key. + * @type {string} + * @const */ - this.animationPos_ = 0; + static KEY_SELECTED_COLOR = '#b0d6ff'; /** - * Target position for the animation as the piano SVG shifts left or right. + * The number of white keys in one octave on the piano. * @type {number} - * @private + * @const */ - this.animationTarget_ = 0; + static NUM_WHITE_KEYS = 8; /** - * A flag indicating that the mouse is currently down. Used in combination with - * mouse enter events to update the key selection while dragging. - * @type {boolean} - * @private + * Height of a white piano key, in px. + * @type {string} + * @const */ - this.mouseIsDown_ = false; + static WHITE_KEY_HEIGHT = 72; /** - * An array of wrappers for mouse down events on piano keys. - * @type {!Array.} - * @private + * Width of a white piano key, in px. + * @type {string} + * @const */ - this.mouseDownWrappers_ = []; + static WHITE_KEY_WIDTH = 40; /** - * A wrapper for the mouse up event. - * @type {!Array.} - * @private + * Height of a black piano key, in px. + * @type {string} + * @const */ - this.mouseUpWrapper_ = null; + static BLACK_KEY_HEIGHT = 40; /** - * An array of wrappers for mouse enter events on piano keys. - * @type {!Array.} - * @private + * Width of a black piano key, in px. + * @type {string} + * @const */ - this.mouseEnterWrappers_ = []; + static BLACK_KEY_WIDTH = 32; /** - * A wrapper for the mouse down event on the octave down button. - * @type {!Array.} - * @private + * Radius of the curved bottom corner of a piano key, in px. + * @type {string} + * @const */ - this.octaveDownMouseDownWrapper_ = null; + static KEY_RADIUS = 6; /** - * A wrapper for the mouse down event on the octave up button. - * @type {!Array.} - * @private + * Bottom padding for the labels on C keys. + * @type {string} + * @const */ - this.octaveUpMouseDownWrapper_ = null; -}; -goog.inherits(Blockly.FieldNote, Blockly.FieldTextInput); + static KEY_LABEL_PADDING = 8; -/** - * Inset in pixels of content displayed in the field, caused by parent properties. - * The inset is actually determined by the CSS property blocklyDropDownDiv- it is - * the sum of the padding and border thickness. - */ -Blockly.FieldNote.INSET = 5; - -/** - * Height of the top area of the field, in px. - * @type {number} - * @const - */ -Blockly.FieldNote.TOP_MENU_HEIGHT = 32 - Blockly.FieldNote.INSET; - -/** - * Padding on the top and sides of the field, in px. - * @type {number} - * @const - */ -Blockly.FieldNote.EDGE_PADDING = 1; - -/** - * Height of the drop shadow on the piano, in px. - * @type {number} - * @const - */ -Blockly.FieldNote.SHADOW_HEIGHT = 4; - -/** - * Color for the shadow on the piano. - * @type {string} - * @const - */ -Blockly.FieldNote.SHADOW_COLOR = '#000'; - -/** - * Opacity for the shadow on the piano. - * @type {string} - * @const - */ -Blockly.FieldNote.SHADOW_OPACITY = .2; - -/** - * A color for the white piano keys. - * @type {string} - * @const - */ -Blockly.FieldNote.WHITE_KEY_COLOR = '#FFFFFF'; - -/** - * A color for the black piano keys. - * @type {string} - * @const - */ -Blockly.FieldNote.BLACK_KEY_COLOR = '#323133'; - -/** - * A color for stroke around black piano keys. - * @type {string} - * @const - */ -Blockly.FieldNote.BLACK_KEY_STROKE = '#555555'; - -/** - * A color for the selected state of a piano key. - * @type {string} - * @const - */ -Blockly.FieldNote.KEY_SELECTED_COLOR = '#b0d6ff'; - -/** - * The number of white keys in one octave on the piano. - * @type {number} - * @const - */ -Blockly.FieldNote.NUM_WHITE_KEYS = 8; - -/** - * Height of a white piano key, in px. - * @type {string} - * @const - */ -Blockly.FieldNote.WHITE_KEY_HEIGHT = 72; - -/** - * Width of a white piano key, in px. - * @type {string} - * @const - */ -Blockly.FieldNote.WHITE_KEY_WIDTH = 40; - -/** - * Height of a black piano key, in px. - * @type {string} - * @const - */ -Blockly.FieldNote.BLACK_KEY_HEIGHT = 40; - -/** - * Width of a black piano key, in px. - * @type {string} - * @const - */ -Blockly.FieldNote.BLACK_KEY_WIDTH = 32; - -/** - * Radius of the curved bottom corner of a piano key, in px. - * @type {string} - * @const - */ -Blockly.FieldNote.KEY_RADIUS = 6; - -/** - * Bottom padding for the labels on C keys. - * @type {string} - * @const - */ -Blockly.FieldNote.KEY_LABEL_PADDING = 8; - -/** - * An array of objects with data describing the keys on the piano. - * @type {Array.<{name: String, pitch: Number, isBlack: boolean}>} - * @const - */ -Blockly.FieldNote.KEY_INFO = [ - {name: 'C', pitch: 0}, - {name: 'C♯', pitch: 1, isBlack: true}, - {name: 'D', pitch: 2}, - {name: 'E♭', pitch: 3, isBlack: true}, - {name: 'E', pitch: 4}, - {name: 'F', pitch: 5}, - {name: 'F♯', pitch: 6, isBlack: true}, - {name: 'G', pitch: 7}, - {name: 'G♯', pitch: 8, isBlack: true}, - {name: 'A', pitch: 9}, - {name: 'B♭', pitch: 10, isBlack: true}, - {name: 'B', pitch: 11}, - {name: 'C', pitch: 12} -]; + /** + * An array of objects with data describing the keys on the piano. + * @type {Array.<{name: String, pitch: Number, isBlack: boolean}>} + * @const + */ + static KEY_INFO = [ + {name: 'C', pitch: 0}, + {name: 'C♯', pitch: 1, isBlack: true}, + {name: 'D', pitch: 2}, + {name: 'E♭', pitch: 3, isBlack: true}, + {name: 'E', pitch: 4}, + {name: 'F', pitch: 5}, + {name: 'F♯', pitch: 6, isBlack: true}, + {name: 'G', pitch: 7}, + {name: 'G♯', pitch: 8, isBlack: true}, + {name: 'A', pitch: 9}, + {name: 'B♭', pitch: 10, isBlack: true}, + {name: 'B', pitch: 11}, + {name: 'C', pitch: 12} + ]; -/** - * The MIDI note number of the highest note selectable on the piano. - * @type {number} - * @const - */ -Blockly.FieldNote.MAX_NOTE = 130; + /** + * The MIDI note number of the highest note selectable on the piano. + * @type {number} + * @const + */ + static MAX_NOTE = 130; -/** - * The fraction of the distance to the target location to move the piano at each - * step of the animation. - * @type {number} - * @const - */ -Blockly.FieldNote.ANIMATION_FRACTION = 0.2; + /** + * The fraction of the distance to the target location to move the piano at each + * step of the animation. + * @type {number} + * @const + */ + static ANIMATION_FRACTION = 0.2; -/** - * Path to the arrow svg icon, used on the octave buttons. - * @type {string} - * @const - */ -Blockly.FieldNote.ARROW_SVG_PATH = 'icons/arrow_button.svg'; + /** + * Path to the arrow svg icon, used on the octave buttons. + * @type {string} + * @const + */ + static ARROW_SVG_PATH = 'icons/arrow_button.svg'; -/** - * The size of the square octave buttons. - * @type {number} - * @const - */ -Blockly.FieldNote.OCTAVE_BUTTON_SIZE = 32; + /** + * The size of the square octave buttons. + * @type {number} + * @const + */ + static OCTAVE_BUTTON_SIZE = 32; -/** - * Construct a FieldNote from a JSON arg object. - * @param {!Object} options A JSON object with options. - * @returns {!Blockly.FieldNote} The new field instance. - * @package - * @nocollapse - */ -Blockly.FieldNote.fromJson = function(options) { - return new Blockly.FieldNote(options['note']); -}; + /** + * Construct a FieldNote from a JSON arg object. + * @param {!Object} options A JSON object with options. + * @returns {!Blockly.FieldNote} The new field instance. + * @package + * @nocollapse + */ + static fromJson(options) { + return new FieldNote(options['note']); + } -/** - * Clean up this FieldNote, as well as the inherited FieldTextInput. - * @return {!Function} Closure to call on destruction of the WidgetDiv. - * @private - */ -Blockly.FieldNote.prototype.dispose_ = function() { - var thisField = this; - return function() { - Blockly.FieldNote.superClass_.dispose_.call(thisField)(); - thisField.mouseDownWrappers_.forEach(function(wrapper) { - Blockly.unbindEvent_(wrapper); + /** + * Clean up this FieldNote, as well as the inherited FieldTextInput. + * @return {!Function} Closure to call on destruction of the WidgetDiv. + * @private + */ + dispose() { + super.dispose(); + this.mouseDownWrappers_.forEach(function(wrapper) { + Blockly.browserEvents.unbind(wrapper); }); - thisField.mouseEnterWrappers_.forEach(function(wrapper) { - Blockly.unbindEvent_(wrapper); + this.mouseEnterWrappers_.forEach(function(wrapper) { + Blockly.browserEvents.unbind(wrapper); }); - if (thisField.mouseUpWrapper_) { - Blockly.unbindEvent_(thisField.mouseUpWrapper_); + if (this.mouseUpWrapper_) { + Blockly.browserEvents.unbind(this.mouseUpWrapper_); } - if (thisField.octaveDownMouseDownWrapper_) { - Blockly.unbindEvent_(thisField.octaveDownMouseDownWrapper_); + if (this.octaveDownMouseDownWrapper_) { + Blockly.browserEvents.unbind(this.octaveDownMouseDownWrapper_); } - if (thisField.octaveUpMouseDownWrapper_) { - Blockly.unbindEvent_(thisField.octaveUpMouseDownWrapper_); + if (this.octaveUpMouseDownWrapper_) { + Blockly.browserEvents.unbind(this.octaveUpMouseDownWrapper_); } this.pianoSVG_ = null; this.keySVGs_.length = 0; this.noteNameText_ = null; this.lowCText_ = null; this.highCText_ = null; - }; -}; + } -/** - * Show a field with piano keys. - * @private - */ -Blockly.FieldNote.prototype.showEditor_ = function() { - // Mobile browsers have issues with in-line textareas (focus & keyboards). - Blockly.FieldNote.superClass_.showEditor_.call(this, this.useTouchInteraction_); - - // If there is an existing drop-down someone else owns, hide it immediately and clear it. - Blockly.DropDownDiv.hideWithoutAnimation(); - Blockly.DropDownDiv.clearContent(); - - // Build the SVG DOM. - var div = Blockly.DropDownDiv.getContentDiv(); - - this.fieldEditorWidth_ = Blockly.FieldNote.NUM_WHITE_KEYS * Blockly.FieldNote.WHITE_KEY_WIDTH + - Blockly.FieldNote.EDGE_PADDING; - this.fieldEditorHeight_ = Blockly.FieldNote.TOP_MENU_HEIGHT + - Blockly.FieldNote.WHITE_KEY_HEIGHT + - Blockly.FieldNote.EDGE_PADDING; - - var svg = Blockly.utils.createSvgElement('svg', { - 'xmlns': 'http://www.w3.org/2000/svg', - 'xmlns:html': 'http://www.w3.org/1999/xhtml', - 'xmlns:xlink': 'http://www.w3.org/1999/xlink', - 'version': '1.1', - 'height': this.fieldEditorHeight_ + 'px', - 'width': this.fieldEditorWidth_ + 'px' - }, div); - - // Add the white and black keys - // Since we are adding the keys from left to right in order, they need - // to be in two groups in order to layer correctly. - this.pianoSVG_ = Blockly.utils.createSvgElement('g', {}, svg); - var whiteKeyGroup = Blockly.utils.createSvgElement('g', {}, this.pianoSVG_); - var blackKeyGroup = Blockly.utils.createSvgElement('g', {}, this.pianoSVG_); - - // Add three piano octaves, so we can animate moving up or down an octave. - // Only the middle octave gets bound to events. - this.keySVGs_ = []; - this.addPianoOctave_(-this.fieldEditorWidth_ + Blockly.FieldNote.EDGE_PADDING, - whiteKeyGroup, blackKeyGroup, null); - this.addPianoOctave_(0, whiteKeyGroup, blackKeyGroup, this.keySVGs_); - this.addPianoOctave_(this.fieldEditorWidth_ - Blockly.FieldNote.EDGE_PADDING, - whiteKeyGroup, blackKeyGroup, null); - - // Note name indicator at the top of the field - this.noteNameText_ = Blockly.utils.createSvgElement('text', - { - 'x': this.fieldEditorWidth_ / 2, - 'y': Blockly.FieldNote.TOP_MENU_HEIGHT / 2, - 'class': 'blocklyText', - 'text-anchor': 'middle', - 'dominant-baseline': 'middle', - }, svg); - - // Note names on the low and high C keys - var lowCX = Blockly.FieldNote.WHITE_KEY_WIDTH / 2; - this.lowCText_ = this.addCKeyLabel_(lowCX, svg); - var highCX = lowCX + (Blockly.FieldNote.WHITE_KEY_WIDTH * - (Blockly.FieldNote.NUM_WHITE_KEYS - 1)); - this.highCText_ = this.addCKeyLabel_(highCX, svg); - - // Horizontal line at the top of the keys - Blockly.utils.createSvgElement('line', - { - 'stroke': this.sourceBlock_.getColourTertiary(), - 'x1': 0, - 'y1': Blockly.FieldNote.TOP_MENU_HEIGHT, - 'x2': this.fieldEditorWidth_, - 'y2': Blockly.FieldNote.TOP_MENU_HEIGHT - }, svg); - - // Drop shadow at the top of the keys - Blockly.utils.createSvgElement('rect', - { - 'x': 0, - 'y': Blockly.FieldNote.TOP_MENU_HEIGHT, - 'width': this.fieldEditorWidth_, - 'height': Blockly.FieldNote.SHADOW_HEIGHT, - 'fill': Blockly.FieldNote.SHADOW_COLOR, - 'fill-opacity': Blockly.FieldNote.SHADOW_OPACITY - }, svg); - - // Octave buttons - this.octaveDownButton = this.addOctaveButton_(0, true, svg); - this.octaveUpButton = this.addOctaveButton_( - (this.fieldEditorWidth_ + Blockly.FieldNote.INSET * 2) - - Blockly.FieldNote.OCTAVE_BUTTON_SIZE, false, svg); - - this.octaveDownMouseDownWrapper_ = - Blockly.bindEvent_(this.octaveDownButton, 'mousedown', this, function() { - this.changeOctaveBy_(-1); - }); - this.octaveUpMouseDownWrapper_ = - Blockly.bindEvent_(this.octaveUpButton, 'mousedown', this,function() { - this.changeOctaveBy_(1); + /** + * Show a field with piano keys. + * @private + */ + showEditor_(event, quietInput = false) { + super.showEditor_(event, quietInput); + + // Build the SVG DOM. + var div = Blockly.DropDownDiv.getContentDiv(); + + this.fieldEditorWidth_ = FieldNote.NUM_WHITE_KEYS * FieldNote.WHITE_KEY_WIDTH + + FieldNote.EDGE_PADDING; + this.fieldEditorHeight_ = FieldNote.TOP_MENU_HEIGHT + + FieldNote.WHITE_KEY_HEIGHT + + FieldNote.EDGE_PADDING; + + var svg = Blockly.utils.dom.createSvgElement('svg', { + 'xmlns': 'http://www.w3.org/2000/svg', + 'xmlns:html': 'http://www.w3.org/1999/xhtml', + 'xmlns:xlink': 'http://www.w3.org/1999/xlink', + 'version': '1.1', + 'height': this.fieldEditorHeight_ + 'px', + 'width': this.fieldEditorWidth_ + 'px' + }, div); + + // Add the white and black keys + // Since we are adding the keys from left to right in order, they need + // to be in two groups in order to layer correctly. + this.pianoSVG_ = Blockly.utils.dom.createSvgElement('g', {}, svg); + var whiteKeyGroup = Blockly.utils.dom.createSvgElement('g', {}, this.pianoSVG_); + var blackKeyGroup = Blockly.utils.dom.createSvgElement('g', {}, this.pianoSVG_); + + // Add three piano octaves, so we can animate moving up or down an octave. + // Only the middle octave gets bound to events. + this.keySVGs_ = []; + this.addPianoOctave_(-this.fieldEditorWidth_ + FieldNote.EDGE_PADDING, + whiteKeyGroup, blackKeyGroup, null); + this.addPianoOctave_(0, whiteKeyGroup, blackKeyGroup, this.keySVGs_); + this.addPianoOctave_(this.fieldEditorWidth_ - FieldNote.EDGE_PADDING, + whiteKeyGroup, blackKeyGroup, null); + + // Note name indicator at the top of the field + this.noteNameText_ = Blockly.utils.dom.createSvgElement('text', + { + 'x': this.fieldEditorWidth_ / 2, + 'y': FieldNote.TOP_MENU_HEIGHT / 2, + 'class': 'blocklyText', + 'text-anchor': 'middle', + 'dominant-baseline': 'middle', + }, svg); + + // Note names on the low and high C keys + var lowCX = FieldNote.WHITE_KEY_WIDTH / 2; + this.lowCText_ = this.addCKeyLabel_(lowCX, svg); + var highCX = lowCX + (FieldNote.WHITE_KEY_WIDTH * + (FieldNote.NUM_WHITE_KEYS - 1)); + this.highCText_ = this.addCKeyLabel_(highCX, svg); + + // Horizontal line at the top of the keys + Blockly.utils.dom.createSvgElement('line', + { + 'stroke': this.sourceBlock_.parentBlock_.getColourTertiary(), + 'x1': 0, + 'y1': FieldNote.TOP_MENU_HEIGHT, + 'x2': this.fieldEditorWidth_, + 'y2': FieldNote.TOP_MENU_HEIGHT + }, svg); + + // Drop shadow at the top of the keys + Blockly.utils.dom.createSvgElement('rect', + { + 'x': 0, + 'y': FieldNote.TOP_MENU_HEIGHT, + 'width': this.fieldEditorWidth_, + 'height': FieldNote.SHADOW_HEIGHT, + 'fill': FieldNote.SHADOW_COLOR, + 'fill-opacity': FieldNote.SHADOW_OPACITY + }, svg); + + // Octave buttons + this.octaveDownButton = this.addOctaveButton_(0, true, svg); + this.octaveUpButton = this.addOctaveButton_( + (this.fieldEditorWidth_ + FieldNote.INSET * 2) - + FieldNote.OCTAVE_BUTTON_SIZE, false, svg); + + this.octaveDownMouseDownWrapper_ = + Blockly.browserEvents.bind(this.octaveDownButton, 'mousedown', this, function() { + this.changeOctaveBy_(-1); }); - Blockly.DropDownDiv.setColour(this.sourceBlock_.parentBlock_.getColour(), - this.sourceBlock_.getColourTertiary()); - Blockly.DropDownDiv.setCategory(this.sourceBlock_.parentBlock_.getCategory()); - Blockly.DropDownDiv.showPositionedByBlock(this, this.sourceBlock_); - - this.updateSelection_(); -}; + this.octaveUpMouseDownWrapper_ = + Blockly.browserEvents.bind(this.octaveUpButton, 'mousedown', this,function() { + this.changeOctaveBy_(1); + }); + Blockly.DropDownDiv.setColour(this.sourceBlock_.parentBlock_.getColour(), + this.sourceBlock_.parentBlock_.getColourTertiary()); + Blockly.DropDownDiv.showPositionedByBlock(this, this.sourceBlock_); + + this.updateSelection_(); + } -/** - * Add one octave of piano keys drawn using SVG. - * @param {number} x The x position of the left edge of this octave of keys. - * @param {SVGElement} whiteKeyGroup The group for all white piano keys. - * @param {SvgElement} blackKeyGroup The group for all black piano keys. - * @param {!Array.} keySVGarray An array containing all the key SVGs. - * @private - */ -Blockly.FieldNote.prototype.addPianoOctave_ = function(x, whiteKeyGroup, blackKeyGroup, keySVGarray) { - var xIncrement, width, height, fill, stroke, group; - x += Blockly.FieldNote.EDGE_PADDING / 2; - var y = Blockly.FieldNote.TOP_MENU_HEIGHT; - for (var i = 0; i < Blockly.FieldNote.KEY_INFO.length; i++) { - // Draw a black or white key - if (Blockly.FieldNote.KEY_INFO[i].isBlack) { - // Black keys are shifted back half a key - x -= Blockly.FieldNote.BLACK_KEY_WIDTH / 2; - xIncrement = Blockly.FieldNote.BLACK_KEY_WIDTH / 2; - width = Blockly.FieldNote.BLACK_KEY_WIDTH; - height = Blockly.FieldNote.BLACK_KEY_HEIGHT; - fill = Blockly.FieldNote.BLACK_KEY_COLOR; - stroke = Blockly.FieldNote.BLACK_KEY_STROKE; - group = blackKeyGroup; - } else { - xIncrement = Blockly.FieldNote.WHITE_KEY_WIDTH; - width = Blockly.FieldNote.WHITE_KEY_WIDTH; - height = Blockly.FieldNote.WHITE_KEY_HEIGHT; - fill = Blockly.FieldNote.WHITE_KEY_COLOR; - stroke = this.sourceBlock_.getColourTertiary(); - group = whiteKeyGroup; - } - var attr = { - 'd': this.getPianoKeyPath_(x, y, width, height), - 'fill': fill, - 'stroke': stroke - }; - x += xIncrement; - - var keySVG = Blockly.utils.createSvgElement('path', attr, group); - - if (keySVGarray) { - keySVGarray[i] = keySVG; - keySVG.setAttribute('data-pitch', Blockly.FieldNote.KEY_INFO[i].pitch); - keySVG.setAttribute('data-name', Blockly.FieldNote.KEY_INFO[i].name); - keySVG.setAttribute('data-isBlack', Blockly.FieldNote.KEY_INFO[i].isBlack); - - this.mouseDownWrappers_[i] = - Blockly.bindEvent_(keySVG, 'mousedown', this, this.onMouseDownOnKey_); - this.mouseEnterWrappers_[i] = - Blockly.bindEvent_(keySVG, 'mouseenter', this, this.onMouseEnter_); + /** + * Add one octave of piano keys drawn using SVG. + * @param {number} x The x position of the left edge of this octave of keys. + * @param {SVGElement} whiteKeyGroup The group for all white piano keys. + * @param {SvgElement} blackKeyGroup The group for all black piano keys. + * @param {!Array.} keySVGarray An array containing all the key SVGs. + * @private + */ + addPianoOctave_(x, whiteKeyGroup, blackKeyGroup, keySVGarray) { + var xIncrement, width, height, fill, stroke, group; + x += FieldNote.EDGE_PADDING / 2; + var y = FieldNote.TOP_MENU_HEIGHT; + for (var i = 0; i < FieldNote.KEY_INFO.length; i++) { + // Draw a black or white key + if (FieldNote.KEY_INFO[i].isBlack) { + // Black keys are shifted back half a key + x -= FieldNote.BLACK_KEY_WIDTH / 2; + xIncrement = FieldNote.BLACK_KEY_WIDTH / 2; + width = FieldNote.BLACK_KEY_WIDTH; + height = FieldNote.BLACK_KEY_HEIGHT; + fill = FieldNote.BLACK_KEY_COLOR; + stroke = FieldNote.BLACK_KEY_STROKE; + group = blackKeyGroup; + } else { + xIncrement = FieldNote.WHITE_KEY_WIDTH; + width = FieldNote.WHITE_KEY_WIDTH; + height = FieldNote.WHITE_KEY_HEIGHT; + fill = FieldNote.WHITE_KEY_COLOR; + stroke = this.sourceBlock_.parentBlock_.getColourTertiary(); + group = whiteKeyGroup; + } + var attr = { + 'd': this.getPianoKeyPath_(x, y, width, height), + 'fill': fill, + 'stroke': stroke + }; + x += xIncrement; + + var keySVG = Blockly.utils.dom.createSvgElement('path', attr, group); + + if (keySVGarray) { + keySVGarray[i] = keySVG; + keySVG.setAttribute('data-pitch', FieldNote.KEY_INFO[i].pitch); + keySVG.setAttribute('data-name', FieldNote.KEY_INFO[i].name); + keySVG.setAttribute('data-isBlack', FieldNote.KEY_INFO[i].isBlack); + + this.mouseDownWrappers_[i] = + Blockly.browserEvents.bind(keySVG, 'mousedown', this, this.onMouseDownOnKey_); + this.mouseEnterWrappers_[i] = + Blockly.browserEvents.bind(keySVG, 'mouseenter', this, this.onMouseEnter_); + } } } -}; -/** - * Construct the SVG path string for a piano key shape: a rectangle with rounded - * corners at the bottom. - * @param {number} x the x position for the key. - * @param {number} y the y position for the key. - * @param {number} width the width of the key. - * @param {number} height the height of the key. - * @returns {string} the SVG path as a string. - * @private - */ -Blockly.FieldNote.prototype.getPianoKeyPath_ = function(x, y, width, height) { - return 'M' + x + ' ' + y + ' ' + - 'L' + x + ' ' + (y + height - Blockly.FieldNote.KEY_RADIUS) + ' ' + - 'Q' + x + ' ' + (y + height) + ' ' + - (x + Blockly.FieldNote.KEY_RADIUS) + ' ' + (y + height) + ' ' + - 'L' + (x + width - Blockly.FieldNote.KEY_RADIUS) + ' ' + (y + height) + ' ' + - 'Q' + (x + width) + ' ' + (y + height) + ' ' + - (x + width) + ' ' + (y + height - Blockly.FieldNote.KEY_RADIUS) + ' ' + - 'L' + (x + width) + ' ' + y + ' ' + - 'L' + x + ' ' + y; -}; - -/** - * Add a button for switching the displayed octave of the piano up or down. - * @param {number} x The x position of the button. - * @param {boolean} flipped If true, the icon should be flipped. - * @param {SvgElement} svg The svg element to add the buttons to. - * @returns {SvgElement} A group containing the button SVG elements. - * @private - */ -Blockly.FieldNote.prototype.addOctaveButton_ = function(x, flipped, svg) { - var group = Blockly.utils.createSvgElement('g', {}, svg); - var imageSize = Blockly.FieldNote.OCTAVE_BUTTON_SIZE; - var arrow = Blockly.utils.createSvgElement('image', - { - 'width': imageSize, - 'height': imageSize, - 'x': x - Blockly.FieldNote.INSET, - 'y': -1 * Blockly.FieldNote.INSET - }, group); - arrow.setAttributeNS( - 'http://www.w3.org/1999/xlink', - 'xlink:href', - Blockly.mainWorkspace.options.pathToMedia + Blockly.FieldNote.ARROW_SVG_PATH - ); - Blockly.utils.createSvgElement('line', - { - 'stroke': this.sourceBlock_.getColourTertiary(), - 'x1': x - Blockly.FieldNote.INSET, - 'y1': 0, - 'x2': x - Blockly.FieldNote.INSET, - 'y2': Blockly.FieldNote.TOP_MENU_HEIGHT - Blockly.FieldNote.INSET - }, group); - if (flipped) { - var translateX = -1 * Blockly.FieldNote.OCTAVE_BUTTON_SIZE + (Blockly.FieldNote.INSET * 2); - group.setAttribute('transform', 'scale(-1, 1) ' + - 'translate(' + translateX + ', 0)'); + /** + * Construct the SVG path string for a piano key shape: a rectangle with rounded + * corners at the bottom. + * @param {number} x the x position for the key. + * @param {number} y the y position for the key. + * @param {number} width the width of the key. + * @param {number} height the height of the key. + * @returns {string} the SVG path as a string. + * @private + */ + getPianoKeyPath_(x, y, width, height) { + return 'M' + x + ' ' + y + ' ' + + 'L' + x + ' ' + (y + height - FieldNote.KEY_RADIUS) + ' ' + + 'Q' + x + ' ' + (y + height) + ' ' + + (x + FieldNote.KEY_RADIUS) + ' ' + (y + height) + ' ' + + 'L' + (x + width - FieldNote.KEY_RADIUS) + ' ' + (y + height) + ' ' + + 'Q' + (x + width) + ' ' + (y + height) + ' ' + + (x + width) + ' ' + (y + height - FieldNote.KEY_RADIUS) + ' ' + + 'L' + (x + width) + ' ' + y + ' ' + + 'L' + x + ' ' + y; } - return group; -}; -/** - * Add an SVG text label for display on the C keys of the piano. - * @param {number} x The x position for the label. - * @param {SvgElement} svg The SVG element to add the label to. - * @returns {SvgElement} The SVG element containing the label. - * @private - */ -Blockly.FieldNote.prototype.addCKeyLabel_ = function(x, svg) { - return Blockly.utils.createSvgElement('text', - { - 'x': x, - 'y': Blockly.FieldNote.TOP_MENU_HEIGHT + Blockly.FieldNote.WHITE_KEY_HEIGHT - - Blockly.FieldNote.KEY_LABEL_PADDING, - 'class': 'scratchNotePickerKeyLabel', - 'text-anchor': 'middle' - }, svg); -}; - -/** - * Set the visibility of the C key labels. - * @param {boolean} visible If true, set labels to be visible. - * @private - */ -Blockly.FieldNote.prototype.setCKeyLabelsVisible_ = function(visible) { - if (visible) { - this.fadeSvgToOpacity_(this.lowCText_, 1); - this.fadeSvgToOpacity_(this.highCText_, 1); - } else { - this.fadeSvgToOpacity_(this.lowCText_, 0); - this.fadeSvgToOpacity_(this.highCText_, 0); + /** + * Add a button for switching the displayed octave of the piano up or down. + * @param {number} x The x position of the button. + * @param {boolean} flipped If true, the icon should be flipped. + * @param {SvgElement} svg The svg element to add the buttons to. + * @returns {SvgElement} A group containing the button SVG elements. + * @private + */ + addOctaveButton_(x, flipped, svg) { + var group = Blockly.utils.dom.createSvgElement('g', {}, svg); + var imageSize = FieldNote.OCTAVE_BUTTON_SIZE; + var arrow = Blockly.utils.dom.createSvgElement('image', + { + 'width': imageSize, + 'height': imageSize, + 'x': x - FieldNote.INSET, + 'y': -1 * FieldNote.INSET + }, group); + arrow.setAttributeNS( + 'http://www.w3.org/1999/xlink', + 'xlink:href', + Blockly.getMainWorkspace().options.pathToMedia + FieldNote.ARROW_SVG_PATH + ); + Blockly.utils.dom.createSvgElement('line', + { + 'stroke': this.sourceBlock_.parentBlock_.getColourTertiary(), + 'x1': x - FieldNote.INSET, + 'y1': 0, + 'x2': x - FieldNote.INSET, + 'y2': FieldNote.TOP_MENU_HEIGHT - FieldNote.INSET + }, group); + if (flipped) { + var translateX = -1 * FieldNote.OCTAVE_BUTTON_SIZE + (FieldNote.INSET * 2); + group.setAttribute('transform', 'scale(-1, 1) ' + + 'translate(' + translateX + ', 0)'); + } + return group; } -}; -/** - * Animate an SVG to fade it in or out to a target opacity. - * @param {SvgElement} svg The SVG element to apply the fade to. - * @param {number} opacity The target opacity. - * @private - */ -Blockly.FieldNote.prototype.fadeSvgToOpacity_ = function(svg, opacity) { - svg.setAttribute('style', 'opacity: ' + opacity + '; transition: opacity 0.1s;'); -}; + /** + * Add an SVG text label for display on the C keys of the piano. + * @param {number} x The x position for the label. + * @param {SvgElement} svg The SVG element to add the label to. + * @returns {SvgElement} The SVG element containing the label. + * @private + */ + addCKeyLabel_(x, svg) { + return Blockly.utils.dom.createSvgElement('text', + { + 'x': x, + 'y': FieldNote.TOP_MENU_HEIGHT + FieldNote.WHITE_KEY_HEIGHT - + FieldNote.KEY_LABEL_PADDING, + 'class': 'scratchNotePickerKeyLabel', + 'text-anchor': 'middle' + }, svg); + } -/** - * Handle the mouse down event on a piano key. - * @param {!Event} e Mouse down event. - * @private - */ -Blockly.FieldNote.prototype.onMouseDownOnKey_ = function(e) { - this.mouseIsDown_ = true; - this.mouseUpWrapper_ = Blockly.bindEvent_(document.body, 'mouseup', this, this.onMouseUp_); - this.selectNoteWithMouseEvent_(e); -}; + /** + * Set the visibility of the C key labels. + * @param {boolean} visible If true, set labels to be visible. + * @private + */ + setCKeyLabelsVisible_(visible) { + if (visible) { + this.fadeSvgToOpacity_(this.lowCText_, 1); + this.fadeSvgToOpacity_(this.highCText_, 1); + } else { + this.fadeSvgToOpacity_(this.lowCText_, 0); + this.fadeSvgToOpacity_(this.highCText_, 0); + } + } -/** - * Handle the mouse up event following a mouse down on a piano key. - * @private - */ -Blockly.FieldNote.prototype.onMouseUp_ = function() { - this.mouseIsDown_ = false; - Blockly.unbindEvent_(this.mouseUpWrapper_); -}; + /** + * Animate an SVG to fade it in or out to a target opacity. + * @param {SvgElement} svg The SVG element to apply the fade to. + * @param {number} opacity The target opacity. + * @private + */ + fadeSvgToOpacity_(svg, opacity) { + svg.setAttribute('style', 'opacity: ' + opacity + '; transition: opacity 0.1s;'); + } -/** - * Handle the event when the mouse enters a piano key. - * @param {!Event} e Mouse enter event. - * @private - */ -Blockly.FieldNote.prototype.onMouseEnter_ = function(e) { - if (this.mouseIsDown_) { + /** + * Handle the mouse down event on a piano key. + * @param {!Event} e Mouse down event. + * @private + */ + onMouseDownOnKey_(e) { + this.mouseIsDown_ = true; + this.mouseUpWrapper_ = Blockly.browserEvents.bind(document.body, 'mouseup', this, this.onMouseUp_); this.selectNoteWithMouseEvent_(e); } -}; -/** - * Use the data in a mouse event to select a new note, and play it. - * @param {!Event} e Mouse event. - * @private - */ -Blockly.FieldNote.prototype.selectNoteWithMouseEvent_ = function(e) { - var newNoteNum = Number(e.target.getAttribute('data-pitch')) + this.displayedOctave_ * 12; - this.setNoteNum_(newNoteNum); - this.playNoteInternal_(); -}; + /** + * Handle the mouse up event following a mouse down on a piano key. + * @private + */ + onMouseUp_() { + this.mouseIsDown_ = false; + Blockly.browserEvents.unbind(this.mouseUpWrapper_); + this.mouseUpWrapper_ = null; + } -/** - * Play a note, by calling the externally overriden play note function. - * @private - */ -Blockly.FieldNote.prototype.playNoteInternal_ = function() { - if (Blockly.FieldNote.playNote_) { - Blockly.FieldNote.playNote_( - this.getValue(), - this.sourceBlock_.parentBlock_.getCategory() - ); + /** + * Handle the event when the mouse enters a piano key. + * @param {!Event} e Mouse enter event. + * @private + */ + onMouseEnter_(e) { + if (this.mouseIsDown_) { + this.selectNoteWithMouseEvent_(e); + } } -}; -/** - * Function to play a musical note corresponding to the key selected. - * Overridden externally. - * @param {number} noteNum the MIDI note number to play. - * @param {string} id An id to select a scratch extension to play the note. - * @private - */ -Blockly.FieldNote.playNote_ = function(/* noteNum, id*/) { - return; -}; + /** + * Use the data in a mouse event to select a new note, and play it. + * @param {!Event} e Mouse event. + * @private + */ + selectNoteWithMouseEvent_(e) { + var newNoteNum = Number(e.target.getAttribute('data-pitch')) + this.displayedOctave_ * 12; + this.setEditorValue_(newNoteNum); + this.playNoteInternal_(); + } -/** - * Change the selected note by a number of octaves, and start the animation. - * @param {number} octaves The number of octaves to change by. - * @private - */ -Blockly.FieldNote.prototype.changeOctaveBy_ = function(octaves) { - this.displayedOctave_ += octaves; - if (this.displayedOctave_ < 0) { - this.displayedOctave_ = 0; - return; + /** + * Play a note, by calling the externally overriden play note function. + * @private + */ + playNoteInternal_() { + if (FieldNote.playNote_) { + FieldNote.playNote_( + Number(this.getValue()), + 'Music', + ); + } } - var maxOctave = Math.floor(Blockly.FieldNote.MAX_NOTE / 12); - if (this.displayedOctave_ > maxOctave) { - this.displayedOctave_ = maxOctave; + + /** + * Function to play a musical note corresponding to the key selected. + * Overridden externally. + * @param {number} noteNum the MIDI note number to play. + * @param {string} id An id to select a scratch extension to play the note. + * @private + */ + static playNote_ = function(/* noteNum, id*/) { return; - } + }; - var newNote = Number(this.getText()) + (octaves * 12); - this.setNoteNum_(newNote); + /** + * Change the selected note by a number of octaves, and start the animation. + * @param {number} octaves The number of octaves to change by. + * @private + */ + changeOctaveBy_(octaves) { + this.displayedOctave_ += octaves; + if (this.displayedOctave_ < 0) { + this.displayedOctave_ = 0; + return; + } + var maxOctave = Math.floor(FieldNote.MAX_NOTE / 12); + if (this.displayedOctave_ > maxOctave) { + this.displayedOctave_ = maxOctave; + return; + } - this.animationTarget_ = this.fieldEditorWidth_ * octaves * -1; - this.animationPos_ = 0; - this.stepOctaveAnimation_(); - this.setCKeyLabelsVisible_(false); -}; + var newNote = Number(this.getText()) + (octaves * 12); + this.setEditorValue_(newNote); -/** - * Animate the piano up or down an octave by sliding it to the left or right. - * @private - */ -Blockly.FieldNote.prototype.stepOctaveAnimation_ = function() { - var absDiff = Math.abs(this.animationPos_ - this.animationTarget_); - if (absDiff < 1) { - this.pianoSVG_.setAttribute('transform', 'translate(0, 0)'); - this.setCKeyLabelsVisible_(true); - this.playNoteInternal_(); - return; + this.animationTarget_ = this.fieldEditorWidth_ * octaves * -1; + this.animationPos_ = 0; + this.stepOctaveAnimation_(); + this.setCKeyLabelsVisible_(false); } - this.animationPos_ += (this.animationTarget_ - this.animationPos_) * - Blockly.FieldNote.ANIMATION_FRACTION; - this.pianoSVG_.setAttribute('transform', 'translate(' + this.animationPos_ + ',0)'); - requestAnimationFrame(this.stepOctaveAnimation_.bind(this)); -}; - -/** - * Set the selected note number, and update the piano display and the input field. - * @param {number} noteNum The MIDI note number to select. - * @private - */ -Blockly.FieldNote.prototype.setNoteNum_ = function(noteNum) { - noteNum = this.callValidator(noteNum); - this.setValue(noteNum); - Blockly.FieldTextInput.htmlInput_.value = noteNum; -}; -/** - * Sets the text in this field. Triggers a rerender of the source block, and - * updates the selection on the field. - * @param {?string} text New text. - */ -Blockly.FieldNote.prototype.setText = function(text) { - Blockly.FieldNote.superClass_.setText.call(this, text); - if (!this.textElement_) { - // Not rendered yet. - return; + /** + * Animate the piano up or down an octave by sliding it to the left or right. + * @private + */ + stepOctaveAnimation_() { + var absDiff = Math.abs(this.animationPos_ - this.animationTarget_); + if (absDiff < 1) { + this.pianoSVG_.setAttribute('transform', 'translate(0, 0)'); + this.setCKeyLabelsVisible_(true); + this.playNoteInternal_(); + return; + } + this.animationPos_ += (this.animationTarget_ - this.animationPos_) * + FieldNote.ANIMATION_FRACTION; + this.pianoSVG_.setAttribute('transform', 'translate(' + this.animationPos_ + ',0)'); + requestAnimationFrame(this.stepOctaveAnimation_.bind(this)); } - this.updateSelection_(); - // Cached width is obsolete. Clear it. - this.size_.width = 0; -}; -/** - * For a MIDI note number, find the index of the corresponding piano key. - * @param {number} noteNum The note number. - * @returns {number} The index of the piano key. - * @private - */ -Blockly.FieldNote.prototype.noteNumToKeyIndex_ = function(noteNum) { - return Math.floor(noteNum) - (this.displayedOctave_ * 12); -}; + doValueUpdate_(newValue) { + super.doValueUpdate_(newValue); -/** - * Update the selected note and labels on the field. - * @private - */ -Blockly.FieldNote.prototype.updateSelection_ = function() { - var noteNum = Number(this.getText()); - - // If the note is outside the currently displayed octave, update it - if (this.displayedOctave_ == null || - noteNum > ((this.displayedOctave_ * 12) + 12) || - noteNum < (this.displayedOctave_ * 12)) { - this.displayedOctave_ = Math.floor(noteNum / 12); + if (!this.textElement_) { + // Not rendered yet. + return; + } + + this.updateSelection_(); } - var index = this.noteNumToKeyIndex_(noteNum); + /** + * For a MIDI note number, find the index of the corresponding piano key. + * @param {number} noteNum The note number. + * @returns {number} The index of the piano key. + * @private + */ + noteNumToKeyIndex_(noteNum) { + return Math.floor(noteNum) - (this.displayedOctave_ * 12); + } - // Clear the highlight on all keys - this.keySVGs_.forEach(function(svg) { - var isBlack = svg.getAttribute('data-isBlack'); - if (isBlack === 'true') { - svg.setAttribute('fill', Blockly.FieldNote.BLACK_KEY_COLOR); - } else { - svg.setAttribute('fill', Blockly.FieldNote.WHITE_KEY_COLOR); + /** + * Update the selected note and labels on the field. + * @private + */ + updateSelection_() { + var noteNum = Number(this.getText()); + + // If the note is outside the currently displayed octave, update it + if (this.displayedOctave_ == null || + noteNum > ((this.displayedOctave_ * 12) + 12) || + noteNum < (this.displayedOctave_ * 12)) { + this.displayedOctave_ = Math.floor(noteNum / 12); } - }); - // Set the highlight on the selected key - if (this.keySVGs_[index]) { - this.keySVGs_[index].setAttribute('fill', Blockly.FieldNote.KEY_SELECTED_COLOR); - // Update the note name text - var noteName = Blockly.FieldNote.KEY_INFO[index].name; - this.noteNameText_.textContent = noteName + ' (' + Math.floor(noteNum) + ')'; - // Update the low and high C note names - var lowCNum = this.displayedOctave_ * 12; - this.lowCText_.textContent = 'C(' + lowCNum + ')'; - this.highCText_.textContent = 'C(' + (lowCNum + 12) + ')'; - } -}; -/** - * Ensure that only a valid MIDI note number may be entered. - * @param {string} text The user's text. - * @return {?string} A string representing a valid note number, or null if invalid. - */ -Blockly.FieldNote.prototype.classValidator = function(text) { - if (text === null) { - return null; - } - var n = parseFloat(text || 0); - if (isNaN(n)) { - return null; - } - if (n < 0) { - n = 0; + var index = this.noteNumToKeyIndex_(noteNum); + + // Clear the highlight on all keys + this.keySVGs_.forEach(function(svg) { + var isBlack = svg.getAttribute('data-isBlack'); + if (isBlack === 'true') { + svg.setAttribute('fill', FieldNote.BLACK_KEY_COLOR); + } else { + svg.setAttribute('fill', FieldNote.WHITE_KEY_COLOR); + } + }); + // Set the highlight on the selected key + if (this.keySVGs_[index]) { + this.keySVGs_[index].setAttribute('fill', FieldNote.KEY_SELECTED_COLOR); + // Update the note name text + var noteName = FieldNote.KEY_INFO[index].name; + this.noteNameText_.textContent = noteName + ' (' + Math.floor(noteNum) + ')'; + // Update the low and high C note names + var lowCNum = this.displayedOctave_ * 12; + this.lowCText_.textContent = 'C(' + lowCNum + ')'; + this.highCText_.textContent = 'C(' + (lowCNum + 12) + ')'; + } } - if (n > Blockly.FieldNote.MAX_NOTE) { - n = Blockly.FieldNote.MAX_NOTE; + + /** + * Ensure that only a valid MIDI note number may be entered. + * @param {string} text The user's text. + * @return {?string} A string representing a valid note number, or null if invalid. + */ + doClassValidation_(text) { + if (text === null) { + return null; + } + var n = parseFloat(text || 0); + if (isNaN(n)) { + return null; + } + if (n < 0) { + n = 0; + } + if (n > FieldNote.MAX_NOTE) { + n = FieldNote.MAX_NOTE; + } + return String(n); } - return String(n); -}; +} -Blockly.Field.register('field_note', Blockly.FieldNote); +Blockly.fieldRegistry.register('field_note', FieldNote); diff --git a/src/index.js b/src/index.js index 537976bd12..ef61b23af8 100644 --- a/src/index.js +++ b/src/index.js @@ -7,6 +7,7 @@ import * as Blockly from 'blockly/core'; import '../blocks_common/colour.js'; import '../blocks_common/math.js'; +import '../blocks_common/note.js'; import '../blocks_common/text.js'; import '../blocks_vertical/vertical_extensions.js'; import '../blocks_vertical/control.js'; @@ -34,6 +35,7 @@ export * from './categories.js'; export * from './procedures.js'; export * from '../core/colours.js'; export * from '../core/field_colour_slider.js'; +export * from '../core/field_note.js'; export * from '../msg/scratch_msgs.js'; export {scratchBlocksUtils}; export {CheckableContinuousFlyout}; From aa3341b69e51de847f177124660a304e2bca8446 Mon Sep 17 00:00:00 2001 From: Aaron Dodson Date: Tue, 30 Apr 2024 13:36:17 -0700 Subject: [PATCH 031/130] fix: reenable the matrix field (#49) * fix: reenable the matrix field * refactor: clean up the matrix field --- blocks_common/matrix.js | 13 +- core/field_matrix.js | 922 +++++++++++++++++++--------------------- src/index.js | 2 + 3 files changed, 452 insertions(+), 485 deletions(-) diff --git a/blocks_common/matrix.js b/blocks_common/matrix.js index 8945f8b09a..839a778496 100644 --- a/blocks_common/matrix.js +++ b/blocks_common/matrix.js @@ -22,15 +22,8 @@ * @fileoverview Matrix blocks for Blockly. * @author khanning@gmail.com (Kreg Hanning) */ -'use strict'; - -goog.provide('Blockly.Blocks.matrix'); - -goog.require('Blockly.Blocks'); - -goog.require('Blockly.Colours'); - -goog.require('Blockly.constants'); +import * as Blockly from 'blockly/core'; +import * as Constants from '../src/constants.js'; Blockly.Blocks['matrix'] = { /** @@ -46,7 +39,7 @@ Blockly.Blocks['matrix'] = { "name": "MATRIX" } ], - "outputShape": Blockly.OUTPUT_SHAPE_ROUND, + "outputShape": Constants.OUTPUT_SHAPE_ROUND, "output": "Number", "extensions": ["colours_pen"] }); diff --git a/core/field_matrix.js b/core/field_matrix.js index e8410e30b9..af4d912f38 100644 --- a/core/field_matrix.js +++ b/core/field_matrix.js @@ -23,11 +23,7 @@ * Displays an editable 5x5 matrix for controlling LED arrays. * @author khanning@gmail.com (Kreg Hanning) */ -'use strict'; - -goog.provide('Blockly.FieldMatrix'); - -goog.require('Blockly.DropDownDiv'); +import * as Blockly from 'blockly/core'; /** * Class for a matrix field. @@ -35,532 +31,508 @@ goog.require('Blockly.DropDownDiv'); * @extends {Blockly.Field} * @constructor */ -Blockly.FieldMatrix = function(matrix) { - Blockly.FieldMatrix.superClass_.constructor.call(this, matrix); - this.addArgType('matrix'); - /** - * Array of SVGElement for matrix thumbnail image on block field. - * @type {!Array} - * @private - */ - this.ledThumbNodes_ = []; +export class FieldMatrix extends Blockly.Field { + constructor(matrix) { + super(matrix); + /** + * Array of SVGElement for matrix thumbnail image on block field. + * @type {!Array} + * @private + */ + this.ledThumbNodes_ = []; + /** + * Array of SVGElement for matrix editor in dropdown menu. + * @type {!Array} + * @private + */ + this.ledButtons_ = []; + /** + * SVGElement for LED matrix in editor. + * @type {?SVGElement} + * @private + */ + this.matrixStage_ = null; + /** + * SVG image for dropdown arrow. + * @type {?SVGElement} + * @private + */ + this.arrow_ = null; + /** + * String indicating matrix paint style. + * value can be [null, 'fill', 'clear']. + * @type {?String} + * @private + */ + this.paintStyle_ = null; + /** + * Touch event wrapper. + * Runs when the field is selected. + * @type {!Array} + * @private + */ + this.mouseDownWrapper_ = null; + /** + * Touch event wrapper. + * Runs when the clear button editor button is selected. + * @type {!Array} + * @private + */ + this.clearButtonWrapper_ = null; + /** + * Touch event wrapper. + * Runs when the fill button editor button is selected. + * @type {!Array} + * @private + */ + this.fillButtonWrapper_ = null; + /** + * Touch event wrapper. + * Runs when the matrix editor is touched. + * @type {!Array} + * @private + */ + this.matrixTouchWrapper_ = null; + /** + * Touch event wrapper. + * Runs when the matrix editor touch event moves. + * @type {!Array} + * @private + */ + this.matrixMoveWrapper_ = null; + /** + * Touch event wrapper. + * Runs when the matrix editor is released. + * @type {!Array} + * @private + */ + this.matrixReleaseWrapper_ = null; + + this.SERIALIZABLE = true; + } + /** - * Array of SVGElement for matrix editor in dropdown menu. - * @type {!Array} - * @private + * Construct a FieldMatrix from a JSON arg object. + * @param {!Object} options A JSON object with options (matrix). + * @returns {!Blockly.FieldMatrix} The new field instance. + * @package + * @nocollapse */ - this.ledButtons_ = []; + static fromJson(options) { + return new FieldMatrix(options['matrix']); + } + /** - * String for storing current matrix value. - * @type {!String] - * @private + * Fixed size of the matrix thumbnail in the input field, in px. + * @type {number} + * @const */ - this.matrix_ = ''; + static THUMBNAIL_SIZE = 26; + /** - * SVGElement for LED matrix in editor. - * @type {?SVGElement} - * @private + * Fixed size of each matrix thumbnail node, in px. + * @type {number} + * @const */ - this.matrixStage_ = null; + static THUMBNAIL_NODE_SIZE = 4; + /** - * SVG image for dropdown arrow. - * @type {?SVGElement} - * @private + * Fixed size of each matrix thumbnail node, in px. + * @type {number} + * @const */ - this.arrow_ = null; + static THUMBNAIL_NODE_PAD = 1; + /** - * String indicating matrix paint style. - * value can be [null, 'fill', 'clear']. - * @type {?String} - * @private + * Fixed size of arrow icon in drop down menu, in px. + * @type {number} + * @const */ - this.paintStyle_ = null; + static ARROW_SIZE = 12; + /** - * Touch event wrapper. - * Runs when the field is selected. - * @type {!Array} - * @private + * Fixed size of each button inside the 5x5 matrix, in px. + * @type {number} + * @const */ - this.mouseDownWrapper_ = null; + static MATRIX_NODE_SIZE = 18; + /** - * Touch event wrapper. - * Runs when the clear button editor button is selected. - * @type {!Array} - * @private + * Fixed corner radius for 5x5 matrix buttons, in px. + * @type {number} + * @const */ - this.clearButtonWrapper_ = null; + static MATRIX_NODE_RADIUS = 4; + /** - * Touch event wrapper. - * Runs when the fill button editor button is selected. - * @type {!Array} - * @private + * Fixed padding for 5x5 matrix buttons, in px. + * @type {number} + * @const */ - this.fillButtonWrapper_ = null; + static MATRIX_NODE_PAD = 5; + /** - * Touch event wrapper. - * Runs when the matrix editor is touched. - * @type {!Array} - * @private + * String with 25 '0' chars. + * Used for clearing a matrix or filling an LED node array. + * @type {string} + * @const */ - this.matrixTouchWrapper_ = null; + static ZEROS = '0000000000000000000000000'; + /** - * Touch event wrapper. - * Runs when the matrix editor touch event moves. - * @type {!Array} - * @private + * String with 25 '1' chars. + * Used for filling a matrix. + * @type {string} + * @const */ - this.matrixMoveWrapper_ = null; + static ONES = '1111111111111111111111111'; + /** - * Touch event wrapper. - * Runs when the matrix editor is released. - * @type {!Array} - * @private + * Called when the field is placed on a block. + * @param {Block} block The owning block. */ - this.matrixReleaseWrapper_ = null; -}; -goog.inherits(Blockly.FieldMatrix, Blockly.Field); - -/** - * Construct a FieldMatrix from a JSON arg object. - * @param {!Object} options A JSON object with options (matrix). - * @returns {!Blockly.FieldMatrix} The new field instance. - * @package - * @nocollapse - */ -Blockly.FieldMatrix.fromJson = function(options) { - return new Blockly.FieldMatrix(options['matrix']); -}; - -/** - * Fixed size of the matrix thumbnail in the input field, in px. - * @type {number} - * @const - */ -Blockly.FieldMatrix.THUMBNAIL_SIZE = 26; - -/** - * Fixed size of each matrix thumbnail node, in px. - * @type {number} - * @const - */ -Blockly.FieldMatrix.THUMBNAIL_NODE_SIZE = 4; - -/** - * Fixed size of each matrix thumbnail node, in px. - * @type {number} - * @const - */ -Blockly.FieldMatrix.THUMBNAIL_NODE_PAD = 1; - -/** - * Fixed size of arrow icon in drop down menu, in px. - * @type {number} - * @const - */ -Blockly.FieldMatrix.ARROW_SIZE = 12; - -/** - * Fixed size of each button inside the 5x5 matrix, in px. - * @type {number} - * @const - */ -Blockly.FieldMatrix.MATRIX_NODE_SIZE = 18; + initView() { + // Build the DOM. + this.updateSize_(); + const dropdownArrowPadding = this.getConstants().GRID_UNIT * 2; + var thumbX = dropdownArrowPadding / 2; + var thumbY = (this.size_.height - FieldMatrix.THUMBNAIL_SIZE) / 2; + var thumbnail = Blockly.utils.dom.createSvgElement('g', { + 'transform': 'translate(' + thumbX + ', ' + thumbY + ')', + 'pointer-events': 'bounding-box', 'cursor': 'pointer' + }, this.fieldGroup_); + this.ledThumbNodes_ = []; + var nodeSize = FieldMatrix.THUMBNAIL_NODE_SIZE; + var nodePad = FieldMatrix.THUMBNAIL_NODE_PAD; + for (var i = 0; i < 5; i++) { + for (var n = 0; n < 5; n++) { + var attr = { + 'x': ((nodeSize + nodePad) * n) + nodePad, + 'y': ((nodeSize + nodePad) * i) + nodePad, + 'width': nodeSize, 'height': nodeSize, + 'rx': nodePad, 'ry': nodePad + }; + this.ledThumbNodes_.push( + Blockly.utils.dom.createSvgElement('rect', attr, thumbnail) + ); + } + thumbnail.style.cursor = 'default'; + this.updateMatrix_(); + } -/** - * Fixed corner radius for 5x5 matrix buttons, in px. - * @type {number} - * @const - */ -Blockly.FieldMatrix.MATRIX_NODE_RADIUS = 4; + if (!this.arrow_) { + var arrowX = FieldMatrix.THUMBNAIL_SIZE + + dropdownArrowPadding * 1.5; + var arrowY = (this.size_.height - FieldMatrix.ARROW_SIZE) / 2; + this.arrow_ = Blockly.utils.dom.createSvgElement('image', { + 'height': FieldMatrix.ARROW_SIZE + 'px', + 'width': FieldMatrix.ARROW_SIZE + 'px', + 'transform': 'translate(' + arrowX + ', ' + arrowY + ')' + }, this.fieldGroup_); + this.arrow_.setAttributeNS('http://www.w3.org/1999/xlink', + 'xlink:href', Blockly.getMainWorkspace().options.pathToMedia + + 'dropdown-arrow.svg'); + this.arrow_.style.cursor = 'default'; + } + } -/** - * Fixed padding for 5x5 matrix buttons, in px. - * @type {number} - * @const - */ -Blockly.FieldMatrix.MATRIX_NODE_PAD = 5; + doClassValidation_(matrix) { + return matrix ? matrix + FieldMatrix.ZEROS.substr(0, 25 - matrix.length) : matrix; + } -/** - * String with 25 '0' chars. - * Used for clearing a matrix or filling an LED node array. - * @type {string} - * @const - */ -Blockly.FieldMatrix.ZEROS = '0000000000000000000000000'; + doValueUpdate_(newValue) { + super.doValueUpdate_(newValue); + if (newValue) { + this.updateMatrix_(); + } + } -/** - * String with 25 '1' chars. - * Used for filling a matrix. - * @type {string} - * @const - */ -Blockly.FieldMatrix.ONES = '1111111111111111111111111'; + /** + * Show the drop-down menu for editing this field. + * @private + */ + showEditor_() { + var div = Blockly.DropDownDiv.getContentDiv(); + // Build the SVG DOM. + var matrixSize = (FieldMatrix.MATRIX_NODE_SIZE * 5) + + (FieldMatrix.MATRIX_NODE_PAD * 6); + this.matrixStage_ = Blockly.utils.dom.createSvgElement('svg', { + 'xmlns': 'http://www.w3.org/2000/svg', + 'xmlns:html': 'http://www.w3.org/1999/xhtml', + 'xmlns:xlink': 'http://www.w3.org/1999/xlink', + 'version': '1.1', + 'height': matrixSize + 'px', + 'width': matrixSize + 'px' + }, div); + // Create the 5x5 matrix + this.ledButtons_ = []; + for (var i = 0; i < 5; i++) { + for (var n = 0; n < 5; n++) { + var x = (FieldMatrix.MATRIX_NODE_SIZE * n) + + (FieldMatrix.MATRIX_NODE_PAD * (n + 1)); + var y = (FieldMatrix.MATRIX_NODE_SIZE * i) + + (FieldMatrix.MATRIX_NODE_PAD * (i + 1)); + var attr = { + 'x': x + 'px', 'y': y + 'px', + 'width': FieldMatrix.MATRIX_NODE_SIZE, + 'height': FieldMatrix.MATRIX_NODE_SIZE, + 'rx': FieldMatrix.MATRIX_NODE_RADIUS, + 'ry': FieldMatrix.MATRIX_NODE_RADIUS + }; + var led = Blockly.utils.dom.createSvgElement('rect', attr, this.matrixStage_); + this.matrixStage_.appendChild(led); + this.ledButtons_.push(led); + } + } + // Div for lower button menu + var buttonDiv = document.createElement('div'); + // Button to clear matrix + var clearButtonDiv = document.createElement('div'); + clearButtonDiv.className = 'scratchMatrixButtonDiv'; + var clearButton = this.createButton_(this.sourceBlock_.getColourSecondary()); + clearButtonDiv.appendChild(clearButton); + // Button to fill matrix + var fillButtonDiv = document.createElement('div'); + fillButtonDiv.className = 'scratchMatrixButtonDiv'; + var fillButton = this.createButton_('#FFFFFF'); + fillButtonDiv.appendChild(fillButton); + + buttonDiv.appendChild(clearButtonDiv); + buttonDiv.appendChild(fillButtonDiv); + div.appendChild(buttonDiv); + + Blockly.DropDownDiv.setColour(this.sourceBlock_.getColour(), + this.sourceBlock_.getColourTertiary()); + Blockly.DropDownDiv.showPositionedByBlock(this, this.sourceBlock_); + + this.matrixTouchWrapper_ = + Blockly.browserEvents.bind(this.matrixStage_, 'mousedown', this, this.onMouseDown); + this.clearButtonWrapper_ = + Blockly.browserEvents.bind(clearButton, 'click', this, this.clearMatrix_); + this.fillButtonWrapper_ = + Blockly.browserEvents.bind(fillButton, 'click', this, this.fillMatrix_); + + // Update the matrix for the current value + this.updateMatrix_(); + } -/** - * Called when the field is placed on a block. - * @param {Block} block The owning block. - */ -Blockly.FieldMatrix.prototype.init = function() { - if (this.fieldGroup_) { - // Matrix menu has already been initialized once. - return; + /** + * Make an svg object that resembles a 3x3 matrix to be used as a button. + * @param {string} fill The color to fill the matrix nodes. + * @return {SvgElement} The button svg element. + */ + createButton_(fill) { + var button = Blockly.utils.dom.createSvgElement('svg', { + 'xmlns': 'http://www.w3.org/2000/svg', + 'xmlns:html': 'http://www.w3.org/1999/xhtml', + 'xmlns:xlink': 'http://www.w3.org/1999/xlink', + 'version': '1.1', + 'height': FieldMatrix.MATRIX_NODE_SIZE + 'px', + 'width': FieldMatrix.MATRIX_NODE_SIZE + 'px' + }); + var nodeSize = FieldMatrix.MATRIX_NODE_SIZE / 4; + var nodePad = FieldMatrix.MATRIX_NODE_SIZE / 16; + for (var i = 0; i < 3; i++) { + for (var n = 0; n < 3; n++) { + Blockly.utils.dom.createSvgElement('rect', { + 'x': ((nodeSize + nodePad) * n) + nodePad, + 'y': ((nodeSize + nodePad) * i) + nodePad, + 'width': nodeSize, 'height': nodeSize, + 'rx': nodePad, 'ry': nodePad, + 'fill': fill + }, button); + } + } + return button; } - // Build the DOM. - this.fieldGroup_ = Blockly.utils.createSvgElement('g', {}, null); - this.size_.width = Blockly.FieldMatrix.THUMBNAIL_SIZE + - Blockly.FieldMatrix.ARROW_SIZE + (Blockly.BlockSvg.DROPDOWN_ARROW_PADDING * 1.5); - - this.sourceBlock_.getSvgRoot().appendChild(this.fieldGroup_); - - var thumbX = Blockly.BlockSvg.DROPDOWN_ARROW_PADDING / 2; - var thumbY = (this.size_.height - Blockly.FieldMatrix.THUMBNAIL_SIZE) / 2; - var thumbnail = Blockly.utils.createSvgElement('g', { - 'transform': 'translate(' + thumbX + ', ' + thumbY + ')', - 'pointer-events': 'bounding-box', 'cursor': 'pointer' - }, this.fieldGroup_); - this.ledThumbNodes_ = []; - var nodeSize = Blockly.FieldMatrix.THUMBNAIL_NODE_SIZE; - var nodePad = Blockly.FieldMatrix.THUMBNAIL_NODE_PAD; - for (var i = 0; i < 5; i++) { - for (var n = 0; n < 5; n++) { - var attr = { - 'x': ((nodeSize + nodePad) * n) + nodePad, - 'y': ((nodeSize + nodePad) * i) + nodePad, - 'width': nodeSize, 'height': nodeSize, - 'rx': nodePad, 'ry': nodePad - }; - this.ledThumbNodes_.push( - Blockly.utils.createSvgElement('rect', attr, thumbnail) - ); + /** + * Redraw the matrix with the current value. + * @private + */ + updateMatrix_() { + const matrix = this.getValue(); + for (var i = 0; i < matrix.length; i++) { + if (matrix[i] === '0') { + this.fillMatrixNode_(this.ledButtons_, i, this.sourceBlock_.getColourSecondary()); + this.fillMatrixNode_(this.ledThumbNodes_, i, this.sourceBlock_.getColour()); + } else { + this.fillMatrixNode_(this.ledButtons_, i, '#FFFFFF'); + this.fillMatrixNode_(this.ledThumbNodes_, i, '#FFFFFF'); + } } - thumbnail.style.cursor = 'default'; - this.updateMatrix_(); } - if (!this.arrow_) { - var arrowX = Blockly.FieldMatrix.THUMBNAIL_SIZE + - Blockly.BlockSvg.DROPDOWN_ARROW_PADDING * 1.5; - var arrowY = (this.size_.height - Blockly.FieldMatrix.ARROW_SIZE) / 2; - this.arrow_ = Blockly.utils.createSvgElement('image', { - 'height': Blockly.FieldMatrix.ARROW_SIZE + 'px', - 'width': Blockly.FieldMatrix.ARROW_SIZE + 'px', - 'transform': 'translate(' + arrowX + ', ' + arrowY + ')' - }, this.fieldGroup_); - this.arrow_.setAttributeNS('http://www.w3.org/1999/xlink', - 'xlink:href', Blockly.mainWorkspace.options.pathToMedia + - 'dropdown-arrow.svg'); - this.arrow_.style.cursor = 'default'; + /** + * Clear the matrix. + * @param {!Event} e Mouse event. + */ + clearMatrix_(e) { + if (e.button != 0) return; + this.setValue(FieldMatrix.ZEROS); } - this.mouseDownWrapper_ = Blockly.bindEventWithChecks_( - this.getClickTarget_(), 'mousedown', this, this.onMouseDown_); -}; + /** + * Fill the matrix. + * @param {!Event} e Mouse event. + */ + fillMatrix_(e) { + if (e.button != 0) return; + this.setValue(FieldMatrix.ONES); + } -/** - * Set the value for this matrix menu. - * @param {string} matrix The new matrix value represented by a 25-bit integer. - * @override - */ -Blockly.FieldMatrix.prototype.setValue = function(matrix) { - if (!matrix || matrix === this.matrix_) { - return; // No change + /** + * Fill matrix node with specified colour. + * @param {!Array} node The array of matrix nodes. + * @param {!number} index The index of the matrix node. + * @param {!string} fill The fill colour in '#rrggbb' format. + */ + fillMatrixNode_(node, index, fill) { + if (!node || !node[index] || !fill) return; + node[index].setAttribute('fill', fill); } - if (this.sourceBlock_ && Blockly.Events.isEnabled()) { - Blockly.Events.fire(new Blockly.Events.Change( - this.sourceBlock_, 'field', this.name, this.matrix_, matrix)); + + setLEDNode_(led, state) { + if (led < 0 || led > 24) return; + const oldMatrix = this.getValue(); + const newMatrix = oldMatrix.substr(0, led) + state + oldMatrix.substr(led + 1); + this.setValue(newMatrix); } - matrix = matrix + Blockly.FieldMatrix.ZEROS.substr(0, 25 - matrix.length); - this.matrix_ = matrix; - this.updateMatrix_(); -}; -/** - * Get the value from this matrix menu. - * @return {string} Current matrix value. - */ -Blockly.FieldMatrix.prototype.getValue = function() { - return String(this.matrix_); -}; + fillLEDNode_(led) { + if (led < 0 || led > 24) return; + this.setLEDNode_(led, '1'); + } -/** - * Show the drop-down menu for editing this field. - * @private - */ -Blockly.FieldMatrix.prototype.showEditor_ = function() { - // If there is an existing drop-down someone else owns, hide it immediately and clear it. - Blockly.DropDownDiv.hideWithoutAnimation(); - Blockly.DropDownDiv.clearContent(); - var div = Blockly.DropDownDiv.getContentDiv(); - // Build the SVG DOM. - var matrixSize = (Blockly.FieldMatrix.MATRIX_NODE_SIZE * 5) + - (Blockly.FieldMatrix.MATRIX_NODE_PAD * 6); - this.matrixStage_ = Blockly.utils.createSvgElement('svg', { - 'xmlns': 'http://www.w3.org/2000/svg', - 'xmlns:html': 'http://www.w3.org/1999/xhtml', - 'xmlns:xlink': 'http://www.w3.org/1999/xlink', - 'version': '1.1', - 'height': matrixSize + 'px', - 'width': matrixSize + 'px' - }, div); - // Create the 5x5 matrix - this.ledButtons_ = []; - for (var i = 0; i < 5; i++) { - for (var n = 0; n < 5; n++) { - var x = (Blockly.FieldMatrix.MATRIX_NODE_SIZE * n) + - (Blockly.FieldMatrix.MATRIX_NODE_PAD * (n + 1)); - var y = (Blockly.FieldMatrix.MATRIX_NODE_SIZE * i) + - (Blockly.FieldMatrix.MATRIX_NODE_PAD * (i + 1)); - var attr = { - 'x': x + 'px', 'y': y + 'px', - 'width': Blockly.FieldMatrix.MATRIX_NODE_SIZE, - 'height': Blockly.FieldMatrix.MATRIX_NODE_SIZE, - 'rx': Blockly.FieldMatrix.MATRIX_NODE_RADIUS, - 'ry': Blockly.FieldMatrix.MATRIX_NODE_RADIUS - }; - var led = Blockly.utils.createSvgElement('rect', attr, this.matrixStage_); - this.matrixStage_.appendChild(led); - this.ledButtons_.push(led); - } + clearLEDNode_(led) { + if (led < 0 || led > 24) return; + this.setLEDNode_(led, '0'); } - // Div for lower button menu - var buttonDiv = document.createElement('div'); - // Button to clear matrix - var clearButtonDiv = document.createElement('div'); - clearButtonDiv.className = 'scratchMatrixButtonDiv'; - var clearButton = this.createButton_(this.sourceBlock_.colourSecondary_); - clearButtonDiv.appendChild(clearButton); - // Button to fill matrix - var fillButtonDiv = document.createElement('div'); - fillButtonDiv.className = 'scratchMatrixButtonDiv'; - var fillButton = this.createButton_('#FFFFFF'); - fillButtonDiv.appendChild(fillButton); - - buttonDiv.appendChild(clearButtonDiv); - buttonDiv.appendChild(fillButtonDiv); - div.appendChild(buttonDiv); - - Blockly.DropDownDiv.setColour(this.sourceBlock_.getColour(), - this.sourceBlock_.getColourTertiary()); - Blockly.DropDownDiv.setCategory(this.sourceBlock_.getCategory()); - Blockly.DropDownDiv.showPositionedByBlock(this, this.sourceBlock_); - - this.matrixTouchWrapper_ = - Blockly.bindEvent_(this.matrixStage_, 'mousedown', this, this.onMouseDown); - this.clearButtonWrapper_ = - Blockly.bindEvent_(clearButton, 'click', this, this.clearMatrix_); - this.fillButtonWrapper_ = - Blockly.bindEvent_(fillButton, 'click', this, this.fillMatrix_); - - // Update the matrix for the current value - this.updateMatrix_(); - -}; - -this.nodeCallback_ = function(e, num) { - console.log(num); -}; -/** - * Make an svg object that resembles a 3x3 matrix to be used as a button. - * @param {string} fill The color to fill the matrix nodes. - * @return {SvgElement} The button svg element. - */ -Blockly.FieldMatrix.prototype.createButton_ = function(fill) { - var button = Blockly.utils.createSvgElement('svg', { - 'xmlns': 'http://www.w3.org/2000/svg', - 'xmlns:html': 'http://www.w3.org/1999/xhtml', - 'xmlns:xlink': 'http://www.w3.org/1999/xlink', - 'version': '1.1', - 'height': Blockly.FieldMatrix.MATRIX_NODE_SIZE + 'px', - 'width': Blockly.FieldMatrix.MATRIX_NODE_SIZE + 'px' - }); - var nodeSize = Blockly.FieldMatrix.MATRIX_NODE_SIZE / 4; - var nodePad = Blockly.FieldMatrix.MATRIX_NODE_SIZE / 16; - for (var i = 0; i < 3; i++) { - for (var n = 0; n < 3; n++) { - Blockly.utils.createSvgElement('rect', { - 'x': ((nodeSize + nodePad) * n) + nodePad, - 'y': ((nodeSize + nodePad) * i) + nodePad, - 'width': nodeSize, 'height': nodeSize, - 'rx': nodePad, 'ry': nodePad, - 'fill': fill - }, button); + toggleLEDNode_(led) { + if (led < 0 || led > 24) return; + if (this.getValue().charAt(led) === '0') { + this.setLEDNode_(led, '1'); + } else { + this.setLEDNode_(led, '0'); } } - return button; -}; -/** - * Redraw the matrix with the current value. - * @private - */ -Blockly.FieldMatrix.prototype.updateMatrix_ = function() { - for (var i = 0; i < this.matrix_.length; i++) { - if (this.matrix_[i] === '0') { - this.fillMatrixNode_(this.ledButtons_, i, this.sourceBlock_.colourSecondary_); - this.fillMatrixNode_(this.ledThumbNodes_, i, this.sourceBlock_.colour_); + /** + * Toggle matrix nodes on and off. + * @param {!Event} e Mouse event. + */ + onMouseDown(e) { + this.matrixMoveWrapper_ = + Blockly.browserEvents.bind(document.body, 'mousemove', this, this.onMouseMove); + this.matrixReleaseWrapper_ = + Blockly.browserEvents.bind(document.body, 'mouseup', this, this.onMouseUp); + var ledHit = this.checkForLED_(e); + if (ledHit > -1) { + if (this.getValue().charAt(ledHit) === '0') { + this.paintStyle_ = 'fill'; + } else { + this.paintStyle_ = 'clear'; + } + this.toggleLEDNode_(ledHit); + this.updateMatrix_(); } else { - this.fillMatrixNode_(this.ledButtons_, i, '#FFFFFF'); - this.fillMatrixNode_(this.ledThumbNodes_, i, '#FFFFFF'); + this.paintStyle_ = null; } } -}; -/** - * Clear the matrix. - * @param {!Event} e Mouse event. - */ -Blockly.FieldMatrix.prototype.clearMatrix_ = function(e) { - if (e.button != 0) return; - this.setValue(Blockly.FieldMatrix.ZEROS); -}; - -/** - * Fill the matrix. - * @param {!Event} e Mouse event. - */ -Blockly.FieldMatrix.prototype.fillMatrix_ = function(e) { - if (e.button != 0) return; - this.setValue(Blockly.FieldMatrix.ONES); -}; - -/** - * Fill matrix node with specified colour. - * @param {!Array} node The array of matrix nodes. - * @param {!number} index The index of the matrix node. - * @param {!string} fill The fill colour in '#rrggbb' format. - */ -Blockly.FieldMatrix.prototype.fillMatrixNode_ = function(node, index, fill) { - if (!node || !node[index] || !fill) return; - node[index].setAttribute('fill', fill); -}; - -Blockly.FieldMatrix.prototype.setLEDNode_ = function(led, state) { - if (led < 0 || led > 24) return; - var matrix = this.matrix_.substr(0, led) + state + this.matrix_.substr(led + 1); - this.setValue(matrix); -}; - -Blockly.FieldMatrix.prototype.fillLEDNode_ = function(led) { - if (led < 0 || led > 24) return; - this.setLEDNode_(led, '1'); -}; - -Blockly.FieldMatrix.prototype.clearLEDNode_ = function(led) { - if (led < 0 || led > 24) return; - this.setLEDNode_(led, '0'); -}; - -Blockly.FieldMatrix.prototype.toggleLEDNode_ = function(led) { - if (led < 0 || led > 24) return; - if (this.matrix_.charAt(led) === '0') { - this.setLEDNode_(led, '1'); - } else { - this.setLEDNode_(led, '0'); + /** + * Unbind mouse move event and clear the paint style. + * @param {!Event} e Mouse move event. + */ + onMouseUp() { + Blockly.browserEvents.unbind(this.matrixMoveWrapper_); + this.matrixMoveWrapper_ = null; + Blockly.browserEvents.unbind(this.matrixReleaseWrapper_); + this.matrixReleaseWrapper_ = null; + this.paintStyle_ = null; } -}; -/** - * Toggle matrix nodes on and off. - * @param {!Event} e Mouse event. - */ -Blockly.FieldMatrix.prototype.onMouseDown = function(e) { - this.matrixMoveWrapper_ = - Blockly.bindEvent_(document.body, 'mousemove', this, this.onMouseMove); - this.matrixReleaseWrapper_ = - Blockly.bindEvent_(document.body, 'mouseup', this, this.onMouseUp); - var ledHit = this.checkForLED_(e); - if (ledHit > -1) { - if (this.matrix_.charAt(ledHit) === '0') { - this.paintStyle_ = 'fill'; - } else { - this.paintStyle_ = 'clear'; + /** + * Toggle matrix nodes on and off by dragging mouse. + * @param {!Event} e Mouse move event. + */ + onMouseMove(e) { + e.preventDefault(); + if (this.paintStyle_) { + var led = this.checkForLED_(e); + if (led < 0) return; + if (this.paintStyle_ === 'clear') { + this.clearLEDNode_(led); + } else if (this.paintStyle_ === 'fill') { + this.fillLEDNode_(led); + } } - this.toggleLEDNode_(ledHit); - this.updateMatrix_(); - } else { - this.paintStyle_ = null; } -}; - -/** - * Unbind mouse move event and clear the paint style. - * @param {!Event} e Mouse move event. - */ -Blockly.FieldMatrix.prototype.onMouseUp = function() { - Blockly.unbindEvent_(this.matrixMoveWrapper_); - Blockly.unbindEvent_(this.matrixReleaseWrapper_); - this.paintStyle_ = null; -}; -/** - * Toggle matrix nodes on and off by dragging mouse. - * @param {!Event} e Mouse move event. - */ -Blockly.FieldMatrix.prototype.onMouseMove = function(e) { - e.preventDefault(); - if (this.paintStyle_) { - var led = this.checkForLED_(e); - if (led < 0) return; - if (this.paintStyle_ === 'clear') { - this.clearLEDNode_(led); - } else if (this.paintStyle_ === 'fill') { - this.fillLEDNode_(led); + /** + * Check if mouse coordinates collide with a matrix node. + * @param {!Event} e Mouse move event. + * @return {number} The matching matrix node or -1 for none. + */ + checkForLED_(e) { + var bBox = this.matrixStage_.getBoundingClientRect(); + var nodeSize = FieldMatrix.MATRIX_NODE_SIZE; + var nodePad = FieldMatrix.MATRIX_NODE_PAD; + var dx = e.clientX - bBox.left; + var dy = e.clientY - bBox.top; + var min = nodePad / 2; + var max = bBox.width - (nodePad / 2); + if (dx < min || dx > max || dy < min || dy > max) { + return -1; } + var xDiv = Math.trunc((dx - nodePad / 2) / (nodeSize + nodePad)); + var yDiv = Math.trunc((dy - nodePad / 2) / (nodeSize + nodePad)); + return xDiv + (yDiv * nodePad); } -}; -/** - * Check if mouse coordinates collide with a matrix node. - * @param {!Event} e Mouse move event. - * @return {number} The matching matrix node or -1 for none. - */ -Blockly.FieldMatrix.prototype.checkForLED_ = function(e) { - var bBox = this.matrixStage_.getBoundingClientRect(); - var nodeSize = Blockly.FieldMatrix.MATRIX_NODE_SIZE; - var nodePad = Blockly.FieldMatrix.MATRIX_NODE_PAD; - var dx = e.clientX - bBox.left; - var dy = e.clientY - bBox.top; - var min = nodePad / 2; - var max = bBox.width - (nodePad / 2); - if (dx < min || dx > max || dy < min || dy > max) { - return -1; + /** + * Clean up this FieldMatrix, as well as the inherited Field. + * @return {!Function} Closure to call on destruction of the WidgetDiv. + * @private + */ + dispose() { + super.dispose(); + this.matrixStage_ = null; + if (this.mouseDownWrapper_) { + Blockly.browserEvents.unbind(this.mouseDownWrapper_); + } + if (this.matrixTouchWrapper_) { + Blockly.browserEvents.unbind(this.matrixTouchWrapper_); + } + if (this.matrixReleaseWrapper_) { + Blockly.browserEvents.unbind(this.matrixReleaseWrapper_); + } + if (this.matrixMoveWrapper_) { + Blockly.browserEvents.unbind(this.matrixMoveWrapper_); + } + if (this.clearButtonWrapper_) { + Blockly.browserEvents.unbind(this.clearButtonWrapper_); + } + if (this.fillButtonWrapper_) { + Blockly.browserEvents.unbind(this.fillButtonWrapper_); + } } - var xDiv = Math.trunc((dx - nodePad / 2) / (nodeSize + nodePad)); - var yDiv = Math.trunc((dy - nodePad / 2) / (nodeSize + nodePad)); - return xDiv + (yDiv * nodePad); -}; -/** - * Clean up this FieldMatrix, as well as the inherited Field. - * @return {!Function} Closure to call on destruction of the WidgetDiv. - * @private - */ -Blockly.FieldMatrix.prototype.dispose_ = function() { - var thisField = this; - return function() { - Blockly.FieldMatrix.superClass_.dispose_.call(thisField)(); - thisField.matrixStage_ = null; - if (thisField.mouseDownWrapper_) { - Blockly.unbindEvent_(thisField.mouseDownWrapper_); - } - if (thisField.matrixTouchWrapper_) { - Blockly.unbindEvent_(thisField.matrixTouchWrapper_); - } - if (thisField.matrixReleaseWrapper_) { - Blockly.unbindEvent_(thisField.matrixReleaseWrapper_); - } - if (thisField.matrixMoveWrapper_) { - Blockly.unbindEvent_(thisField.matrixMoveWrapper_); - } - if (thisField.clearButtonWrapper_) { - Blockly.unbindEvent_(thisField.clearButtonWrapper_); - } - if (thisField.fillButtonWrapper_) { - Blockly.unbindEvent_(thisField.fillButtonWrapper_); - } - }; -}; + updateSize_(margin) { + const constants = this.getConstants(); + let totalHeight = constants.FIELD_TEXT_HEIGHT; + + this.size_.height = totalHeight; + this.size_.width = FieldMatrix.THUMBNAIL_SIZE + + FieldMatrix.ARROW_SIZE + (constants.GRID_UNIT * 2 * 1.5); + + this.positionBorderRect_(); + } + + getClickTarget_() { + return this.sourceBlock_.getSvgRoot(); + } +} -Blockly.Field.register('field_matrix', Blockly.FieldMatrix); +Blockly.fieldRegistry.register('field_matrix', FieldMatrix); diff --git a/src/index.js b/src/index.js index ef61b23af8..3951214280 100644 --- a/src/index.js +++ b/src/index.js @@ -7,6 +7,7 @@ import * as Blockly from 'blockly/core'; import '../blocks_common/colour.js'; import '../blocks_common/math.js'; +import '../blocks_common/matrix.js'; import '../blocks_common/note.js'; import '../blocks_common/text.js'; import '../blocks_vertical/vertical_extensions.js'; @@ -35,6 +36,7 @@ export * from './categories.js'; export * from './procedures.js'; export * from '../core/colours.js'; export * from '../core/field_colour_slider.js'; +export * from '../core/field_matrix.js'; export * from '../core/field_note.js'; export * from '../msg/scratch_msgs.js'; export {scratchBlocksUtils}; From 003afd04b98ae1d3688b5356885e27c116fc61ac Mon Sep 17 00:00:00 2001 From: Aaron Dodson Date: Fri, 3 May 2024 08:21:16 -0700 Subject: [PATCH 032/130] fix: reenable the mobile numpad field (#54) * fix: reenable the mobile numpad field * fix: better align field_number behaviors with Scratch * fix: reenable default number field validation --- core/field_number.js | 550 ++++++++++++++++++++----------------------- src/index.js | 1 + 2 files changed, 256 insertions(+), 295 deletions(-) diff --git a/core/field_number.js b/core/field_number.js index c3307c623a..356c52d781 100644 --- a/core/field_number.js +++ b/core/field_number.js @@ -22,14 +22,8 @@ * @fileoverview Field for numbers. Includes validator and numpad on touch. * @author tmickel@mit.edu (Tim Mickel) */ -'use strict'; - -goog.provide('Blockly.FieldNumber'); - -goog.require('Blockly.FieldTextInput'); -goog.require('Blockly.Touch'); -goog.require('goog.math'); -goog.require('goog.userAgent'); +import * as Blockly from 'blockly/core'; +import {Colours} from './colours.js'; /** * Class for an editable number field. @@ -51,316 +45,282 @@ goog.require('goog.userAgent'); * @extends {Blockly.FieldTextInput} * @constructor */ -Blockly.FieldNumber = function(opt_value, opt_min, opt_max, opt_precision, - opt_validator) { - var numRestrictor = this.getNumRestrictor(opt_min, opt_max, opt_precision); - opt_value = (opt_value && !isNaN(opt_value)) ? String(opt_value) : '0'; - Blockly.FieldNumber.superClass_.constructor.call( - this, opt_value, opt_validator, numRestrictor); - this.addArgType('number'); -}; -goog.inherits(Blockly.FieldNumber, Blockly.FieldTextInput); - -/** - * Construct a FieldNumber from a JSON arg object. - * @param {!Object} options A JSON object with options (value, min, max, and - * precision). - * @returns {!Blockly.FieldNumber} The new field instance. - * @package - * @nocollapse - */ -Blockly.FieldNumber.fromJson = function(options) { - return new Blockly.FieldNumber(options['value'], - options['min'], options['max'], options['precision']); -}; - -/** - * Fixed width of the num-pad drop-down, in px. - * @type {number} - * @const - */ -Blockly.FieldNumber.DROPDOWN_WIDTH = 168; - -/** - * Buttons for the num-pad, in order from the top left. - * Values are strings of the number or symbol will be added to the field text - * when the button is pressed. - * @type {Array.} - * @const - */ -// Calculator order -Blockly.FieldNumber.NUMPAD_BUTTONS = - ['7', '8', '9', '4', '5', '6', '1', '2', '3', '.', '0', '-', ' ']; - -/** - * Src for the delete icon to be shown on the num-pad. - * @type {string} - * @const - */ -Blockly.FieldNumber.NUMPAD_DELETE_ICON = 'data:image/svg+xml;utf8,' + - '' + - ''; - -/** - * Currently active field during an edit. - * Used to give a reference to the num-pad button callbacks. - * @type {?FieldNumber} - * @private - */ -Blockly.FieldNumber.activeField_ = null; - -/** - * Return an appropriate restrictor, depending on whether this FieldNumber - * allows decimal or negative numbers. - * @param {number|string|undefined} opt_min Minimum value. - * @param {number|string|undefined} opt_max Maximum value. - * @param {number|string|undefined} opt_precision Precision for value. - * @return {!RegExp} Regular expression for this FieldNumber's restrictor. - */ -Blockly.FieldNumber.prototype.getNumRestrictor = function(opt_min, opt_max, - opt_precision) { - this.setConstraints_(opt_min, opt_max, opt_precision); - var pattern = "[\\d]"; // Always allow digits. - if (this.decimalAllowed_) { - pattern += "|[\\.]"; - } - if (this.negativeAllowed_) { - pattern += "|[-]"; +class FieldNumberPicker extends Blockly.FieldNumber { + /** + * Fixed width of the num-pad drop-down, in px. + * @type {number} + * @const + */ + static DROPDOWN_WIDTH = 168; + + /** + * Buttons for the num-pad, in order from the top left. + * Values are strings of the number or symbol will be added to the field text + * when the button is pressed. + * @type {Array.} + * @const + */ + // Calculator order + static NUMPAD_BUTTONS = + ['7', '8', '9', '4', '5', '6', '1', '2', '3', '.', '0', '-', ' ']; + + /** + * Src for the delete icon to be shown on the num-pad. + * @type {string} + * @const + */ + static NUMPAD_DELETE_ICON = 'data:image/svg+xml;utf8,' + + '' + + ''; + + configure_(config) { + super.configure_(config); + this.decimalAllowed_ = (typeof config.precision == 'undefined') || + isNaN(config.precision) || (config.precision == 0) || + (Math.floor(config.precision) != config.precision); + this.negativeAllowed_ = (typeof config.min == 'undefined') || isNaN(config.min) || + config.min < 0; + this.exponentialAllowed_ = this.decimalAllowed_; } - if (this.exponentialAllowed_) { - pattern += "|[eE]"; - } - return new RegExp(pattern); -}; -/** - * Set the constraints for this field. - * @param {number=} opt_min Minimum number allowed. - * @param {number=} opt_max Maximum number allowed. - * @param {number=} opt_precision Step allowed between numbers - */ -Blockly.FieldNumber.prototype.setConstraints_ = function(opt_min, opt_max, - opt_precision) { - this.decimalAllowed_ = (typeof opt_precision == 'undefined') || - isNaN(opt_precision) || (opt_precision == 0) || - (Math.floor(opt_precision) != opt_precision); - this.negativeAllowed_ = (typeof opt_min == 'undefined') || isNaN(opt_min) || - opt_min < 0; - this.exponentialAllowed_ = this.decimalAllowed_; -}; + /** + * Return an appropriate restrictor, depending on whether this FieldNumber + * allows decimal or negative numbers. + * @return {!RegExp} Regular expression for this FieldNumber's restrictor. + */ + getNumRestrictor() { + var pattern = "[\\d]"; // Always allow digits. + if (this.decimalAllowed_) { + pattern += "|[\\.]"; + } + if (this.negativeAllowed_) { + pattern += "|[-]"; + } + if (this.exponentialAllowed_) { + pattern += "|[eE]"; + } + return new RegExp(pattern); + } -/** - * Show the inline free-text editor on top of the text and the num-pad if - * appropriate. - * @private - */ -Blockly.FieldNumber.prototype.showEditor_ = function() { - Blockly.FieldNumber.activeField_ = this; - // Do not focus on mobile devices so we can show the num-pad - var showNumPad = this.useTouchInteraction_; - Blockly.FieldNumber.superClass_.showEditor_.call(this, false, showNumPad); - - // Show a numeric keypad in the drop-down on touch - if (showNumPad) { - this.showNumPad_(); + /** + * Show the inline free-text editor on top of the text and the num-pad if + * appropriate. + * @private + */ + showEditor_(e, ) { + // Do not focus on mobile devices so we can show the num-pad + var showNumPad = e && e.pointerType === 'touch'; + super.showEditor_(e, showNumPad); + + // Show a numeric keypad in the drop-down on touch + if (showNumPad) { + this.htmlInput_.select(); + this.showNumPad_(); + } } -}; -/** - * Show the number pad. - * @private - */ -Blockly.FieldNumber.prototype.showNumPad_ = function() { - // If there is an existing drop-down someone else owns, hide it immediately - // and clear it. - Blockly.DropDownDiv.hideWithoutAnimation(); - Blockly.DropDownDiv.clearContent(); + onHtmlInputKeyDown_(e) { + super.onHtmlInputKeyDown_(e); + // key can be things like "Backspace", so only validate when it represents a single + // character so as to allow non-textual input to work as normal. + if (e.key.length === 1) { + const validator = this.getNumRestrictor(); + if (!e.key.match(validator)) { + e.preventDefault(); + } + } + } - var contentDiv = Blockly.DropDownDiv.getContentDiv(); + /** + * Show the number pad. + * @private + */ + showNumPad_() { + var contentDiv = Blockly.DropDownDiv.getContentDiv(); - // Accessibility properties - contentDiv.setAttribute('role', 'menu'); - contentDiv.setAttribute('aria-haspopup', 'true'); + // Accessibility properties + contentDiv.setAttribute('role', 'menu'); + contentDiv.setAttribute('aria-haspopup', 'true'); - this.addButtons_(contentDiv); + this.addButtons_(contentDiv); - // Set colour and size of drop-down - Blockly.DropDownDiv.setColour(this.sourceBlock_.parentBlock_.getColour(), - this.sourceBlock_.getColourTertiary()); - contentDiv.style.width = Blockly.FieldNumber.DROPDOWN_WIDTH + 'px'; + // Set colour and size of drop-down + Blockly.DropDownDiv.setColour(this.sourceBlock_.parentBlock_.getColour(), + this.sourceBlock_.getColourTertiary()); + contentDiv.style.width = FieldNumberPicker.DROPDOWN_WIDTH + 'px'; - this.position_(); -}; + this.position_(); + } -/** - * Figure out where to place the drop-down, and move it there. - * @private - */ -Blockly.FieldNumber.prototype.position_ = function() { - // Calculate positioning for the drop-down - // sourceBlock_ is the rendered shadow field input box - var scale = this.sourceBlock_.workspace.scale; - var bBox = this.sourceBlock_.getHeightWidth(); - bBox.width *= scale; - bBox.height *= scale; - var position = this.getAbsoluteXY_(); - // If we can fit it, render below the shadow block - var primaryX = position.x + bBox.width / 2; - var primaryY = position.y + bBox.height; - // If we can't fit it, render above the entire parent block - var secondaryX = primaryX; - var secondaryY = position.y; - - Blockly.DropDownDiv.setBoundsElement( - this.sourceBlock_.workspace.getParentSvg().parentNode); - Blockly.DropDownDiv.show(this, primaryX, primaryY, secondaryX, secondaryY, - this.onHide_.bind(this)); -}; + /** + * Figure out where to place the drop-down, and move it there. + * @private + */ + position_() { + // Calculate positioning for the drop-down + // sourceBlock_ is the rendered shadow field input box + var scale = this.sourceBlock_.workspace.scale; + var bBox = this.sourceBlock_.getHeightWidth(); + bBox.width *= scale; + bBox.height *= scale; + var position = this.getAbsoluteXY_(); + // If we can fit it, render below the shadow block + var primaryX = position.x + bBox.width / 2; + var primaryY = position.y + bBox.height; + // If we can't fit it, render above the entire parent block + var secondaryX = primaryX; + var secondaryY = position.y; + + Blockly.DropDownDiv.setBoundsElement( + this.sourceBlock_.workspace.getParentSvg().parentNode); + Blockly.DropDownDiv.show(this, this.getSourceBlock().RTL, primaryX, primaryY, secondaryX, secondaryY, + this.onHide_.bind(this)); + } -/** - * Add number, punctuation, and erase buttons to the numeric keypad's content - * div. - * @param {Element} contentDiv The div for the numeric keypad. - * @private - */ -Blockly.FieldNumber.prototype.addButtons_ = function(contentDiv) { - var buttonColour = this.sourceBlock_.parentBlock_.getColour(); - var buttonBorderColour = this.sourceBlock_.parentBlock_.getColourTertiary(); - - // Add numeric keypad buttons - var buttons = Blockly.FieldNumber.NUMPAD_BUTTONS; - for (var i = 0, buttonText; buttonText = buttons[i]; i++) { - var button = document.createElement('button'); - button.setAttribute('role', 'menuitem'); - button.setAttribute('class', 'blocklyNumPadButton'); - button.setAttribute('style', + /** + * Add number, punctuation, and erase buttons to the numeric keypad's content + * div. + * @param {Element} contentDiv The div for the numeric keypad. + * @private + */ + addButtons_(contentDiv) { + var buttonColour = this.sourceBlock_.parentBlock_.getColour(); + var buttonBorderColour = this.sourceBlock_.parentBlock_.getColourTertiary(); + + // Add numeric keypad buttons + var buttons = FieldNumberPicker.NUMPAD_BUTTONS; + for (var i = 0, buttonText; buttonText = buttons[i]; i++) { + var button = document.createElement('button'); + button.setAttribute('role', 'menuitem'); + button.setAttribute('class', 'blocklyNumPadButton'); + button.setAttribute('style', + 'background:' + buttonColour + ';' + + 'border: 1px solid ' + buttonBorderColour + ';'); + button.title = buttonText; + button.innerHTML = buttonText; + Blockly.browserEvents.bind(button, 'mousedown', button, + this.numPadButtonTouch.bind(this)); + if (buttonText == '.' && !this.decimalAllowed_) { + // Don't show the decimal point for inputs that must be round numbers + button.setAttribute('style', 'visibility: hidden'); + } else if (buttonText == '-' && !this.negativeAllowed_) { + continue; + } else if (buttonText == ' ' && !this.negativeAllowed_) { + continue; + } else if (buttonText == ' ' && this.negativeAllowed_) { + button.setAttribute('style', 'visibility: hidden'); + } + contentDiv.appendChild(button); + } + // Add erase button to the end + var eraseButton = document.createElement('button'); + eraseButton.setAttribute('role', 'menuitem'); + eraseButton.setAttribute('class', 'blocklyNumPadButton'); + eraseButton.setAttribute('style', 'background:' + buttonColour + ';' + 'border: 1px solid ' + buttonBorderColour + ';'); - button.title = buttonText; - button.innerHTML = buttonText; - Blockly.bindEvent_(button, 'mousedown', button, - Blockly.FieldNumber.numPadButtonTouch); - if (buttonText == '.' && !this.decimalAllowed_) { - // Don't show the decimal point for inputs that must be round numbers - button.setAttribute('style', 'visibility: hidden'); - } else if (buttonText == '-' && !this.negativeAllowed_) { - continue; - } else if (buttonText == ' ' && !this.negativeAllowed_) { - continue; - } else if (buttonText == ' ' && this.negativeAllowed_) { - button.setAttribute('style', 'visibility: hidden'); - } - contentDiv.appendChild(button); - } - // Add erase button to the end - var eraseButton = document.createElement('button'); - eraseButton.setAttribute('role', 'menuitem'); - eraseButton.setAttribute('class', 'blocklyNumPadButton'); - eraseButton.setAttribute('style', - 'background:' + buttonColour + ';' + - 'border: 1px solid ' + buttonBorderColour + ';'); - eraseButton.title = 'Delete'; - - var eraseImage = document.createElement('img'); - eraseImage.src = Blockly.FieldNumber.NUMPAD_DELETE_ICON; - eraseButton.appendChild(eraseImage); - - Blockly.bindEvent_(eraseButton, 'mousedown', null, - Blockly.FieldNumber.numPadEraseButtonTouch); - contentDiv.appendChild(eraseButton); -}; - -/** - * Call for when a num-pad number or punctuation button is touched. - * Determine what the user is inputting and update the text field appropriately. - * @param {Event} e DOM event triggering the touch. - */ -Blockly.FieldNumber.numPadButtonTouch = function(e) { - // String of the button (e.g., '7') - var spliceValue = this.innerHTML; - // Old value of the text field - var oldValue = Blockly.FieldTextInput.htmlInput_.value; - // Determine the selected portion of the text field - var selectionStart = Blockly.FieldTextInput.htmlInput_.selectionStart; - var selectionEnd = Blockly.FieldTextInput.htmlInput_.selectionEnd; + eraseButton.title = 'Delete'; - // Splice in the new value - var newValue = oldValue.slice(0, selectionStart) + spliceValue + - oldValue.slice(selectionEnd); + var eraseImage = document.createElement('img'); + eraseImage.src = FieldNumberPicker.NUMPAD_DELETE_ICON; + eraseButton.appendChild(eraseImage); - // Set new value and advance the cursor - Blockly.FieldNumber.updateDisplay_(newValue, selectionStart + spliceValue.length); + Blockly.browserEvents.bind(eraseButton, 'mousedown', null, + this.numPadEraseButtonTouch.bind(this)); + contentDiv.appendChild(eraseButton); + } - // This is just a click. - Blockly.Touch.clearTouchIdentifier(); + /** + * Call for when a num-pad number or punctuation button is touched. + * Determine what the user is inputting and update the text field appropriately. + * @param {Event} e DOM event triggering the touch. + */ + numPadButtonTouch(e) { + // String of the button (e.g., '7') + var spliceValue = e.target.innerText; + // Old value of the text field + var oldValue = this.htmlInput_.value; + // Determine the selected portion of the text field + var selectionStart = this.htmlInput_.selectionStart; + var selectionEnd = this.htmlInput_.selectionEnd; + + // Splice in the new value + var newValue = oldValue.slice(0, selectionStart) + spliceValue + + oldValue.slice(selectionEnd); + + // Set new value and advance the cursor + this.updateDisplay_(newValue, selectionStart + spliceValue.length); + + // This is just a click. + Blockly.Touch.clearTouchIdentifier(); + + // Prevent default to not lose input focus + e.preventDefault(); + } - // Prevent default to not lose input focus - e.preventDefault(); -}; + /** + * Call for when the num-pad erase button is touched. + * Determine what the user is asking to erase, and erase it. + * @param {Event} e DOM event triggering the touch. + */ + numPadEraseButtonTouch(e) { + // Old value of the text field + var oldValue = this.htmlInput_.value; + // Determine what is selected to erase (if anything) + var selectionStart = this.htmlInput_.selectionStart; + var selectionEnd = this.htmlInput_.selectionEnd; + + // If selection is zero-length, shift start to the left 1 character + if (selectionStart == selectionEnd) { + selectionStart = Math.max(0, selectionStart - 1); + } -/** - * Call for when the num-pad erase button is touched. - * Determine what the user is asking to erase, and erase it. - * @param {Event} e DOM event triggering the touch. - */ -Blockly.FieldNumber.numPadEraseButtonTouch = function(e) { - // Old value of the text field - var oldValue = Blockly.FieldTextInput.htmlInput_.value; - // Determine what is selected to erase (if anything) - var selectionStart = Blockly.FieldTextInput.htmlInput_.selectionStart; - var selectionEnd = Blockly.FieldTextInput.htmlInput_.selectionEnd; - - // If selection is zero-length, shift start to the left 1 character - if (selectionStart == selectionEnd) { - selectionStart = Math.max(0, selectionStart - 1); - } + // Cut out selected range + var newValue = oldValue.slice(0, selectionStart) + + oldValue.slice(selectionEnd); - // Cut out selected range - var newValue = oldValue.slice(0, selectionStart) + - oldValue.slice(selectionEnd); + this.updateDisplay_(newValue, selectionStart); - Blockly.FieldNumber.updateDisplay_(newValue, selectionStart); + // This is just a click. + Blockly.Touch.clearTouchIdentifier(); - // This is just a click. - Blockly.Touch.clearTouchIdentifier(); + // Prevent default to not lose input focus which resets cursors in Chrome + e.preventDefault(); + } - // Prevent default to not lose input focus which resets cursors in Chrome - e.preventDefault(); -}; + /** + * Update the displayed value and resize/scroll the text field as needed. + * @param {string} newValue The new text to display. + * @param {string} newSelection The new index to put the cursor + * @private + */ + updateDisplay_(newValue, newSelection) { + this.setEditorValue_(newValue); + // Resize and scroll the text field appropriately + const htmlInput = this.htmlInput_ + htmlInput.setSelectionRange(newSelection, newSelection); + htmlInput.scrollLeft = htmlInput.scrollWidth; + } -/** - * Update the displayed value and resize/scroll the text field as needed. - * @param {string} newValue The new text to display. - * @param {string} newSelection The new index to put the cursor - * @private. - */ -Blockly.FieldNumber.updateDisplay_ = function(newValue, newSelection) { - var htmlInput = Blockly.FieldTextInput.htmlInput_; - // Updates the display. The actual setValue occurs when editing ends. - htmlInput.value = newValue; - // Resize and scroll the text field appropriately - Blockly.FieldNumber.superClass_.resizeEditor_.call( - Blockly.FieldNumber.activeField_); - htmlInput.setSelectionRange(newSelection, newSelection); - htmlInput.scrollLeft = htmlInput.scrollWidth; - Blockly.FieldNumber.activeField_.validate_(); -}; + /** + * Callback for when the drop-down is hidden. + */ + onHide_() { + // Clear accessibility properties + Blockly.DropDownDiv.getContentDiv().removeAttribute('role'); + Blockly.DropDownDiv.getContentDiv().removeAttribute('aria-haspopup'); + } +} -/** - * Callback for when the drop-down is hidden. - */ -Blockly.FieldNumber.prototype.onHide_ = function() { - // Clear accessibility properties - Blockly.DropDownDiv.content_.removeAttribute('role'); - Blockly.DropDownDiv.content_.removeAttribute('aria-haspopup'); -}; +FieldNumberPicker.prototype.DEFAULT_VALUE = ''; -Blockly.Field.register('field_number', Blockly.FieldNumber); +Blockly.fieldRegistry.unregister('field_number'); +Blockly.fieldRegistry.register('field_number', FieldNumberPicker); diff --git a/src/index.js b/src/index.js index 3951214280..d4a89f660d 100644 --- a/src/index.js +++ b/src/index.js @@ -38,6 +38,7 @@ export * from '../core/colours.js'; export * from '../core/field_colour_slider.js'; export * from '../core/field_matrix.js'; export * from '../core/field_note.js'; +export * from '../core/field_number.js'; export * from '../msg/scratch_msgs.js'; export {scratchBlocksUtils}; export {CheckableContinuousFlyout}; From 70c8cfd73ee1081eafcb2773fe56a4e078cb2bea Mon Sep 17 00:00:00 2001 From: Aaron Dodson Date: Fri, 3 May 2024 19:44:43 -0700 Subject: [PATCH 033/130] fix: reenable reporting block values (#55) * fix: reenable reporting block values * fix: make reporter bubbles appear on the correct block * fix: avoid error when attempting to report values of nonexistent blocks --- src/block_reporting.js | 21 +++++++++++++++++++++ src/checkable_continuous_flyout.js | 10 ++++++++++ src/index.js | 1 + 3 files changed, 32 insertions(+) create mode 100644 src/block_reporting.js diff --git a/src/block_reporting.js b/src/block_reporting.js new file mode 100644 index 0000000000..6950d57175 --- /dev/null +++ b/src/block_reporting.js @@ -0,0 +1,21 @@ +import * as Blockly from 'blockly/core'; +import {Colours} from '../core/colours.js'; + +export function reportValue(id, value) { + const block = Blockly.getMainWorkspace().getBlockById(id) || + Blockly.getMainWorkspace().getFlyout().getWorkspace().getBlockById(id); + if (!block) { + throw 'Tried to report value on block that does not exist.'; + } + const field = block.inputList[0].fieldRow[0]; + const contentDiv = Blockly.DropDownDiv.getContentDiv(); + const valueReportBox = document.createElement('div'); + valueReportBox.setAttribute('class', 'valueReportBox'); + valueReportBox.innerText = value; + contentDiv.appendChild(valueReportBox); + Blockly.DropDownDiv.setColour( + Colours.valueReportBackground, + Colours.valueReportBorder + ); + Blockly.DropDownDiv.showPositionedByBlock(field, block); +} diff --git a/src/checkable_continuous_flyout.js b/src/checkable_continuous_flyout.js index fc2db632b1..f67833ab0d 100644 --- a/src/checkable_continuous_flyout.js +++ b/src/checkable_continuous_flyout.js @@ -74,6 +74,16 @@ export class CheckableContinuousFlyout extends ContinuousFlyout { super.show(flyoutDef); } + serializeBlock(block) { + const json = super.serializeBlock(block); + // Delete the serialized block's ID so that a new one is generated when it is + // placed on the workspace. Otherwise, the block on the workspace may be + // indistinguishable from the one in the flyout, which can cause reporter blocks + // to have their value dropdown shown in the wrong place. + delete json.id; + return json; + } + clearOldCheckboxes() { for (const checkbox of this.checkboxes_.values()) { checkbox.svgRoot.remove(); diff --git a/src/index.js b/src/index.js index d4a89f660d..2c58a3aed1 100644 --- a/src/index.js +++ b/src/index.js @@ -32,6 +32,7 @@ import {CheckableContinuousFlyout} from './checkable_continuous_flyout.js'; import './scratch_continuous_category.js'; export * from 'blockly'; +export * from './block_reporting.js'; export * from './categories.js'; export * from './procedures.js'; export * from '../core/colours.js'; From f3e059cbf5cf3ce4e063871632a213c8d58f1000 Mon Sep 17 00:00:00 2001 From: Aaron Dodson Date: Mon, 6 May 2024 09:49:54 -0700 Subject: [PATCH 034/130] fix: resolve error when adding the stop block to the workspace (#56) --- blocks_vertical/control.js | 22 ++-------------------- 1 file changed, 2 insertions(+), 20 deletions(-) diff --git a/blocks_vertical/control.js b/blocks_vertical/control.js index d9de23414a..c555a6544b 100644 --- a/blocks_vertical/control.js +++ b/blocks_vertical/control.js @@ -188,17 +188,8 @@ Blockly.Blocks['control_stop'] = { [Blockly.Msg.CONTROL_STOP_OTHER, OTHER_SCRIPTS] ]; }, function(option) { - // Create an event group to keep field value and mutator in sync - // Return null at the end because setValue is called here already. - Blockly.Events.setGroup(true); - var oldMutation = Blockly.Xml.domToText(this.sourceBlock_.mutationToDom()); - this.sourceBlock_.setNextStatement(option == OTHER_SCRIPTS); - var newMutation = Blockly.Xml.domToText(this.sourceBlock_.mutationToDom()); - Blockly.Events.fire(new Blockly.Events.BlockChange(this.sourceBlock_, - 'mutation', null, oldMutation, newMutation)); - this.setValue(option); - Blockly.Events.setGroup(false); - return null; + this.getSourceBlock().setNextStatement(option === OTHER_SCRIPTS); + return option; }); this.appendDummyInput() .appendField(Blockly.Msg.CONTROL_STOP) @@ -209,15 +200,6 @@ Blockly.Blocks['control_stop'] = { Colours.control.quaternary ); this.setPreviousStatement(true); - }, - mutationToDom: function() { - var container = document.createElement('mutation'); - container.setAttribute('hasnext', this.nextConnection != null); - return container; - }, - domToMutation: function(xmlElement) { - var hasNext = (xmlElement.getAttribute('hasnext') == 'true'); - this.setNextStatement(hasNext); } }; From 0d675673de70153fcb38b0049e39fdadbc061dab Mon Sep 17 00:00:00 2001 From: Aaron Dodson Date: Mon, 6 May 2024 10:38:07 -0700 Subject: [PATCH 035/130] chore: update to the latest continuous toolbox (#58) --- package-lock.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/package-lock.json b/package-lock.json index 159c22b5b1..071bca4add 100644 --- a/package-lock.json +++ b/package-lock.json @@ -123,9 +123,9 @@ } }, "node_modules/@blockly/continuous-toolbox": { - "version": "5.0.15", - "resolved": "https://registry.npmjs.org/@blockly/continuous-toolbox/-/continuous-toolbox-5.0.15.tgz", - "integrity": "sha512-XXW+ETvPljsq9A5KdXO/aKnVbEIy+ANlgfQmPN9Vztl4U0NdQ3QvA/PtZRlZ6ISJdEkM4GnhTXOIIO+0qDqJ8w==", + "version": "5.0.17", + "resolved": "https://registry.npmjs.org/@blockly/continuous-toolbox/-/continuous-toolbox-5.0.17.tgz", + "integrity": "sha512-3JCSimCo5KEWvvN4qC66vs2L/WtJIHepoIfkPNcbvMwjwYxJ484UPK2LKdlyI1842mgFfcYM3nTERjfa+Q4rXA==", "engines": { "node": ">=8.17.0" }, @@ -7123,9 +7123,9 @@ } }, "@blockly/continuous-toolbox": { - "version": "5.0.15", - "resolved": "https://registry.npmjs.org/@blockly/continuous-toolbox/-/continuous-toolbox-5.0.15.tgz", - "integrity": "sha512-XXW+ETvPljsq9A5KdXO/aKnVbEIy+ANlgfQmPN9Vztl4U0NdQ3QvA/PtZRlZ6ISJdEkM4GnhTXOIIO+0qDqJ8w==", + "version": "5.0.17", + "resolved": "https://registry.npmjs.org/@blockly/continuous-toolbox/-/continuous-toolbox-5.0.17.tgz", + "integrity": "sha512-3JCSimCo5KEWvvN4qC66vs2L/WtJIHepoIfkPNcbvMwjwYxJ484UPK2LKdlyI1842mgFfcYM3nTERjfa+Q4rXA==", "requires": {} }, "@blockly/field-colour": { From 33e9e91be1210c1699bc3491df5d9c7c191bc30d Mon Sep 17 00:00:00 2001 From: Aaron Dodson Date: Mon, 6 May 2024 13:41:59 -0700 Subject: [PATCH 036/130] fix: show the glow only when blocks are running (#57) * fix: show the glow only when blocks are running * refactor: remove glowBlock and add defs to the workspace svg --- src/glows.js | 78 ++++++++++++++++++++++++++++++++++++++++++++++++++++ src/index.js | 11 ++++++++ 2 files changed, 89 insertions(+) create mode 100644 src/glows.js diff --git a/src/glows.js b/src/glows.js new file mode 100644 index 0000000000..7172e6c9dc --- /dev/null +++ b/src/glows.js @@ -0,0 +1,78 @@ +import * as Blockly from 'blockly/core'; +import {Colours} from '../core/colours.js'; + +/** + * Glow/unglow a stack in the workspace. + * @param {?string} id ID of block which starts the stack. + * @param {boolean} isGlowingStack Whether to glow the stack. + */ +export function glowStack(id, isGlowingStack) { + if (id) { + const block = Blockly.getMainWorkspace().getBlockById(id) || + Blockly.getMainWorkspace().getFlyout().getWorkspace().getBlockById(id); + if (!block) { + throw 'Tried to glow block that does not exist.'; + } + + const svg = block.getSvgRoot(); + if (isGlowingStack && !svg.hasAttribute('filter')) { + svg.setAttribute('filter', 'url(#blocklyStackGlowFilter)'); + } else if (!isGlowingStack && svg.hasAttribute('filter')) { + svg.removeAttribute('filter'); + } + } +} + +export function buildGlowFilter(workspace) { + const svg = workspace.getParentSvg(); + const defs = Blockly.utils.dom.createSvgElement(Blockly.utils.Svg.DEFS, {}, svg); + // Using a dilate distorts the block shape. + // Instead use a gaussian blur, and then set all alpha to 1 with a transfer. + const stackGlowFilter = Blockly.utils.dom.createSvgElement('filter', + { + 'id': 'blocklyStackGlowFilter', + 'height': '160%', + 'width': '180%', + y: '-30%', + x: '-40%' + }, + defs); + Blockly.utils.dom.createSvgElement('feGaussianBlur', + { + 'in': 'SourceGraphic', + 'stdDeviation': Colours.stackGlowSize + }, + stackGlowFilter); + // Set all gaussian blur pixels to 1 opacity before applying flood + const componentTransfer = Blockly.utils.dom.createSvgElement( + 'feComponentTransfer', {'result': 'outBlur'}, stackGlowFilter); + Blockly.utils.dom.createSvgElement('feFuncA', + { + 'type': 'table', + 'tableValues': '0' + ' 1'.repeat(16), + }, + componentTransfer); + // Color the highlight + Blockly.utils.dom.createSvgElement('feFlood', + { + 'flood-color': Colours.stackGlow, + 'flood-opacity': Colours.stackGlowOpacity, + 'result': 'outColor' + }, + stackGlowFilter); + Blockly.utils.dom.createSvgElement('feComposite', + { + 'in': 'outColor', + 'in2': 'outBlur', + 'operator': 'in', + 'result': 'outGlow' + }, + stackGlowFilter); + Blockly.utils.dom.createSvgElement('feComposite', + { + 'in': 'SourceGraphic', + 'in2': 'outGlow', + 'operator': 'over' + }, + stackGlowFilter); +} diff --git a/src/index.js b/src/index.js index 2c58a3aed1..aab92e6a22 100644 --- a/src/index.js +++ b/src/index.js @@ -29,6 +29,7 @@ import { ContinuousMetrics, } from '@blockly/continuous-toolbox'; import {CheckableContinuousFlyout} from './checkable_continuous_flyout.js'; +import {buildGlowFilter, glowStack} from './glows.js'; import './scratch_continuous_category.js'; export * from 'blockly'; @@ -41,6 +42,7 @@ export * from '../core/field_matrix.js'; export * from '../core/field_note.js'; export * from '../core/field_number.js'; export * from '../msg/scratch_msgs.js'; +export {glowStack}; export {scratchBlocksUtils}; export {CheckableContinuousFlyout}; @@ -53,6 +55,15 @@ export function inject(container, options) { }, }); const workspace = Blockly.inject(container, options); + workspace.getRenderer().getConstants().selectedGlowFilterId = ''; + + const flyout = workspace.getFlyout(); + if (flyout) { + flyout.getWorkspace().getRenderer().getConstants().selectedGlowFilterId = ''; + } + + buildGlowFilter(workspace); + return workspace; } From aeec5ec5c581d0b5d1331449d5168d22abede60d Mon Sep 17 00:00:00 2001 From: Aaron Dodson Date: Tue, 7 May 2024 11:58:04 -0700 Subject: [PATCH 037/130] chore: upgrade dependency to Blockly v11 beta (#75) --- package-lock.json | 368 ++++++++++++++++++++++------------------------ package.json | 3 +- src/index.js | 2 + 3 files changed, 179 insertions(+), 194 deletions(-) diff --git a/package-lock.json b/package-lock.json index 071bca4add..b05266debe 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,8 +10,9 @@ "license": "Apache-2.0", "dependencies": { "@blockly/continuous-toolbox": "^5.0.15", + "@blockly/field-angle": "^4.0.2", "@blockly/field-colour": "^4.0.2", - "blockly": "^10.0.0" + "blockly": "^11.0.0-beta.11" }, "devDependencies": { "@commitlint/cli": "^17.8.1", @@ -133,6 +134,17 @@ "blockly": "^10.0.0" } }, + "node_modules/@blockly/field-angle": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@blockly/field-angle/-/field-angle-4.0.2.tgz", + "integrity": "sha512-N7kxQtmoPUuu3oKtOrrVpqBa6hMagmKxwDZkh9mvo2K0AiFbysVzmqfXhz1gGt4Z9ve617h9gTO4dk/qWpc/fQ==", + "engines": { + "node": ">=8.0.0" + }, + "peerDependencies": { + "blockly": "^10.0.0" + } + }, "node_modules/@blockly/field-colour": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/@blockly/field-colour/-/field-colour-4.0.2.tgz", @@ -574,14 +586,6 @@ "integrity": "sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A==", "dev": true }, - "node_modules/@tootallnate/once": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", - "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==", - "engines": { - "node": ">= 10" - } - }, "node_modules/@tsconfig/node10": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz", @@ -1015,7 +1019,8 @@ "version": "2.0.6", "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz", "integrity": "sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==", - "deprecated": "Use your platform's native atob() and btoa() methods instead" + "deprecated": "Use your platform's native atob() and btoa() methods instead", + "dev": true }, "node_modules/accepts": { "version": "1.3.8", @@ -1082,14 +1087,14 @@ } }, "node_modules/agent-base": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", - "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz", + "integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==", "dependencies": { - "debug": "4" + "debug": "^4.3.4" }, "engines": { - "node": ">= 6.0.0" + "node": ">= 14" } }, "node_modules/ajv": { @@ -1346,11 +1351,14 @@ } }, "node_modules/blockly": { - "version": "10.4.3", - "resolved": "https://registry.npmjs.org/blockly/-/blockly-10.4.3.tgz", - "integrity": "sha512-+opfBmQnSiv7vTiY/TkDEBOslxUyfj8luS3S+qs1NnQKjInC+Waf2l9cNsMh9J8BMkmiCIT+Ed/3mmjIaL9wug==", + "version": "11.0.0-beta.11", + "resolved": "https://registry.npmjs.org/blockly/-/blockly-11.0.0-beta.11.tgz", + "integrity": "sha512-re2FiKJ9WVigldQShnZAinMZw7V0fjgHstOgHQsG/2ARnmu3xOhPsEq059+d+WtMgM09UXl1liYO76dTZPuD+w==", "dependencies": { - "jsdom": "22.1.0" + "jsdom": "23.0.0" + }, + "engines": { + "node": ">=18" } }, "node_modules/body-parser": { @@ -2045,16 +2053,15 @@ } }, "node_modules/data-urls": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-4.0.0.tgz", - "integrity": "sha512-/mMTei/JXPqvFqQtfyTowxmJVwr2PVAeCcDxyFf6LhoOu/09TX2OX3kb2wzi4DMXcfj4OItwDOnhl5oziPnT6g==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-5.0.0.tgz", + "integrity": "sha512-ZYP5VBHshaDAiVZxjbRVcFJpc+4xGgT0bK3vzy1HLN8jTO975HEbuYzZJcHoQEY5K1a0z8YayJkyVETa08eNTg==", "dependencies": { - "abab": "^2.0.6", - "whatwg-mimetype": "^3.0.0", - "whatwg-url": "^12.0.0" + "whatwg-mimetype": "^4.0.0", + "whatwg-url": "^14.0.0" }, "engines": { - "node": ">=14" + "node": ">=18" } }, "node_modules/debug": { @@ -2225,18 +2232,6 @@ "node": ">=0.10.0" } }, - "node_modules/domexception": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/domexception/-/domexception-4.0.0.tgz", - "integrity": "sha512-A2is4PLG+eeSfoTMA95/s4pvAoSo2mKtiM5jlHkAVewmiO8ISFTFKZjH7UAM1Atli/OT/7JHOrJRJiMKUZKYBw==", - "deprecated": "Use your platform's native DOMException instead", - "dependencies": { - "webidl-conversions": "^7.0.0" - }, - "engines": { - "node": ">=12" - } - }, "node_modules/dot-prop": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", @@ -3432,14 +3427,14 @@ } }, "node_modules/html-encoding-sniffer": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-3.0.0.tgz", - "integrity": "sha512-oWv4T4yJ52iKrufjnyZPkrN0CH3QnrUqdB6In1g5Fe1mia8GmF36gnfNySxoZtxD5+NmYw1EElVXiBk93UeskA==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-4.0.0.tgz", + "integrity": "sha512-Y22oTqIU4uuPgEemfz7NDJz6OeKf12Lsu+QC+s3BVpda64lTiMYCyGwg5ki4vFxkMwQdeZDl2adZoqUgdFuTgQ==", "dependencies": { - "whatwg-encoding": "^2.0.0" + "whatwg-encoding": "^3.1.1" }, "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/html-entities": { @@ -3501,16 +3496,15 @@ } }, "node_modules/http-proxy-agent": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", - "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", + "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", "dependencies": { - "@tootallnate/once": "2", - "agent-base": "6", - "debug": "4" + "agent-base": "^7.1.0", + "debug": "^4.3.4" }, "engines": { - "node": ">= 6" + "node": ">= 14" } }, "node_modules/http-proxy-middleware": { @@ -3538,15 +3532,15 @@ } }, "node_modules/https-proxy-agent": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", - "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.4.tgz", + "integrity": "sha512-wlwpilI7YdjSkWaQ/7omYBMTliDcmCN8OLihO6I9B86g06lMyAoqgoDpV0XqoaPOKj+0DIdAvnsWfyAAhmimcg==", "dependencies": { - "agent-base": "6", + "agent-base": "^7.0.2", "debug": "4" }, "engines": { - "node": ">= 6" + "node": ">= 14" } }, "node_modules/human-signals": { @@ -4022,39 +4016,37 @@ } }, "node_modules/jsdom": { - "version": "22.1.0", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-22.1.0.tgz", - "integrity": "sha512-/9AVW7xNbsBv6GfWho4TTNjEo9fe6Zhf9O7s0Fhhr3u+awPwAJMKwAMXnkk5vBxflqLW9hTHX/0cs+P3gW+cQw==", + "version": "23.0.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-23.0.0.tgz", + "integrity": "sha512-cbL/UCtohJguhFC7c2/hgW6BeZCNvP7URQGnx9tSJRYKCdnfbfWOrtuLTMfiB2VxKsx5wPHVsh/J0aBy9lIIhQ==", "dependencies": { - "abab": "^2.0.6", "cssstyle": "^3.0.0", - "data-urls": "^4.0.0", + "data-urls": "^5.0.0", "decimal.js": "^10.4.3", - "domexception": "^4.0.0", "form-data": "^4.0.0", - "html-encoding-sniffer": "^3.0.0", - "http-proxy-agent": "^5.0.0", - "https-proxy-agent": "^5.0.1", + "html-encoding-sniffer": "^4.0.0", + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.2", "is-potential-custom-element-name": "^1.0.1", - "nwsapi": "^2.2.4", + "nwsapi": "^2.2.7", "parse5": "^7.1.2", "rrweb-cssom": "^0.6.0", "saxes": "^6.0.0", "symbol-tree": "^3.2.4", - "tough-cookie": "^4.1.2", - "w3c-xmlserializer": "^4.0.0", + "tough-cookie": "^4.1.3", + "w3c-xmlserializer": "^5.0.0", "webidl-conversions": "^7.0.0", - "whatwg-encoding": "^2.0.0", - "whatwg-mimetype": "^3.0.0", - "whatwg-url": "^12.0.1", - "ws": "^8.13.0", - "xml-name-validator": "^4.0.0" + "whatwg-encoding": "^3.1.1", + "whatwg-mimetype": "^4.0.0", + "whatwg-url": "^14.0.0", + "ws": "^8.14.2", + "xml-name-validator": "^5.0.0" }, "engines": { - "node": ">=16" + "node": ">=18" }, "peerDependencies": { - "canvas": "^2.5.0" + "canvas": "^3.0.0" }, "peerDependenciesMeta": { "canvas": { @@ -4569,9 +4561,9 @@ } }, "node_modules/nwsapi": { - "version": "2.2.7", - "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.7.tgz", - "integrity": "sha512-ub5E4+FBPKwAZx0UwIQOjYWGHTEq5sPqHQNRN8Z9e4A7u3Tj1weLJsL59yH9vmvqEtBHaOmT6cYQKIZOxp35FQ==" + "version": "2.2.9", + "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.9.tgz", + "integrity": "sha512-2f3F0SEEer8bBu0dsNCFF50N0cTThV1nWFYcEYFZttdW0lDAoybv9cQoK7X7/68Z89S7FoRrVjP1LPX4XRf9vg==" }, "node_modules/object-assign": { "version": "4.1.1", @@ -6209,9 +6201,9 @@ } }, "node_modules/tough-cookie": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.3.tgz", - "integrity": "sha512-aX/y5pVRkfRnfmuX+OdbSdXvPe6ieKX/G2s7e98f4poJHnqH3281gDPm/metm6E/WRamfx7WC4HUqkWHfQHprw==", + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.4.tgz", + "integrity": "sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==", "dependencies": { "psl": "^1.1.33", "punycode": "^2.1.1", @@ -6223,14 +6215,14 @@ } }, "node_modules/tr46": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-4.1.1.tgz", - "integrity": "sha512-2lv/66T7e5yNyhAAC4NaKe5nVavzuGJQVVtRYLyQ2OI8tsJ61PMLlelehb0wi2Hx6+hT/OJUWZcw8MjlSRnxvw==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-5.0.0.tgz", + "integrity": "sha512-tk2G5R2KRwBd+ZN0zaEXpmzdKyOYksXwywulIX95MBODjSzMIuQnQ3m8JxgbhnL1LeVo7lqQKsYa1O3Htl7K5g==", "dependencies": { - "punycode": "^2.3.0" + "punycode": "^2.3.1" }, "engines": { - "node": ">=14" + "node": ">=18" } }, "node_modules/trim-newlines": { @@ -6462,14 +6454,14 @@ } }, "node_modules/w3c-xmlserializer": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-4.0.0.tgz", - "integrity": "sha512-d+BFHzbiCx6zGfz0HyQ6Rg69w9k19nviJspaj4yNscGjrHu94sVP+aRm75yEbCh+r2/yR+7q6hux9LVtbuTGBw==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-5.0.0.tgz", + "integrity": "sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==", "dependencies": { - "xml-name-validator": "^4.0.0" + "xml-name-validator": "^5.0.0" }, "engines": { - "node": ">=14" + "node": ">=18" } }, "node_modules/watchpack": { @@ -6840,34 +6832,34 @@ } }, "node_modules/whatwg-encoding": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-2.0.0.tgz", - "integrity": "sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz", + "integrity": "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==", "dependencies": { "iconv-lite": "0.6.3" }, "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/whatwg-mimetype": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-3.0.0.tgz", - "integrity": "sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz", + "integrity": "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==", "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/whatwg-url": { - "version": "12.0.1", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-12.0.1.tgz", - "integrity": "sha512-Ed/LrqB8EPlGxjS+TrsXcpUond1mhccS3pchLhzSgPCnTimUCKj3IZE75pAs5m6heB2U2TMerKFUXheyHY+VDQ==", + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-14.0.0.tgz", + "integrity": "sha512-1lfMEm2IEr7RIV+f4lUNPOqfFL+pO+Xw3fJSqmjX9AbXcXcYOkCe1P6+9VBZB6n94af16NfZf+sSk0JCBZC9aw==", "dependencies": { - "tr46": "^4.1.1", + "tr46": "^5.0.0", "webidl-conversions": "^7.0.0" }, "engines": { - "node": ">=14" + "node": ">=18" } }, "node_modules/which": { @@ -6956,11 +6948,11 @@ } }, "node_modules/xml-name-validator": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-4.0.0.tgz", - "integrity": "sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-5.0.0.tgz", + "integrity": "sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==", "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/xmlchars": { @@ -7128,6 +7120,12 @@ "integrity": "sha512-3JCSimCo5KEWvvN4qC66vs2L/WtJIHepoIfkPNcbvMwjwYxJ484UPK2LKdlyI1842mgFfcYM3nTERjfa+Q4rXA==", "requires": {} }, + "@blockly/field-angle": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@blockly/field-angle/-/field-angle-4.0.2.tgz", + "integrity": "sha512-N7kxQtmoPUuu3oKtOrrVpqBa6hMagmKxwDZkh9mvo2K0AiFbysVzmqfXhz1gGt4Z9ve617h9gTO4dk/qWpc/fQ==", + "requires": {} + }, "@blockly/field-colour": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/@blockly/field-colour/-/field-colour-4.0.2.tgz", @@ -7475,11 +7473,6 @@ "integrity": "sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A==", "dev": true }, - "@tootallnate/once": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", - "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==" - }, "@tsconfig/node10": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz", @@ -7899,7 +7892,8 @@ "abab": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz", - "integrity": "sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==" + "integrity": "sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==", + "dev": true }, "accepts": { "version": "1.3.8", @@ -7948,11 +7942,11 @@ "dev": true }, "agent-base": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", - "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz", + "integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==", "requires": { - "debug": "4" + "debug": "^4.3.4" } }, "ajv": { @@ -8153,11 +8147,11 @@ "dev": true }, "blockly": { - "version": "10.4.3", - "resolved": "https://registry.npmjs.org/blockly/-/blockly-10.4.3.tgz", - "integrity": "sha512-+opfBmQnSiv7vTiY/TkDEBOslxUyfj8luS3S+qs1NnQKjInC+Waf2l9cNsMh9J8BMkmiCIT+Ed/3mmjIaL9wug==", + "version": "11.0.0-beta.11", + "resolved": "https://registry.npmjs.org/blockly/-/blockly-11.0.0-beta.11.tgz", + "integrity": "sha512-re2FiKJ9WVigldQShnZAinMZw7V0fjgHstOgHQsG/2ARnmu3xOhPsEq059+d+WtMgM09UXl1liYO76dTZPuD+w==", "requires": { - "jsdom": "22.1.0" + "jsdom": "23.0.0" } }, "body-parser": { @@ -8684,13 +8678,12 @@ "dev": true }, "data-urls": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-4.0.0.tgz", - "integrity": "sha512-/mMTei/JXPqvFqQtfyTowxmJVwr2PVAeCcDxyFf6LhoOu/09TX2OX3kb2wzi4DMXcfj4OItwDOnhl5oziPnT6g==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-5.0.0.tgz", + "integrity": "sha512-ZYP5VBHshaDAiVZxjbRVcFJpc+4xGgT0bK3vzy1HLN8jTO975HEbuYzZJcHoQEY5K1a0z8YayJkyVETa08eNTg==", "requires": { - "abab": "^2.0.6", - "whatwg-mimetype": "^3.0.0", - "whatwg-url": "^12.0.0" + "whatwg-mimetype": "^4.0.0", + "whatwg-url": "^14.0.0" } }, "debug": { @@ -8815,14 +8808,6 @@ "esutils": "^2.0.2" } }, - "domexception": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/domexception/-/domexception-4.0.0.tgz", - "integrity": "sha512-A2is4PLG+eeSfoTMA95/s4pvAoSo2mKtiM5jlHkAVewmiO8ISFTFKZjH7UAM1Atli/OT/7JHOrJRJiMKUZKYBw==", - "requires": { - "webidl-conversions": "^7.0.0" - } - }, "dot-prop": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", @@ -9772,11 +9757,11 @@ } }, "html-encoding-sniffer": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-3.0.0.tgz", - "integrity": "sha512-oWv4T4yJ52iKrufjnyZPkrN0CH3QnrUqdB6In1g5Fe1mia8GmF36gnfNySxoZtxD5+NmYw1EElVXiBk93UeskA==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-4.0.0.tgz", + "integrity": "sha512-Y22oTqIU4uuPgEemfz7NDJz6OeKf12Lsu+QC+s3BVpda64lTiMYCyGwg5ki4vFxkMwQdeZDl2adZoqUgdFuTgQ==", "requires": { - "whatwg-encoding": "^2.0.0" + "whatwg-encoding": "^3.1.1" } }, "html-entities": { @@ -9822,13 +9807,12 @@ } }, "http-proxy-agent": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", - "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", + "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", "requires": { - "@tootallnate/once": "2", - "agent-base": "6", - "debug": "4" + "agent-base": "^7.1.0", + "debug": "^4.3.4" } }, "http-proxy-middleware": { @@ -9845,11 +9829,11 @@ } }, "https-proxy-agent": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", - "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.4.tgz", + "integrity": "sha512-wlwpilI7YdjSkWaQ/7omYBMTliDcmCN8OLihO6I9B86g06lMyAoqgoDpV0XqoaPOKj+0DIdAvnsWfyAAhmimcg==", "requires": { - "agent-base": "6", + "agent-base": "^7.0.2", "debug": "4" } }, @@ -10210,33 +10194,31 @@ } }, "jsdom": { - "version": "22.1.0", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-22.1.0.tgz", - "integrity": "sha512-/9AVW7xNbsBv6GfWho4TTNjEo9fe6Zhf9O7s0Fhhr3u+awPwAJMKwAMXnkk5vBxflqLW9hTHX/0cs+P3gW+cQw==", + "version": "23.0.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-23.0.0.tgz", + "integrity": "sha512-cbL/UCtohJguhFC7c2/hgW6BeZCNvP7URQGnx9tSJRYKCdnfbfWOrtuLTMfiB2VxKsx5wPHVsh/J0aBy9lIIhQ==", "requires": { - "abab": "^2.0.6", "cssstyle": "^3.0.0", - "data-urls": "^4.0.0", + "data-urls": "^5.0.0", "decimal.js": "^10.4.3", - "domexception": "^4.0.0", "form-data": "^4.0.0", - "html-encoding-sniffer": "^3.0.0", - "http-proxy-agent": "^5.0.0", - "https-proxy-agent": "^5.0.1", + "html-encoding-sniffer": "^4.0.0", + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.2", "is-potential-custom-element-name": "^1.0.1", - "nwsapi": "^2.2.4", + "nwsapi": "^2.2.7", "parse5": "^7.1.2", "rrweb-cssom": "^0.6.0", "saxes": "^6.0.0", "symbol-tree": "^3.2.4", - "tough-cookie": "^4.1.2", - "w3c-xmlserializer": "^4.0.0", + "tough-cookie": "^4.1.3", + "w3c-xmlserializer": "^5.0.0", "webidl-conversions": "^7.0.0", - "whatwg-encoding": "^2.0.0", - "whatwg-mimetype": "^3.0.0", - "whatwg-url": "^12.0.1", - "ws": "^8.13.0", - "xml-name-validator": "^4.0.0" + "whatwg-encoding": "^3.1.1", + "whatwg-mimetype": "^4.0.0", + "whatwg-url": "^14.0.0", + "ws": "^8.14.2", + "xml-name-validator": "^5.0.0" } }, "json-parse-even-better-errors": { @@ -10646,9 +10628,9 @@ } }, "nwsapi": { - "version": "2.2.7", - "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.7.tgz", - "integrity": "sha512-ub5E4+FBPKwAZx0UwIQOjYWGHTEq5sPqHQNRN8Z9e4A7u3Tj1weLJsL59yH9vmvqEtBHaOmT6cYQKIZOxp35FQ==" + "version": "2.2.9", + "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.9.tgz", + "integrity": "sha512-2f3F0SEEer8bBu0dsNCFF50N0cTThV1nWFYcEYFZttdW0lDAoybv9cQoK7X7/68Z89S7FoRrVjP1LPX4XRf9vg==" }, "object-assign": { "version": "4.1.1", @@ -11915,9 +11897,9 @@ "dev": true }, "tough-cookie": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.3.tgz", - "integrity": "sha512-aX/y5pVRkfRnfmuX+OdbSdXvPe6ieKX/G2s7e98f4poJHnqH3281gDPm/metm6E/WRamfx7WC4HUqkWHfQHprw==", + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.4.tgz", + "integrity": "sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==", "requires": { "psl": "^1.1.33", "punycode": "^2.1.1", @@ -11926,11 +11908,11 @@ } }, "tr46": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-4.1.1.tgz", - "integrity": "sha512-2lv/66T7e5yNyhAAC4NaKe5nVavzuGJQVVtRYLyQ2OI8tsJ61PMLlelehb0wi2Hx6+hT/OJUWZcw8MjlSRnxvw==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-5.0.0.tgz", + "integrity": "sha512-tk2G5R2KRwBd+ZN0zaEXpmzdKyOYksXwywulIX95MBODjSzMIuQnQ3m8JxgbhnL1LeVo7lqQKsYa1O3Htl7K5g==", "requires": { - "punycode": "^2.3.0" + "punycode": "^2.3.1" } }, "trim-newlines": { @@ -12083,11 +12065,11 @@ "dev": true }, "w3c-xmlserializer": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-4.0.0.tgz", - "integrity": "sha512-d+BFHzbiCx6zGfz0HyQ6Rg69w9k19nviJspaj4yNscGjrHu94sVP+aRm75yEbCh+r2/yR+7q6hux9LVtbuTGBw==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-5.0.0.tgz", + "integrity": "sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==", "requires": { - "xml-name-validator": "^4.0.0" + "xml-name-validator": "^5.0.0" } }, "watchpack": { @@ -12342,24 +12324,24 @@ "dev": true }, "whatwg-encoding": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-2.0.0.tgz", - "integrity": "sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz", + "integrity": "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==", "requires": { "iconv-lite": "0.6.3" } }, "whatwg-mimetype": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-3.0.0.tgz", - "integrity": "sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q==" + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz", + "integrity": "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==" }, "whatwg-url": { - "version": "12.0.1", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-12.0.1.tgz", - "integrity": "sha512-Ed/LrqB8EPlGxjS+TrsXcpUond1mhccS3pchLhzSgPCnTimUCKj3IZE75pAs5m6heB2U2TMerKFUXheyHY+VDQ==", + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-14.0.0.tgz", + "integrity": "sha512-1lfMEm2IEr7RIV+f4lUNPOqfFL+pO+Xw3fJSqmjX9AbXcXcYOkCe1P6+9VBZB6n94af16NfZf+sSk0JCBZC9aw==", "requires": { - "tr46": "^4.1.1", + "tr46": "^5.0.0", "webidl-conversions": "^7.0.0" } }, @@ -12417,9 +12399,9 @@ "requires": {} }, "xml-name-validator": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-4.0.0.tgz", - "integrity": "sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==" + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-5.0.0.tgz", + "integrity": "sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==" }, "xmlchars": { "version": "2.2.0", diff --git a/package.json b/package.json index 3f052b4f49..a80e261d44 100644 --- a/package.json +++ b/package.json @@ -28,7 +28,8 @@ }, "dependencies": { "@blockly/continuous-toolbox": "^5.0.15", + "@blockly/field-angle": "^4.0.2", "@blockly/field-colour": "^4.0.2", - "blockly": "^10.0.0" + "blockly": "^11.0.0-beta.11" } } diff --git a/src/index.js b/src/index.js index aab92e6a22..e9fba0444f 100644 --- a/src/index.js +++ b/src/index.js @@ -5,6 +5,8 @@ */ import * as Blockly from 'blockly/core'; +import {registerFieldAngle} from '@blockly/field-angle'; +registerFieldAngle(); import '../blocks_common/colour.js'; import '../blocks_common/math.js'; import '../blocks_common/matrix.js'; From cb5b068afa6e781e649754b55fc013a02112431e Mon Sep 17 00:00:00 2001 From: Aaron Dodson Date: Thu, 16 May 2024 15:53:56 -0700 Subject: [PATCH 038/130] fix: improve reliability of block value reporting (#77) * fix: improve reliability of block value reporting * chore: add comment clarifying recycling behavior --- src/block_reporting.js | 11 ++++++++++- src/checkable_continuous_flyout.js | 8 ++++++++ src/index.js | 3 ++- src/scratch_continuous_toolbox.js | 12 ++++++++++++ 4 files changed, 32 insertions(+), 2 deletions(-) create mode 100644 src/scratch_continuous_toolbox.js diff --git a/src/block_reporting.js b/src/block_reporting.js index 6950d57175..3cd2854cfd 100644 --- a/src/block_reporting.js +++ b/src/block_reporting.js @@ -7,7 +7,16 @@ export function reportValue(id, value) { if (!block) { throw 'Tried to report value on block that does not exist.'; } - const field = block.inputList[0].fieldRow[0]; + + let field; + for (const input of block.inputList) { + for (const f of input.fieldRow) { + field = f; + break; + } + } + if (!field) return; + const contentDiv = Blockly.DropDownDiv.getContentDiv(); const valueReportBox = document.createElement('div'); valueReportBox.setAttribute('class', 'valueReportBox'); diff --git a/src/checkable_continuous_flyout.js b/src/checkable_continuous_flyout.js index f67833ab0d..f14d9047d9 100644 --- a/src/checkable_continuous_flyout.js +++ b/src/checkable_continuous_flyout.js @@ -218,4 +218,12 @@ export class CheckableContinuousFlyout extends ContinuousFlyout { getFlyoutScale() { return 0.675; } + + blockIsRecyclable_(block) { + const recyclable = super.blockIsRecyclable_(block); + // Exclude blocks with output connections, because they are able to report their current + // value in a popover and recycling them interacts poorly with the VM's maintenance of its + // state. + return recyclable && !block.outputConnection; + } } diff --git a/src/index.js b/src/index.js index e9fba0444f..7170893fef 100644 --- a/src/index.js +++ b/src/index.js @@ -31,6 +31,7 @@ import { ContinuousMetrics, } from '@blockly/continuous-toolbox'; import {CheckableContinuousFlyout} from './checkable_continuous_flyout.js'; +import {ScratchContinuousToolbox} from './scratch_continuous_toolbox.js'; import {buildGlowFilter, glowStack} from './glows.js'; import './scratch_continuous_category.js'; @@ -51,7 +52,7 @@ export {CheckableContinuousFlyout}; export function inject(container, options) { Object.assign(options, { plugins: { - toolbox: ContinuousToolbox, + toolbox: ScratchContinuousToolbox, flyoutsVerticalToolbox: CheckableContinuousFlyout, metricsManager: ContinuousMetrics, }, diff --git a/src/scratch_continuous_toolbox.js b/src/scratch_continuous_toolbox.js new file mode 100644 index 0000000000..0be28b0a95 --- /dev/null +++ b/src/scratch_continuous_toolbox.js @@ -0,0 +1,12 @@ +import * as Blockly from 'blockly/core'; +import {ContinuousToolbox} from '@blockly/continuous-toolbox'; + +export class ScratchContinuousToolbox extends ContinuousToolbox { + refreshSelection() { + // Intentionally a no-op, Scratch manually manages refreshing the toolbox via forceRerender(). + } + + forceRerender() { + super.refreshSelection(); + } +} From 1f1c8598a5dac8bb42dd82fff7edc7eda7fe4225 Mon Sep 17 00:00:00 2001 From: Aaron Dodson Date: Fri, 17 May 2024 15:10:55 -0700 Subject: [PATCH 039/130] fix: use non-deprecated input type constants (#78) --- blocks_vertical/procedures.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/blocks_vertical/procedures.js b/blocks_vertical/procedures.js index 941acb8d5e..71f103257e 100644 --- a/blocks_vertical/procedures.js +++ b/blocks_vertical/procedures.js @@ -561,9 +561,9 @@ function updateDeclarationProcCode_() { this.procCode_ += ' '; } var input = this.inputList[i]; - if (input.type == Blockly.DUMMY_INPUT) { + if (input.type == Blockly.inputs.inputTypes.DUMMY) { this.procCode_ += input.fieldRow[0].getValue(); - } else if (input.type == Blockly.INPUT_VALUE) { + } else if (input.type == Blockly.inputs.inputTypes.VALUE) { // Inspect the argument editor. var target = input.connection.targetBlock(); this.displayNames_.push(target.getFieldValue('TEXT')); @@ -587,9 +587,9 @@ function updateDeclarationProcCode_() { function focusLastEditor_() { if (this.inputList.length > 0) { var newInput = this.inputList[this.inputList.length - 1]; - if (newInput.type == Blockly.DUMMY_INPUT) { + if (newInput.type == Blockly.inputs.inputTypes.DUMMY) { newInput.fieldRow[0].showEditor_(); - } else if (newInput.type == Blockly.INPUT_VALUE) { + } else if (newInput.type == Blockly.inputs.inputTypes.VALUE) { // Inspect the argument editor. var target = newInput.connection.targetBlock(); target.getField('TEXT').showEditor_(); From fd1bc58bdef66697b0630d1c67f5a04d01dfa716 Mon Sep 17 00:00:00 2001 From: Aaron Dodson Date: Fri, 17 May 2024 15:44:37 -0700 Subject: [PATCH 040/130] fix: match Scratch behaviors around dragging and connection stickiness (#80) --- src/index.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/index.js b/src/index.js index 7170893fef..7ad5679595 100644 --- a/src/index.js +++ b/src/index.js @@ -67,6 +67,12 @@ export function inject(container, options) { buildGlowFilter(workspace); + Blockly.config.dragRadius = 3; + Blockly.config.snapRadius = 48; + Blockly.config.connectingSnapRadius = 68; + Blockly.config.currentConnectionPreference = 20; + Blockly.config.bumpDelay = 0; + return workspace; } From 94d2a2ca55c0d0265a79237610bcf8c246d74a9b Mon Sep 17 00:00:00 2001 From: Aaron Dodson Date: Tue, 21 May 2024 15:19:09 -0700 Subject: [PATCH 041/130] fix: reenable shadows for blocks being dragged (#79) * fix: reenable shadows for blocks being dragged * fix: apply drop shadows to all dragging things via CSS * chore: add a license to shadows.js --- core/colours.js | 2 +- core/css.js | 6 ++++++ src/index.js | 4 +++- src/shadows.js | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 56 insertions(+), 2 deletions(-) create mode 100644 src/shadows.js diff --git a/core/colours.js b/core/colours.js index 167336594b..12fd515b0a 100644 --- a/core/colours.js +++ b/core/colours.js @@ -103,7 +103,7 @@ "textFieldText": "#575E75", "insertionMarker": "#000000", "insertionMarkerOpacity": 0.2, - "dragShadowOpacity": 0.3, + "dragShadowOpacity": 0.6, "stackGlow": "#FFF200", "stackGlowSize": 4, "stackGlowOpacity": 1, diff --git a/core/css.js b/core/css.js index 2ec49ad874..e6526522b1 100644 --- a/core/css.js +++ b/core/css.js @@ -284,6 +284,12 @@ const styles = ` cursor: -webkit-grabbing; cursor: -moz-grabbing; } + + /* All the blocks being dragged get the blocklyDragging class, so match only the root one */ + :not(.blocklyDragging) > .blocklyDragging { + filter: url(#blocklyDragShadowFilter); + } + /* Changes cursor on mouse down. Not effective in Firefox because of https://bugzilla.mozilla.org/show_bug.cgi?id=771241 */ .blocklyDraggable:active { diff --git a/src/index.js b/src/index.js index 7ad5679595..d00c3b2a40 100644 --- a/src/index.js +++ b/src/index.js @@ -31,9 +31,10 @@ import { ContinuousMetrics, } from '@blockly/continuous-toolbox'; import {CheckableContinuousFlyout} from './checkable_continuous_flyout.js'; -import {ScratchContinuousToolbox} from './scratch_continuous_toolbox.js'; import {buildGlowFilter, glowStack} from './glows.js'; +import {ScratchContinuousToolbox} from './scratch_continuous_toolbox.js'; import './scratch_continuous_category.js'; +import {buildShadowFilter} from './shadows.js'; export * from 'blockly'; export * from './block_reporting.js'; @@ -66,6 +67,7 @@ export function inject(container, options) { } buildGlowFilter(workspace); + buildShadowFilter(workspace); Blockly.config.dragRadius = 3; Blockly.config.snapRadius = 48; diff --git a/src/shadows.js b/src/shadows.js new file mode 100644 index 0000000000..c585a4211c --- /dev/null +++ b/src/shadows.js @@ -0,0 +1,46 @@ +/** + * @license + * Copyright 2024 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + +import * as Blockly from 'blockly/core'; +import {Colours} from '../core/colours.js'; + +export function buildShadowFilter(workspace) { + const svg = workspace.getParentSvg(); + const defs = Blockly.utils.dom.createSvgElement(Blockly.utils.Svg.DEFS, {}, svg); + // Adjust these width/height, x/y properties to stop the shadow from clipping + var dragShadowFilter = Blockly.utils.dom.createSvgElement('filter', + { + 'id': 'blocklyDragShadowFilter', + 'height': '140%', + 'width': '140%', + 'y': '-20%', + 'x': '-20%' + }, + defs); + Blockly.utils.dom.createSvgElement('feGaussianBlur', + { + 'in': 'SourceAlpha', + 'stdDeviation': '6' + }, + dragShadowFilter); + var componentTransfer = Blockly.utils.dom.createSvgElement( + 'feComponentTransfer', {'result': 'offsetBlur'}, dragShadowFilter); + // Shadow opacity is specified in the adjustable colour library, + // since the darkness of the shadow largely depends on the workspace colour. + Blockly.utils.dom.createSvgElement('feFuncA', + { + 'type': 'linear', + 'slope': Colours.dragShadowOpacity + }, + componentTransfer); + Blockly.utils.dom.createSvgElement('feComposite', + { + 'in': 'SourceGraphic', + 'in2': 'offsetBlur', + 'operator': 'over' + }, + dragShadowFilter); +} From 9e01bc5dba677211da3f49efc4cf62643cf7c555 Mon Sep 17 00:00:00 2001 From: Aaron Dodson Date: Wed, 22 May 2024 11:25:30 -0700 Subject: [PATCH 042/130] chore: upgrade to Blockly v11 (#81) --- msg/scratch_msgs.js | 24 ++++++++++++------------ package-lock.json | 14 +++++++------- package.json | 2 +- 3 files changed, 20 insertions(+), 20 deletions(-) diff --git a/msg/scratch_msgs.js b/msg/scratch_msgs.js index 12716e7bd5..9312dc206a 100644 --- a/msg/scratch_msgs.js +++ b/msg/scratch_msgs.js @@ -1,17 +1,20 @@ -import * as Blockly from 'blockly'; +import * as Blockly from 'blockly/core'; -const ScratchMsgs = { - currentLocale_: 'en', - setLocale: function(locale) { +export class ScratchMsgs { + static currentLocale_ = 'en'; + static locales = {}; + + static setLocale(locale) { if (Object.keys(this.locales).includes(locale)) { this.currentLocale_ = locale; - Blockly.Msg = Object.assign({}, Blockly.Msg, this.locales[locale]); + Object.assign(Blockly.Msg, this.locales[locale]); } else { // keep current locale console.warn('Ignoring unrecognized locale: ' + locale); } - }, - translate: function(msgId, defaultMsg, useLocale) { + } + + static translate(msgId, defaultMsg, useLocale) { var locale = useLocale || this.currentLocale_; if (Object.keys(this.locales).includes(locale)) { @@ -21,9 +24,8 @@ const ScratchMsgs = { } } return defaultMsg; - }, - locales: {}, -}; + } +} ScratchMsgs.locales["ab"] = { @@ -22985,5 +22987,3 @@ ScratchMsgs.locales["zh-tw"] = "DEFAULT_BROADCAST_MESSAGE_NAME": "message1" }; // End of combined translations - -export {ScratchMsgs}; diff --git a/package-lock.json b/package-lock.json index b05266debe..1635af2260 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,7 +12,7 @@ "@blockly/continuous-toolbox": "^5.0.15", "@blockly/field-angle": "^4.0.2", "@blockly/field-colour": "^4.0.2", - "blockly": "^11.0.0-beta.11" + "blockly": "^11.0.0" }, "devDependencies": { "@commitlint/cli": "^17.8.1", @@ -1351,9 +1351,9 @@ } }, "node_modules/blockly": { - "version": "11.0.0-beta.11", - "resolved": "https://registry.npmjs.org/blockly/-/blockly-11.0.0-beta.11.tgz", - "integrity": "sha512-re2FiKJ9WVigldQShnZAinMZw7V0fjgHstOgHQsG/2ARnmu3xOhPsEq059+d+WtMgM09UXl1liYO76dTZPuD+w==", + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/blockly/-/blockly-11.0.0.tgz", + "integrity": "sha512-6Ie7HuZWZLaETIVKFEP4FPDz267Pubn6+weQNZvXzqnkOYp9sKPSsPue8QIMCV9Qb5F4wYhqivgiDcZJcE1UlQ==", "dependencies": { "jsdom": "23.0.0" }, @@ -8147,9 +8147,9 @@ "dev": true }, "blockly": { - "version": "11.0.0-beta.11", - "resolved": "https://registry.npmjs.org/blockly/-/blockly-11.0.0-beta.11.tgz", - "integrity": "sha512-re2FiKJ9WVigldQShnZAinMZw7V0fjgHstOgHQsG/2ARnmu3xOhPsEq059+d+WtMgM09UXl1liYO76dTZPuD+w==", + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/blockly/-/blockly-11.0.0.tgz", + "integrity": "sha512-6Ie7HuZWZLaETIVKFEP4FPDz267Pubn6+weQNZvXzqnkOYp9sKPSsPue8QIMCV9Qb5F4wYhqivgiDcZJcE1UlQ==", "requires": { "jsdom": "23.0.0" } diff --git a/package.json b/package.json index a80e261d44..7b831293e4 100644 --- a/package.json +++ b/package.json @@ -30,6 +30,6 @@ "@blockly/continuous-toolbox": "^5.0.15", "@blockly/field-angle": "^4.0.2", "@blockly/field-colour": "^4.0.2", - "blockly": "^11.0.0-beta.11" + "blockly": "^11.0.0" } } From 98ccb62d7280d2cc711337581464138a281453e3 Mon Sep 17 00:00:00 2001 From: Aaron Dodson Date: Wed, 12 Jun 2024 09:27:41 -0700 Subject: [PATCH 043/130] fix: enable and style workspace comments (#82) * fix: show workspace comment menu items * fix: mostly match Scratch's styling of workspace comments * fix: register workspace comment menu items only once --- core/css.js | 51 +++++++++++++++++++ media/delete-icon.svg | 10 ++++ ...omment-arrow-down.svg => foldout-icon.svg} | 0 media/resize-handle.svg | 3 ++ src/index.js | 1 + 5 files changed, 65 insertions(+) create mode 100644 media/delete-icon.svg rename media/{comment-arrow-down.svg => foldout-icon.svg} (100%) create mode 100644 media/resize-handle.svg diff --git a/core/css.js b/core/css.js index e6526522b1..b908ae2f4f 100644 --- a/core/css.js +++ b/core/css.js @@ -1287,6 +1287,57 @@ const styles = ` width: 1.25rem; height: 1.25rem; } + + .blocklyCommentTopbar { + height: 32px; + --commentBorderColour: #e2db96; + } + + .blocklyCommentTopbarBackground { + height: 32px; + } + + .blocklyFoldoutIcon { + width: 32px; + height: 32px; + transform-origin: 16px 16px; + } + + .blocklyComment:not(.blocklyCollapsed) .blocklyCommentHighlight, + .blocklySelected .blocklyCommentHighlight, + .blocklyCollapsed .blocklyCommentTopbarBackground, + .blocklyCollapsed.blocklySelected .blocklyCommentTopbarBackground { + stroke: #bcA903; + stroke-width: 1px; + } + + .blocklyCollapsed.blocklyComment .blocklyFoldoutIcon { + transform: rotate(-180deg); + } + + .zelos-renderer.scratch-theme .blocklyComment .blocklyTextarea { + border: none; + --commentFillColour: #fef49c; + font-size: 12pt; + font-weight: 400; + padding: 12px; + color: #575e75; + } + + .zelos-renderer.scratch-theme .blocklyCommentText.blocklyText { + font-weight: 400; + } + + .blocklyDeleteIcon { + display: block; + width: 32px; + height: 32px; + } + + .blocklyResizeHandle { + height: 20px; + width: 20px; + } `; Blockly.Css.register(styles); diff --git a/media/delete-icon.svg b/media/delete-icon.svg new file mode 100644 index 0000000000..ed1f71edff --- /dev/null +++ b/media/delete-icon.svg @@ -0,0 +1,10 @@ + + + + delete-x + Created with Sketch. + + + + + diff --git a/media/comment-arrow-down.svg b/media/foldout-icon.svg similarity index 100% rename from media/comment-arrow-down.svg rename to media/foldout-icon.svg diff --git a/media/resize-handle.svg b/media/resize-handle.svg new file mode 100644 index 0000000000..b7002710e5 --- /dev/null +++ b/media/resize-handle.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/index.js b/src/index.js index d00c3b2a40..1e2dc0ca8d 100644 --- a/src/index.js +++ b/src/index.js @@ -83,3 +83,4 @@ Blockly.FlyoutButton.TEXT_MARGIN_X = 40; Blockly.FlyoutButton.TEXT_MARGIN_Y = 10; Blockly.ContextMenuRegistry.registry.unregister('blockDisable'); Blockly.ContextMenuRegistry.registry.unregister('blockInline'); +Blockly.ContextMenuItems.registerCommentOptions(); From 8902091c2da8ab68aeac6e2a3954741197a50b37 Mon Sep 17 00:00:00 2001 From: Aaron Dodson Date: Thu, 11 Jul 2024 13:31:54 -0700 Subject: [PATCH 044/130] fix: add support for Scratch-style block comments (#83) * fix: add support for Scratch-style block comments * chore: add license header. * refactor: remove redundant property initialization. This is handled in the superclass. * chore: add comments to clarify disabling undo in block comment events. * chore: add @implements annotations to bubble/icon classes. * refactor: remove redundant listener cleanup. * refactor: use an early return when serializing comment icons. * chore: format comment icon. * refactor: set initial comment position in onLocationChange instead of constructor. * refactor: make comment bubbles preserve their offset automatically when their anchor point is set. * refactor: correctly calculate the block comment anchor point. * refactor: use the bubble layer constant. * chore: format block events. * refactor: initialize block comment anchors at the correct location * refactor: don't decompose objects when serializing --- core/css.js | 6 +- src/events_block_comment_base.js | 35 +++++ src/events_block_comment_change.js | 43 ++++++ src/events_block_comment_collapse.js | 43 ++++++ src/events_block_comment_create.js | 52 +++++++ src/events_block_comment_delete.js | 27 ++++ src/events_block_comment_move.js | 54 ++++++++ src/events_block_comment_resize.js | 52 +++++++ src/index.js | 7 + src/scratch_comment_bubble.js | 168 +++++++++++++++++++++++ src/scratch_comment_icon.js | 195 +++++++++++++++++++++++++++ 11 files changed, 681 insertions(+), 1 deletion(-) create mode 100644 src/events_block_comment_base.js create mode 100644 src/events_block_comment_change.js create mode 100644 src/events_block_comment_collapse.js create mode 100644 src/events_block_comment_create.js create mode 100644 src/events_block_comment_delete.js create mode 100644 src/events_block_comment_move.js create mode 100644 src/events_block_comment_resize.js create mode 100644 src/scratch_comment_bubble.js create mode 100644 src/scratch_comment_icon.js diff --git a/core/css.js b/core/css.js index b908ae2f4f..39dfa07ebe 100644 --- a/core/css.js +++ b/core/css.js @@ -1288,6 +1288,10 @@ const styles = ` height: 1.25rem; } + .blocklyComment { + --colour-commentBorder: #bcA903; + } + .blocklyCommentTopbar { height: 32px; --commentBorderColour: #e2db96; @@ -1307,7 +1311,7 @@ const styles = ` .blocklySelected .blocklyCommentHighlight, .blocklyCollapsed .blocklyCommentTopbarBackground, .blocklyCollapsed.blocklySelected .blocklyCommentTopbarBackground { - stroke: #bcA903; + stroke: var(--colour-commentBorder); stroke-width: 1px; } diff --git a/src/events_block_comment_base.js b/src/events_block_comment_base.js new file mode 100644 index 0000000000..248f978f89 --- /dev/null +++ b/src/events_block_comment_base.js @@ -0,0 +1,35 @@ +/** + * @license + * Copyright 2024 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + +import * as Blockly from "blockly/core"; + +export class BlockCommentBase extends Blockly.Events.Abstract { + constructor(opt_blockComment) { + super(); + this.isBlank = !opt_blockComment; + + if (!opt_blockComment) return; + + this.commentId = opt_blockComment.getId(); + this.blockId = opt_blockComment.getSourceBlock()?.id; + this.workspaceId = opt_blockComment.getSourceBlock()?.workspace.id; + } + + toJson() { + return { + ...super.toJson(), + commentId: this.commentId, + blockId: this.blockId, + }; + } + + static fromJson(json, workspace, event) { + const newEvent = super.fromJson(json, workspace, event); + newEvent.commentId = json["commentId"]; + newEvent.blockId = json["blockId"]; + return newEvent; + } +} diff --git a/src/events_block_comment_change.js b/src/events_block_comment_change.js new file mode 100644 index 0000000000..46299d942c --- /dev/null +++ b/src/events_block_comment_change.js @@ -0,0 +1,43 @@ +/** + * @license + * Copyright 2024 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + +import * as Blockly from "blockly/core"; +import { BlockCommentBase } from "./events_block_comment_base.js"; + +class BlockCommentChange extends BlockCommentBase { + constructor(opt_blockComment, oldContents, newContents) { + super(opt_blockComment); + this.type = "block_comment_change"; + this.oldContents_ = oldContents; + this.newContents_ = newContents; + // Disable undo because Blockly already tracks changes to comment text for + // undo purposes; this event exists solely to keep the Scratch VM apprised + // of the state of things. + this.recordUndo = false; + } + + toJson() { + return { + ...super.toJson(), + newContents: this.newContents_, + oldContents: this.oldContents_, + }; + } + + static fromJson(json, workspace, event) { + const newEvent = super.fromJson(json, workspace, event); + newEvent.newContents_ = json["newContents"]; + newEvent.oldContents_ = json["oldContents"]; + + return newEvent; + } +} + +Blockly.registry.register( + Blockly.registry.Type.EVENT, + "block_comment_change", + BlockCommentChange +); diff --git a/src/events_block_comment_collapse.js b/src/events_block_comment_collapse.js new file mode 100644 index 0000000000..ad982d79f8 --- /dev/null +++ b/src/events_block_comment_collapse.js @@ -0,0 +1,43 @@ +/** + * @license + * Copyright 2024 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + +import * as Blockly from "blockly/core"; +import { BlockCommentBase } from "./events_block_comment_base.js"; + +class BlockCommentCollapse extends BlockCommentBase { + constructor(opt_blockComment, collapsed) { + super(opt_blockComment); + this.type = "block_comment_collapse"; + this.newCollapsed = collapsed; + } + + toJson() { + return { + ...super.toJson(), + collapsed: this.newCollapsed, + }; + } + + static fromJson(json, workspace, event) { + const newEvent = super.fromJson(json, workspace, event); + newEvent.newCollapsed = json["collapsed"]; + + return newEvent; + } + + run(forward) { + const workspace = this.getEventWorkspace_(); + const block = workspace.getBlockById(this.blockId); + const comment = block.getIcon(Blockly.icons.IconType.COMMENT); + comment.setBubbleVisible(forward ? !this.newCollapsed : this.newCollapsed); + } +} + +Blockly.registry.register( + Blockly.registry.Type.EVENT, + "block_comment_collapse", + BlockCommentCollapse +); diff --git a/src/events_block_comment_create.js b/src/events_block_comment_create.js new file mode 100644 index 0000000000..97db3cf7dc --- /dev/null +++ b/src/events_block_comment_create.js @@ -0,0 +1,52 @@ +/** + * @license + * Copyright 2024 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + +import * as Blockly from "blockly/core"; +import { BlockCommentBase } from "./events_block_comment_base.js"; + +class BlockCommentCreate extends BlockCommentBase { + constructor(opt_blockComment) { + super(opt_blockComment); + this.type = "block_comment_create"; + const size = opt_blockComment.getSize(); + const location = opt_blockComment.getRelativeToSurfaceXY(); + this.json = { + x: location.x, + y: location.y, + width: size.width, + height: size.height, + }; + // Disable undo because Blockly already tracks comment creation for + // undo purposes; this event exists solely to keep the Scratch VM apprised + // of the state of things. + this.recordUndo = false; + } + + toJson() { + return { + ...super.toJson(), + json: this.json, + }; + } + + static fromJson(json, workspace, event) { + const newEvent = super.fromJson(json, workspace, event); + newEvent.json = { + x: json["json"]["x"], + y: json["json"]["y"], + width: json["json"]["width"], + height: json["json"]["height"], + }; + + return newEvent; + } +} + +Blockly.registry.register( + Blockly.registry.Type.EVENT, + "block_comment_create", + BlockCommentCreate +); diff --git a/src/events_block_comment_delete.js b/src/events_block_comment_delete.js new file mode 100644 index 0000000000..d9a6e60ff9 --- /dev/null +++ b/src/events_block_comment_delete.js @@ -0,0 +1,27 @@ +/** + * @license + * Copyright 2024 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + +import * as Blockly from "blockly/core"; +import { BlockCommentBase } from "./events_block_comment_base.js"; + +class BlockCommentDelete extends BlockCommentBase { + constructor(opt_blockComment, sourceBlock) { + super(opt_blockComment); + this.type = "block_comment_delete"; + this.blockId = sourceBlock.id; + this.workspaceId = sourceBlock.workspace.id; + // Disable undo because Blockly already tracks comment deletion for + // undo purposes; this event exists solely to keep the Scratch VM apprised + // of the state of things. + this.recordUndo = false; + } +} + +Blockly.registry.register( + Blockly.registry.Type.EVENT, + "block_comment_delete", + BlockCommentDelete +); diff --git a/src/events_block_comment_move.js b/src/events_block_comment_move.js new file mode 100644 index 0000000000..ffc098fd90 --- /dev/null +++ b/src/events_block_comment_move.js @@ -0,0 +1,54 @@ +/** + * @license + * Copyright 2024 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + +import * as Blockly from "blockly/core"; +import { BlockCommentBase } from "./events_block_comment_base.js"; + +class BlockCommentMove extends BlockCommentBase { + constructor(opt_blockComment, oldCoordinate, newCoordinate) { + super(opt_blockComment); + this.type = "block_comment_move"; + this.oldCoordinate_ = oldCoordinate; + this.newCoordinate_ = newCoordinate; + } + + toJson() { + return { + ...super.toJson(), + newCoordinate: this.newCoordinate_, + oldCoordinate: this.oldCoordinate_, + }; + } + + static fromJson(json, workspace, event) { + const newEvent = super.fromJson(json, workspace, event); + newEvent.newCoordinate_ = new Blockly.utils.Coordinate( + json["newCoordinate"]["x"], + json["newCoordinate"]["y"] + ); + newEvent.oldCoordinate_ = new Blockly.utils.Coordinate( + json["oldCoordinate"]["x"], + json["oldCoordinate"]["y"] + ); + + return newEvent; + } + + run(forward) { + const workspace = this.getEventWorkspace_(); + const block = workspace?.getBlockById(this.blockId); + const comment = block?.getIcon(Blockly.icons.IconType.COMMENT); + comment?.setBubbleLocation( + forward ? this.newCoordinate_ : this.oldCoordinate_ + ); + } +} + +Blockly.registry.register( + Blockly.registry.Type.EVENT, + "block_comment_move", + BlockCommentMove +); diff --git a/src/events_block_comment_resize.js b/src/events_block_comment_resize.js new file mode 100644 index 0000000000..6c7b5953a7 --- /dev/null +++ b/src/events_block_comment_resize.js @@ -0,0 +1,52 @@ +/** + * @license + * Copyright 2024 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + +import * as Blockly from "blockly/core"; +import { BlockCommentBase } from "./events_block_comment_base.js"; + +class BlockCommentResize extends BlockCommentBase { + constructor(opt_blockComment, oldSize, newSize) { + super(opt_blockComment); + this.type = "block_comment_resize"; + this.oldSize = oldSize; + this.newSize = newSize; + } + + toJson() { + return { + ...super.toJson(), + newSize: this.newSize, + oldSize: this.oldSize, + }; + } + + static fromJson(json, workspace, event) { + const newEvent = super.fromJson(json, workspace, event); + newEvent.newSize = new Blockly.utils.Size( + json["newSize"]["width"], + json["newSize"]["height"] + ); + newEvent.oldSize = new Blockly.utils.Size( + json["oldSize"]["width"], + json["oldSize"]["height"] + ); + + return newEvent; + } + + run(forward) { + const workspace = this.getEventWorkspace_(); + const block = workspace?.getBlockById(this.blockId); + const comment = block?.getIcon(Blockly.icons.IconType.COMMENT); + comment?.setBubbleSize(forward ? this.newSize : this.oldSize); + } +} + +Blockly.registry.register( + Blockly.registry.Type.EVENT, + "block_comment_resize", + BlockCommentResize +); diff --git a/src/index.js b/src/index.js index 1e2dc0ca8d..3f61eb2d01 100644 --- a/src/index.js +++ b/src/index.js @@ -34,6 +34,13 @@ import {CheckableContinuousFlyout} from './checkable_continuous_flyout.js'; import {buildGlowFilter, glowStack} from './glows.js'; import {ScratchContinuousToolbox} from './scratch_continuous_toolbox.js'; import './scratch_continuous_category.js'; +import './scratch_comment_icon.js'; +import './events_block_comment_change.js'; +import './events_block_comment_collapse.js'; +import './events_block_comment_create.js'; +import './events_block_comment_delete.js'; +import './events_block_comment_move.js'; +import './events_block_comment_resize.js'; import {buildShadowFilter} from './shadows.js'; export * from 'blockly'; diff --git a/src/scratch_comment_bubble.js b/src/scratch_comment_bubble.js new file mode 100644 index 0000000000..8a6b6d5c41 --- /dev/null +++ b/src/scratch_comment_bubble.js @@ -0,0 +1,168 @@ +/** + * @license + * Copyright 2024 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + +import * as Blockly from "blockly/core"; + +/** + * A Scratch-style comment bubble for block comments. + * @implements {IBubble} + * @implements {ISelectable} + */ +export class ScratchCommentBubble extends Blockly.comments.CommentView { + constructor(sourceBlock) { + super(sourceBlock.workspace); + this.sourceBlock = sourceBlock; + this.disposing = false; + this.id = Blockly.utils.idGenerator.genUid(); + this.getSvgRoot().setAttribute( + "style", + `--colour-commentBorder: ${sourceBlock.getColourTertiary()};` + ); + + Blockly.browserEvents.conditionalBind( + this.getSvgRoot(), + "pointerdown", + this, + this.startGesture + ); + // Don't zoom with mousewheel; let it scroll instead. + Blockly.browserEvents.conditionalBind( + this.getSvgRoot(), + "wheel", + this, + (e) => { + e.stopPropagation(); + } + ); + } + + setDeleteStyle(enable) {} + showContextMenu() {} + setDragging(start) {} + select() {} + unselect() {} + + isMovable() { + return true; + } + + moveDuringDrag(newLocation) { + this.moveTo(newLocation); + } + + moveTo(xOrCoordinate, y) { + const destination = + xOrCoordinate instanceof Blockly.utils.Coordinate + ? xOrCoordinate + : new Blockly.utils.Coordinate(xOrCoordinate, y); + super.moveTo(destination); + this.redrawAnchorChain(); + } + + startGesture(e) { + const gesture = this.workspace.getGesture(e); + if (gesture) { + gesture.handleCommentStart(e, this); + Blockly.common.setSelected(this); + } + } + + startDrag(event) { + this.dragStartLocation = this.getRelativeToSurfaceXY(); + this.workspace.setResizesEnabled(false); + this.workspace.getLayerManager()?.moveToDragLayer(this); + Blockly.utils.dom.addClass(this.getSvgRoot(), "blocklyDragging"); + } + + drag(newLocation, event) { + this.moveTo(newLocation); + } + + endDrag() { + this.workspace + .getLayerManager() + ?.moveOffDragLayer(this, Blockly.layers.BUBBLE); + this.workspace.setResizesEnabled(false); + Blockly.utils.dom.removeClass(this.getSvgRoot(), "blocklyDragging"); + Blockly.Events.fire( + new (Blockly.Events.get("block_comment_move"))( + this, + this.dragStartLocation, + this.getRelativeToSurfaceXY() + ) + ); + } + + revertDrag() { + this.moveTo(this.dragStartLocation); + } + + setAnchorLocation(newAnchor) { + const oldAnchor = this.anchor; + const alreadyAnchored = !!this.anchor; + this.anchor = newAnchor; + if (!alreadyAnchored) { + this.dropAnchor(); + } else { + const oldLocation = this.getRelativeToSurfaceXY(); + const delta = Blockly.utils.Coordinate.difference(this.anchor, oldAnchor); + const newLocation = Blockly.utils.Coordinate.sum(oldLocation, delta); + this.moveTo(newLocation); + } + } + + dropAnchor() { + this.moveTo(this.anchor.x + 40, this.anchor.y - 16); + const location = this.getRelativeToSurfaceXY(); + this.anchorChain = Blockly.utils.dom.createSvgElement( + Blockly.utils.Svg.LINE, + { + x1: this.anchor.x - location.x, + y1: this.anchor.y - location.y, + x2: this.getSize().width / 2, + y2: 16, + style: `stroke: ${this.sourceBlock.getColourTertiary()}; stroke-width: 1`, + }, + this.getSvgRoot() + ); + this.getSvgRoot().insertBefore( + this.anchorChain, + this.getSvgRoot().firstChild + ); + } + + redrawAnchorChain() { + if (!this.anchorChain) return; + + const location = this.getRelativeToSurfaceXY(); + this.anchorChain.setAttribute("x1", this.anchor.x - location.x); + this.anchorChain.setAttribute("y1", this.anchor.y - location.y); + } + + getId() { + return this.id; + } + + getSourceBlock() { + return this.sourceBlock; + } + + dispose() { + this.disposing = true; + Blockly.utils.dom.removeNode(this.anchorChain); + if (this.sourceBlock) { + Blockly.Events.fire( + new (Blockly.Events.get("block_comment_delete"))(this, this.sourceBlock) + ); + const block = this.sourceBlock; + this.sourceBlock = null; + if (!block.isDeadOrDying()) { + block.setCommentText(null); + } + } + super.dispose(); + } +} diff --git a/src/scratch_comment_icon.js b/src/scratch_comment_icon.js new file mode 100644 index 0000000000..a67589e2f4 --- /dev/null +++ b/src/scratch_comment_icon.js @@ -0,0 +1,195 @@ +/** + * @license + * Copyright 2024 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + +import * as Blockly from "blockly/core"; +import { ScratchCommentBubble } from "./scratch_comment_bubble.js"; + +/** + * Custom comment icon that draws no icon indicator, used for block comments. + * @implements {IHasBubble} + * @implements {ISerializable} + */ +class ScratchCommentIcon extends Blockly.icons.Icon { + constructor(sourceBlock) { + super(sourceBlock); + this.sourceBlock = sourceBlock; + this.commentBubble = new ScratchCommentBubble(this.sourceBlock); + Blockly.Events.fire( + new (Blockly.Events.get("block_comment_create"))(this.commentBubble) + ); + this.onTextChangedListener = this.onTextChanged.bind(this); + this.onSizeChangedListener = this.onSizeChanged.bind(this); + this.onCollapseListener = this.onCollapsed.bind(this); + this.commentBubble.addTextChangeListener(this.onTextChangedListener); + this.commentBubble.addSizeChangeListener(this.onSizeChangedListener); + this.commentBubble.addOnCollapseListener(this.onCollapseListener); + } + + getType() { + return Blockly.icons.IconType.COMMENT; + } + + initView(pointerDownListener) { + // Scratch comments have no indicator icon on the block. + return; + } + + getSize() { + // Awful hack to cancel out the default padding added to icons. + return new Blockly.utils.Size(-8, 0); + } + + getAnchorPoint() { + const blockRect = this.sourceBlock.getBoundingRectangleWithoutChildren(); + const y = blockRect.top + this.offsetInBlock.y; + const x = this.sourceBlock.workspace.RTL ? blockRect.left : blockRect.right; + return new Blockly.utils.Coordinate(x, y); + } + + onLocationChange(blockOrigin) { + if (!this.sourceBlock || !this.commentBubble) return; + + if (this.sourceBlock.isInsertionMarker()) { + this.commentBubble.dispose(); + return; + } + + super.onLocationChange(blockOrigin); + const oldBubbleLocation = this.commentBubble.getRelativeToSurfaceXY(); + this.commentBubble.setAnchorLocation(this.getAnchorPoint()); + const newBubbleLocation = this.commentBubble.getRelativeToSurfaceXY(); + Blockly.Events.fire( + new (Blockly.Events.get("block_comment_move"))( + this.commentBubble, + oldBubbleLocation, + newBubbleLocation + ) + ); + } + + setText(text) { + this.commentBubble?.setText(text); + } + + getText() { + return this.commentBubble?.getText() ?? ""; + } + + onTextChanged(oldText, newText) { + Blockly.Events.fire( + new (Blockly.Events.get(Blockly.Events.BLOCK_CHANGE))( + this.sourceBlock, + "comment", + null, + oldText, + newText + ) + ); + Blockly.Events.fire( + new (Blockly.Events.get("block_comment_change"))( + this.commentBubble, + oldText, + newText + ) + ); + } + + onCollapsed(collapsed) { + Blockly.Events.fire( + new (Blockly.Events.get("block_comment_collapse"))( + this.commentBubble, + collapsed + ) + ); + } + + onSizeChanged(oldSize, newSize) { + Blockly.Events.fire( + new (Blockly.Events.get("block_comment_resize"))( + this.commentBubble, + oldSize, + newSize + ) + ); + } + + setBubbleSize(size) { + this.commentBubble?.setSize(size); + } + + getBubbleSize() { + return this.commentBubble?.getSize() ?? new Blockly.utils.Size(0, 0); + } + + setBubbleLocation(newLocation) { + const oldLocation = this.getBubbleLocation(); + this.commentBubble?.moveTo(newLocation); + Blockly.Events.fire( + new (Blockly.Events.get("block_comment_move"))( + this.commentBubble, + oldLocation, + newLocation + ) + ); + } + + getBubbleLocation() { + return this.commentBubble?.getRelativeToSurfaceXY(); + } + + saveState() { + if (!this.commentBubble) return null; + + const size = this.getBubbleSize(); + const bubbleLocation = this.commentBubble.getRelativeToSurfaceXY(); + const delta = Blockly.utils.Coordinate.difference( + bubbleLocation, + this.workspaceLocation + ); + return { + text: this.getText(), + height: size.height, + width: size.width, + x: delta.x, + y: delta.y, + collapsed: this.commentBubble.isCollapsed(), + }; + } + + loadState(state) { + this.setText(state["text"]); + this.setBubbleSize(new Blockly.utils.Size(state["width"], state["height"])); + const delta = new Blockly.utils.Coordinate(state["x"], state["y"]); + const newBubbleLocation = Blockly.utils.Coordinate.sum( + this.workspaceLocation, + delta + ); + this.commentBubble.moveTo(newBubbleLocation); + this.commentBubble.setCollapsed(state["collapsed"]); + } + + bubbleIsVisible() { + return true; + } + + async setBubbleVisible(visible) { + this.commentBubble.setCollapsed(!visible); + } + + dispose() { + this.commentBubble?.dispose(); + this.commentBubble = null; + this.sourceBlock = null; + super.dispose(); + } +} + +Blockly.registry.register( + Blockly.registry.Type.ICON, + Blockly.icons.IconType.COMMENT.toString(), + ScratchCommentIcon, + true +); From c12de22f5d2fe81ca746aad4e1944bda410fb617 Mon Sep 17 00:00:00 2001 From: Aaron Dodson Date: Thu, 25 Jul 2024 10:08:05 -0700 Subject: [PATCH 045/130] refactor: modernize FieldVariableGetter (#85) * chore: move field_variable_getter.js into src * refactor: modernize FieldVariableGetter --- core/field_variable_getter.js | 185 ---------------------------------- src/field_variable_getter.js | 104 +++++++++++++++++++ 2 files changed, 104 insertions(+), 185 deletions(-) delete mode 100644 core/field_variable_getter.js create mode 100644 src/field_variable_getter.js diff --git a/core/field_variable_getter.js b/core/field_variable_getter.js deleted file mode 100644 index 93721289f3..0000000000 --- a/core/field_variable_getter.js +++ /dev/null @@ -1,185 +0,0 @@ -/** - * @license - * Visual Blocks Editor - * - * Copyright 2017 Google Inc. - * https://developers.google.com/blockly/ - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @fileoverview Variable getter field. Appears as a label but has a variable - * picker in the right-click menu. - * @author fenichel@google.com (Rachel Fenichel) - */ -'use strict'; - -goog.provide('Blockly.FieldVariableGetter'); - -goog.require('Blockly.Field'); - - -/** - * Class for a variable getter field. - * @param {string} text The initial content of the field. - * @param {string} name Optional CSS class for the field's text. - * @param {string} opt_varType The type of variable this field is associated with. - * @extends {Blockly.FieldLabel} - * @constructor - * - */ -Blockly.FieldVariableGetter = function(text, name, opt_varType) { - this.size_ = new goog.math.Size(Blockly.BlockSvg.FIELD_WIDTH, - Blockly.BlockSvg.FIELD_HEIGHT); - this.text_ = text; - - /** - * Maximum characters of text to display before adding an ellipsis. - * Same for strings and numbers. - * @type {number} - */ - this.maxDisplayLength = Blockly.BlockSvg.MAX_DISPLAY_LENGTH; - - this.name_ = name; - this.variableType_ = opt_varType ? opt_varType : ''; -}; -goog.inherits(Blockly.FieldVariableGetter, Blockly.Field); - -/** - * Construct a FieldVariableGetter from a JSON arg object, - * dereferencing any string table references. - * @param {!Object} options A JSON object with options (variable, - * variableTypes, and defaultType). - * @returns {!Blockly.FieldVariableGetter} The new field instance. - * @package - * @nocollapse - */ -Blockly.FieldVariableGetter.fromJson = function(options) { - var varname = Blockly.utils.replaceMessageReferences(options['text']); - return new Blockly.FieldVariableGetter(varname, options['name'], - options['class'], options['variableType']); -}; - -/** - * Editable fields usually show some sort of UI for the user to change them. - * This field should be serialized, but only edited programmatically. - * @type {boolean} - * @public - */ -Blockly.FieldVariableGetter.prototype.EDITABLE = false; - -/** - * Serializable fields are saved by the XML renderer, non-serializable fields - * are not. This field should be serialized, but only edited programmatically. - * @type {boolean} - * @public - */ -Blockly.FieldVariableGetter.prototype.SERIALIZABLE = true; - -/** - * Install this field on a block. - */ -Blockly.FieldVariableGetter.prototype.init = function() { - if (this.fieldGroup_) { - // Field has already been initialized once. - return; - } - Blockly.FieldVariableGetter.superClass_.init.call(this); - if (this.variable_) { - return; // Initialization already happened. - } - this.workspace_ = this.sourceBlock_.workspace; - var variable = Blockly.Variables.getOrCreateVariablePackage( - this.workspace_, null, this.text_, this.variableType_); - this.setValue(variable.getId()); -}; - -/** - * Get the variable's ID. - * @return {string} Current variable's ID. - */ -Blockly.FieldVariableGetter.prototype.getValue = function() { - return this.variable_ ? this.variable_.getId() : ''; -}; - -/** - * Get the text from this field. - * @return {string} Current text. - */ -Blockly.FieldVariableGetter.prototype.getText = function() { - return this.variable_ ? this.variable_.name : ''; -}; - -/** - * Get the variable model for the variable associated with this field. - * Not guaranteed to be in the variable map on the workspace (e.g. if accessed - * after the variable has been deleted). - * @return {?Blockly.VariableModel} the selected variable, or null if none was - * selected. - * @package - */ -Blockly.FieldVariableGetter.prototype.getVariable = function() { - return this.variable_; -}; - -Blockly.FieldVariableGetter.prototype.setValue = function(id) { - // What do I do when id is null? That happens when undoing a change event - // for the first time the value was set. - var workspace = this.sourceBlock_.workspace; - var variable = Blockly.Variables.getVariable(workspace, id); - - if (!variable) { - throw new Error('Variable id doesn\'t point to a real variable! ID was ' + - id); - } - - if (this.sourceBlock_ && Blockly.Events.isEnabled()) { - var oldValue = this.variable_ ? this.variable_.getId() : null; - Blockly.Events.fire(new Blockly.Events.BlockChange( - this.sourceBlock_, 'field', this.name, oldValue, variable.getId())); - } - this.variable_ = variable; - this.value_ = id; - this.setText(variable.name); -}; - -/** - * This field is editable, but only through the right-click menu. - * @private - */ -Blockly.FieldVariableGetter.prototype.showEditor_ = function() { - // nop. -}; - -/** - * Add or remove the UI indicating if this field is editable or not. - * This field is editable, but only through the right-click menu. - * Suppress default editable behaviour. - */ -Blockly.FieldVariableGetter.prototype.updateEditable = function() { - // nop. -}; - -/** - * Whether this field references any Blockly variables. If true it may need to - * be handled differently during serialization and deserialization. Subclasses - * may override this. - * @return {boolean} True if this field has any variable references. - * @package - */ -Blockly.FieldVariableGetter.prototype.referencesVariables = function() { - return true; -}; - -Blockly.Field.register('field_variable_getter', Blockly.FieldVariableGetter); diff --git a/src/field_variable_getter.js b/src/field_variable_getter.js new file mode 100644 index 0000000000..a7a56e3d0d --- /dev/null +++ b/src/field_variable_getter.js @@ -0,0 +1,104 @@ +/** + * @license + * Visual Blocks Editor + * + * Copyright 2017 Google Inc. + * https://developers.google.com/blockly/ + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @fileoverview Variable getter field. Appears as a label but has a variable + * picker in the right-click menu. + * @author fenichel@google.com (Rachel Fenichel) + */ +import * as Blockly from "blockly/core"; + +/** + * Class for a variable getter field. + * @param {string} allowedVariableType The type of variables this field can display. + */ +export class FieldVariableGetter extends Blockly.FieldLabel { + constructor(allowedVariableType = "") { + super(Blockly.Field.SKIP_SETUP); + this.SERIALIZABLE = true; + this.allowedVariableType = allowedVariableType; + this.variable = null; + } + + /** + * Returns the ID of this field's variable. + * @return {string} The ID of this field's variable. + */ + getValue() { + return this.variable?.getId() ?? ""; + } + + /** + * Returns the name of this field's variable. + * @return {string} The name of this field's variable. + */ + getText() { + return this.variable?.getName() ?? ""; + } + + /** + * Get the variable model for the variable associated with this field. + * Not guaranteed to be in the variable map on the workspace (e.g. if accessed + * after the variable has been deleted). + * @return {?Blockly.VariableModel} the selected variable, or null if none was + * selected. + * @package + */ + getVariable() { + return this.variable; + } + + /** + * Updates this field's variable to one with the given ID. + * @param {string} newVariableId ID of a variable this field should represent. + */ + doValueUpdate_(newVariableId) { + super.doValueUpdate_(newVariableId); + const workspace = this.getSourceBlock().workspace; + this.variable = Blockly.Variables.getVariable(workspace, newVariableId); + } + + /** Informs Blockly that this field depends on a variable. */ + referencesVariables() { + return true; + } + + /** Rerenders this field when the underlying variable's name changes. */ + refreshVariableName() { + this.forceRerender(); + } + + static fromJson(options) { + return new FieldVariableGetter(options["allowedVariableType"]); + } + + fromXml(element) { + this.setValue(element.getAttribute("id")); + } + + toXml(element) { + element.setAttribute("id", this.variable.getId()); + element.setAttribute("variabletype", this.variable.getType()); + element.textContent = this.variable.getName(); + return element; + } +} + +Blockly.fieldRegistry.register("field_variable_getter", FieldVariableGetter); From 2598ede046de74164922bd919695eae65bd0c9b2 Mon Sep 17 00:00:00 2001 From: Aaron Dodson Date: Fri, 26 Jul 2024 08:30:13 -0700 Subject: [PATCH 046/130] feat: add custom Scratch variable model and creation event classes (#86) * feat: add a custom Scratch variable model * feat: add a custom Scratch variable creation event * chore: format index.js * feat: import and register the Scratch variable model and creation event classes * feat: add serialization/running support to the Scratch variable creation event * chore: add license headers * refactor: replace repeated variableMap accesses with a variable --- src/events_scratch_variable_create.js | 67 +++++++++++++++++ src/index.js | 103 +++++++++++++------------- src/scratch_variable_model.js | 24 ++++++ 3 files changed, 144 insertions(+), 50 deletions(-) create mode 100644 src/events_scratch_variable_create.js create mode 100644 src/scratch_variable_model.js diff --git a/src/events_scratch_variable_create.js b/src/events_scratch_variable_create.js new file mode 100644 index 0000000000..d5ab39d6e7 --- /dev/null +++ b/src/events_scratch_variable_create.js @@ -0,0 +1,67 @@ +/** + * @license + * Copyright 2024 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + +import * as Blockly from "blockly/core"; + +class ScratchVariableCreate extends Blockly.Events.VarCreate { + constructor(variable) { + super(variable); + if (!variable) return; + + this.isLocal = variable.isLocal; + this.isCloud = variable.isCloud; + } + + toJson() { + const json = super.toJson(); + json["isLocal"] = this.isLocal; + json["isCloud"] = this.isCloud; + return json; + } + + static fromJson(json, workspace, event) { + const newEvent = super.fromJson(json, workspace, event); + newEvent.isLocal = json["isLocal"]; + newEvent.isCloud = json["isCloud"]; + return newEvent; + } + + run(forward) { + const workspace = this.getEventWorkspace_(); + const variableMap = workspace.getVariableMap(); + if (forward) { + const VariableModel = Blockly.registry.getObject( + Blockly.registry.Type.VARIABLE_MODEL, + Blockly.registry.DEFAULT, + true + ); + const variable = new VariableModel( + workspace, + this.varName, + this.varType, + this.varId, + this.isLocal, + this.isCloud + ); + variableMap.addVariable(variable); + Blockly.Events.fire( + new (Blockly.Events.get(Blockly.Events.VAR_CREATE))(variable) + ); + } else { + const variable = variableMap.getVariableById(this.varId); + if (variable) { + variableMap.deleteVariable(variable); + } + } + } +} + +Blockly.registry.register( + Blockly.registry.Type.EVENT, + Blockly.Events.VAR_CREATE, + ScratchVariableCreate, + true +); diff --git a/src/index.js b/src/index.js index 3f61eb2d01..3011f69149 100644 --- a/src/index.js +++ b/src/index.js @@ -4,58 +4,60 @@ * SPDX-License-Identifier: Apache-2.0 */ -import * as Blockly from 'blockly/core'; -import {registerFieldAngle} from '@blockly/field-angle'; +import * as Blockly from "blockly/core"; +import { registerFieldAngle } from "@blockly/field-angle"; registerFieldAngle(); -import '../blocks_common/colour.js'; -import '../blocks_common/math.js'; -import '../blocks_common/matrix.js'; -import '../blocks_common/note.js'; -import '../blocks_common/text.js'; -import '../blocks_vertical/vertical_extensions.js'; -import '../blocks_vertical/control.js'; -import '../blocks_vertical/data.js'; -import '../blocks_vertical/event.js'; -import '../blocks_vertical/looks.js'; -import '../blocks_vertical/motion.js'; -import '../blocks_vertical/operators.js'; -import '../blocks_vertical/procedures.js'; -import '../blocks_vertical/sensing.js'; -import '../blocks_vertical/sound.js'; -import * as scratchBlocksUtils from '../core/scratch_blocks_utils.js'; -import '../core/css.js'; -import '../core/field_vertical_separator.js'; +import "../blocks_common/colour.js"; +import "../blocks_common/math.js"; +import "../blocks_common/matrix.js"; +import "../blocks_common/note.js"; +import "../blocks_common/text.js"; +import "../blocks_vertical/vertical_extensions.js"; +import "../blocks_vertical/control.js"; +import "../blocks_vertical/data.js"; +import "../blocks_vertical/event.js"; +import "../blocks_vertical/looks.js"; +import "../blocks_vertical/motion.js"; +import "../blocks_vertical/operators.js"; +import "../blocks_vertical/procedures.js"; +import "../blocks_vertical/sensing.js"; +import "../blocks_vertical/sound.js"; +import * as scratchBlocksUtils from "../core/scratch_blocks_utils.js"; +import "../core/css.js"; +import "../core/field_vertical_separator.js"; import { ContinuousToolbox, ContinuousFlyout, ContinuousMetrics, -} from '@blockly/continuous-toolbox'; -import {CheckableContinuousFlyout} from './checkable_continuous_flyout.js'; -import {buildGlowFilter, glowStack} from './glows.js'; -import {ScratchContinuousToolbox} from './scratch_continuous_toolbox.js'; -import './scratch_continuous_category.js'; -import './scratch_comment_icon.js'; -import './events_block_comment_change.js'; -import './events_block_comment_collapse.js'; -import './events_block_comment_create.js'; -import './events_block_comment_delete.js'; -import './events_block_comment_move.js'; -import './events_block_comment_resize.js'; -import {buildShadowFilter} from './shadows.js'; +} from "@blockly/continuous-toolbox"; +import { CheckableContinuousFlyout } from "./checkable_continuous_flyout.js"; +import { buildGlowFilter, glowStack } from "./glows.js"; +import { ScratchContinuousToolbox } from "./scratch_continuous_toolbox.js"; +import "./scratch_continuous_category.js"; +import "./scratch_comment_icon.js"; +import "./scratch_variable_model.js"; +import "./events_block_comment_change.js"; +import "./events_block_comment_collapse.js"; +import "./events_block_comment_create.js"; +import "./events_block_comment_delete.js"; +import "./events_block_comment_move.js"; +import "./events_block_comment_resize.js"; +import "./events_scratch_variable_create.js"; +import { buildShadowFilter } from "./shadows.js"; -export * from 'blockly'; -export * from './block_reporting.js'; -export * from './categories.js'; -export * from './procedures.js'; -export * from '../core/colours.js'; -export * from '../core/field_colour_slider.js'; -export * from '../core/field_matrix.js'; -export * from '../core/field_note.js'; -export * from '../core/field_number.js'; -export * from '../msg/scratch_msgs.js'; -export {glowStack}; -export {scratchBlocksUtils}; -export {CheckableContinuousFlyout}; +export * from "blockly"; +export * from "./block_reporting.js"; +export * from "./categories.js"; +export * from "./procedures.js"; +export * from "../core/colours.js"; +export * from "../core/field_colour_slider.js"; +export * from "../core/field_matrix.js"; +export * from "../core/field_note.js"; +export * from "../core/field_number.js"; +export * from "../msg/scratch_msgs.js"; +export { glowStack }; +export { scratchBlocksUtils }; +export { CheckableContinuousFlyout }; export function inject(container, options) { Object.assign(options, { @@ -66,11 +68,12 @@ export function inject(container, options) { }, }); const workspace = Blockly.inject(container, options); - workspace.getRenderer().getConstants().selectedGlowFilterId = ''; + workspace.getRenderer().getConstants().selectedGlowFilterId = ""; const flyout = workspace.getFlyout(); if (flyout) { - flyout.getWorkspace().getRenderer().getConstants().selectedGlowFilterId = ''; + flyout.getWorkspace().getRenderer().getConstants().selectedGlowFilterId = + ""; } buildGlowFilter(workspace); @@ -88,6 +91,6 @@ export function inject(container, options) { Blockly.Scrollbar.scrollbarThickness = Blockly.Touch.TOUCH_ENABLED ? 14 : 11; Blockly.FlyoutButton.TEXT_MARGIN_X = 40; Blockly.FlyoutButton.TEXT_MARGIN_Y = 10; -Blockly.ContextMenuRegistry.registry.unregister('blockDisable'); -Blockly.ContextMenuRegistry.registry.unregister('blockInline'); +Blockly.ContextMenuRegistry.registry.unregister("blockDisable"); +Blockly.ContextMenuRegistry.registry.unregister("blockInline"); Blockly.ContextMenuItems.registerCommentOptions(); diff --git a/src/scratch_variable_model.js b/src/scratch_variable_model.js new file mode 100644 index 0000000000..92284e42b8 --- /dev/null +++ b/src/scratch_variable_model.js @@ -0,0 +1,24 @@ +/** + * @license + * Copyright 2024 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + +import * as Blockly from "blockly/core"; + +class ScratchVariableModel extends Blockly.VariableModel { + constructor(workspace, name, type, id, isLocal, isCloud) { + super(workspace, name, type, id); + // isLocal and isCloud may not be passed when creating broadcast message + // variables, which conveniently are neither local nor cloud. + this.isLocal = !!isLocal; + this.isCloud = !!isCloud; + } +} + +Blockly.registry.register( + Blockly.registry.Type.VARIABLE_MODEL, + Blockly.registry.DEFAULT, + ScratchVariableModel, + true +); From 5c1acfe3dc1bb0bf406ba20ffd1e25b22356fbd7 Mon Sep 17 00:00:00 2001 From: Aaron Dodson Date: Mon, 29 Jul 2024 15:52:26 -0700 Subject: [PATCH 047/130] feat: clean up and export Scratch's variables.js (#88) * chore: move variables.js into src * chore: format variables.js * refactor: clean up variables.js * refactor: export the ScratchVariables namespace --- core/variables.js | 674 ---------------------------------------------- src/index.js | 2 + src/variables.js | 347 ++++++++++++++++++++++++ 3 files changed, 349 insertions(+), 674 deletions(-) delete mode 100644 core/variables.js create mode 100644 src/variables.js diff --git a/core/variables.js b/core/variables.js deleted file mode 100644 index 9c1155cded..0000000000 --- a/core/variables.js +++ /dev/null @@ -1,674 +0,0 @@ -/** - * @license - * Visual Blocks Editor - * - * Copyright 2012 Google Inc. - * https://developers.google.com/blockly/ - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @fileoverview Utility functions for handling variables. - * @author fraser@google.com (Neil Fraser) - */ -'use strict'; - -/** - * @name Blockly.Variables - * @namespace - **/ -goog.provide('Blockly.Variables'); - -goog.require('Blockly.Blocks'); -goog.require('Blockly.constants'); -goog.require('Blockly.VariableModel'); -goog.require('Blockly.Workspace'); -goog.require('goog.string'); - - -/** - * Constant to separate variable names from procedures and generated functions - * when running generators. - * @deprecated Use Blockly.VARIABLE_CATEGORY_NAME - */ -Blockly.Variables.NAME_TYPE = Blockly.VARIABLE_CATEGORY_NAME; - -/** - * Constant prefix to differentiate cloud variable names from other types - * of variables. - * This is the \u2601 cloud unicode character followed by a space. - * @type {string} - * @package - */ -Blockly.Variables.CLOUD_PREFIX = '☁ '; - -/** - * Find all user-created variables that are in use in the workspace. - * For use by generators. - * @param {!Blockly.Block|!Blockly.Workspace} root Root block or workspace. - * @return {!Array.} Array of variable names. - */ -Blockly.Variables.allUsedVariables = function(root) { - var blocks; - if (root instanceof Blockly.Block) { - // Root is Block. - blocks = root.getDescendants(false); - } else if (root instanceof Blockly.Workspace || - root instanceof Blockly.WorkspaceSvg) { - // Root is Workspace. - blocks = root.getAllBlocks(); - } else { - throw 'Not Block or Workspace: ' + root; - } - - var ignorableName = Blockly.Variables.noVariableText(); - - var variableHash = Object.create(null); - // Iterate through every block and add each variable to the hash. - for (var x = 0; x < blocks.length; x++) { - var blockVariables = blocks[x].getVarModels(); - if (blockVariables) { - for (var y = 0; y < blockVariables.length; y++) { - var variable = blockVariables[y]; - // Variable ID may be null if the block is only half-built. - if (variable.getId() && variable.name.toLowerCase() != ignorableName) { - variableHash[variable.name.toLowerCase()] = variable.name; - } - } - } - } - // Flatten the hash into a list. - var variableList = []; - for (var name in variableHash) { - variableList.push(variableHash[name]); - } - return variableList; -}; - -/** - * Find all variables that the user has created through the workspace or - * toolbox. For use by generators. - * @param {!Blockly.Workspace} root The workspace to inspect. - * @return {!Array.} Array of variable models. - */ -Blockly.Variables.allVariables = function(root) { - if (root instanceof Blockly.Block) { - // Root is Block. - console.warn('Deprecated call to Blockly.Variables.allVariables ' + - 'with a block instead of a workspace. You may want ' + - 'Blockly.Variables.allUsedVariables'); - return {}; - } - return root.getAllVariables(); -}; - -/** - * Find all developer variables used by blocks in the workspace. - * Developer variables are never shown to the user, but are declared as global - * variables in the generated code. - * To declare developer variables, define the getDeveloperVariables function on - * your block and return a list of variable names. - * For use by generators. - * @param {!Blockly.Workspace} workspace The workspace to search. - * @return {!Array.} A list of non-duplicated variable names. - * @package - */ -Blockly.Variables.allDeveloperVariables = function(workspace) { - var blocks = workspace.getAllBlocks(); - var hash = {}; - for (var i = 0; i < blocks.length; i++) { - var block = blocks[i]; - if (block.getDeveloperVars) { - var devVars = block.getDeveloperVars(); - for (var j = 0; j < devVars.length; j++) { - hash[devVars[j]] = devVars[j]; - } - } - } - - // Flatten the hash into a list. - var list = []; - for (var name in hash) { - list.push(hash[name]); - } - return list; -}; - -/** -* Return the text that should be used in a field_variable or -* field_variable_getter when no variable exists. -* TODO: #572 -* @return {string} The text to display. - */ -Blockly.Variables.noVariableText = function() { - return "No variable selected"; -}; - -/** -* Return a new variable name that is not yet being used. This will try to -* generate single letter variable names in the range 'i' to 'z' to start with. -* If no unique name is located it will try 'i' to 'z', 'a' to 'h', -* then 'i2' to 'z2' etc. Skip 'l'. - * @param {!Blockly.Workspace} workspace The workspace to be unique in. -* @return {string} New variable name. -*/ -Blockly.Variables.generateUniqueName = function(workspace) { - var variableList = workspace.getAllVariables(); - var newName = ''; - if (variableList.length) { - var nameSuffix = 1; - var letters = 'ijkmnopqrstuvwxyzabcdefgh'; // No 'l'. - var letterIndex = 0; - var potName = letters.charAt(letterIndex); - while (!newName) { - var inUse = false; - for (var i = 0; i < variableList.length; i++) { - if (variableList[i].name.toLowerCase() == potName) { - // This potential name is already used. - inUse = true; - break; - } - } - if (inUse) { - // Try the next potential name. - letterIndex++; - if (letterIndex == letters.length) { - // Reached the end of the character sequence so back to 'i'. - // a new suffix. - letterIndex = 0; - nameSuffix++; - } - potName = letters.charAt(letterIndex); - if (nameSuffix > 1) { - potName += nameSuffix; - } - } else { - // We can use the current potential name. - newName = potName; - } - } - } else { - newName = 'i'; - } - return newName; -}; - -/** - * Remove any possiblity of conflict/duplication between a real and potential variable. - * When creating a new variable, checks whether the desired name and type already exists - * as a real or potential variable. - * If 'checkReal' is true, checks whether a real variable with the given - * name and type already exists. - * Checks whether a potential variable (using the given 'potentialVarWs') exists. - * If a potential var exists and a real var also exists, discards the potential var - * and returns the real var. - * If a potential var exists and a real var does not exist (or 'checkReal' - * was false), creates the potential var as a real var, - * discards the potential var, and returns the newly created real var. - * If a potential var does not exist, returns null. - * - * @param {string} varName The name of the variable to check for. - * @param {string} varType The type of the variable to check for. - * @param {!Blockly.Workspace} potentialVarWs The workspace containing the - * potential variable map we want to check against. - * @param {boolean} checkReal Whether or not to check if a variable of the given - * name and type exists as a real variable. - * @return {?Blockly.VariableModel} The matching variable, if one already existed - * in the real workspace; the newly transformed variable, if one already - * existed as a potential variable. Null, if no matching variable, real or - * potential, was found. - */ -Blockly.Variables.realizePotentialVar = function(varName, varType, potentialVarWs, - checkReal) { - var potentialVarMap = potentialVarWs.getPotentialVariableMap(); - var realWs = potentialVarWs.targetWorkspace; - if (!potentialVarMap) { - console.warn('Called Blockly.Variables.realizePotentialVar with incorrect ' + - 'workspace. The provided workspace does not have a potential variable map.'); - return; - } - // First check if a variable with the same name and type already exists as a - // real variable. - var realVar; - if (checkReal) { - realVar = Blockly.Variables.getVariable(realWs, null, varName, varType); - } - - // Check if variable with same name and type exists as a potential var - var potentialVar = potentialVarMap.getVariable(varName, varType); - if (!potentialVar) { - return null; - } - - // The potential var exists, so save its id and delete it from the potential - // variable map. - var id = potentialVar.getId(); - potentialVarMap.deleteVariable(potentialVar); - - // Depending on whether a real var already exists or not, either return the - // existing real var or turn the potential var into a new one using its id. - if (realVar) { - return realVar; - } - return realWs.createVariable(varName, varType, id); -}; - -/** - * Create a new variable on the given workspace. - * @param {!Blockly.Workspace} workspace The workspace on which to create the - * variable. - * @param {function(?string=)=} opt_callback An optional callback function to act - * on the id of the variable that is created from the user's input, or null - * if the change is to be aborted (cancel button or an invalid name was provided). - * @param {string} opt_type Optional type of the variable to be created, - * like 'string' or 'list'. - */ -Blockly.Variables.createVariable = function(workspace, opt_callback, opt_type) { - // Decide on a modal message based on the opt_type. If opt_type was not - // provided, default to the original message for scalar variables. - var newMsg, modalTitle; - if (opt_type == Blockly.BROADCAST_MESSAGE_VARIABLE_TYPE) { - newMsg = Blockly.Msg.NEW_BROADCAST_MESSAGE_TITLE; - modalTitle = Blockly.Msg.BROADCAST_MODAL_TITLE; - } else if (opt_type == Blockly.LIST_VARIABLE_TYPE) { - newMsg = Blockly.Msg.NEW_LIST_TITLE; - modalTitle = Blockly.Msg.LIST_MODAL_TITLE; - } else { - // Note: this case covers 1) scalar variables, 2) any new type of - // variable not explicitly checked for above, and 3) a null or undefined - // opt_type -- turns a falsey opt_type into '' - // TODO (#1251) Warn developers that they didn't provide an opt_type/provided - // a falsey opt_type - opt_type = opt_type ? opt_type : ''; - newMsg = Blockly.Msg.NEW_VARIABLE_TITLE; - modalTitle = Blockly.Msg.VARIABLE_MODAL_TITLE; - } - var validate = Blockly.Variables.nameValidator_.bind(null, opt_type); - - // Prompt the user to enter a name for the variable - Blockly.prompt(newMsg, '', - function(text, additionalVars, variableOptions) { - variableOptions = variableOptions || {}; - var scope = variableOptions.scope; - var isLocal = (scope === 'local') || false; - var isCloud = variableOptions.isCloud || false; - // Default to [] if additionalVars is not provided - additionalVars = additionalVars || []; - // Only use additionalVars for global variable creation. - var additionalVarNames = isLocal ? [] : additionalVars; - - var validatedText = validate(text, workspace, additionalVarNames, isCloud, opt_callback); - if (validatedText) { - // The name is valid according to the type, create the variable - var potentialVarMap = workspace.getPotentialVariableMap(); - var variable; - // This check ensures that if a new variable is being created from a - // workspace that already has a variable of the same name and type as - // a potential variable, that potential variable gets turned into a - // real variable and thus there aren't duplicate options in the field_variable - // dropdown. - if (potentialVarMap && opt_type) { - variable = Blockly.Variables.realizePotentialVar(validatedText, - opt_type, workspace, false); - } - if (!variable) { - variable = workspace.createVariable(validatedText, opt_type, null, isLocal, isCloud); - } - - var flyout = workspace.isFlyout ? workspace : workspace.getFlyout(); - var variableBlockId = variable.getId(); - if (flyout.setCheckboxState) { - flyout.setCheckboxState(variableBlockId, true); - } - - if (opt_callback) { - opt_callback(variableBlockId); - } - } else { - // User canceled prompt without a value. - if (opt_callback) { - opt_callback(null); - } - } - }, modalTitle, opt_type); -}; - -/** - * This function provides a common interface for variable name validation agnostic - * of type. This is so that functions like Blockly.Variables.createVariable and - * Blockly.Variables.renameVariable can call a single function (with a single - * type signature) to validate the user-provided name for a variable. - * @param {string} type The type of the variable for which the provided name - * should be validated. - * @param {string} text The user-provided text that should be validated as a - * variable name. - * @param {!Blockly.Workspace} workspace The workspace on which to validate the - * variable name. This is the workspace used to check whether the variable - * already exists. - * @param {Array} additionalVars A list of additional var names to check - * for conflicts against. - * @param {boolean} isCloud Whether the variable is a cloud variable. - * @param {function(?string=)=} opt_callback An optional function to be called on - * a pre-existing variable of the user-provided name. This function is currently - * only used for broadcast messages. - * @return {string} The validated name according to the parameters given, if - * the name is determined to be valid, or null if the name - * is determined to be invalid/in-use, and the calling function should not - * proceed with creating or renaming the variable. - * @private - */ -Blockly.Variables.nameValidator_ = function(type, text, workspace, additionalVars, - isCloud, opt_callback) { - // The validators for the different variable types require slightly different arguments. - // For broadcast messages, if a broadcast message of the provided name already exists, - // the validator needs to call a function that updates the selected - // field option of the dropdown menu of the block that was used to create the new message. - // For scalar variables and lists, the validator has the same validation behavior, but needs - // to know which type of variable to check for and needs a type-specific error message - // that is displayed when a variable of the given name and type already exists. - - if (type == Blockly.BROADCAST_MESSAGE_VARIABLE_TYPE) { - return Blockly.Variables.validateBroadcastMessageName_(text, workspace, opt_callback); - } else if (type == Blockly.LIST_VARIABLE_TYPE) { - return Blockly.Variables.validateScalarVarOrListName_(text, workspace, additionalVars, false, type, - Blockly.Msg.LIST_ALREADY_EXISTS); - } else { - return Blockly.Variables.validateScalarVarOrListName_(text, workspace, additionalVars, isCloud, type, - Blockly.Msg.VARIABLE_ALREADY_EXISTS); - } -}; - -/** - * Validate the given name as a broadcast message type. - * @param {string} name The name to validate - * @param {!Blockly.Workspace} workspace The workspace the name should be validated - * against. - * @param {function(?string=)=} opt_callback An optional function to call if a broadcast - * message already exists with the given name. This function will be called on the id - * of the existing variable. - * @return {string} The validated name, or null if invalid. - * @private - */ -Blockly.Variables.validateBroadcastMessageName_ = function(name, workspace, opt_callback) { - if (!name) { // no name was provided or the user cancelled the prompt - return null; - } - var variable = workspace.getVariable(name, Blockly.BROADCAST_MESSAGE_VARIABLE_TYPE); - if (variable) { - // If the user provided a name for a broadcast message that already exists, - // use the provided callback function to update the selected option in - // the field of the block that was used to create - // this message. - if (opt_callback) { - opt_callback(variable.getId()); - } - // Return null to signal to the calling function that we do not want to create - // a new variable since one already exists. - return null; - } else { - // The name provided is actually a new name, so the calling - // function should go ahead and create it as a new variable. - return name; - } -}; - -/** - * Validate the given name as a scalar variable or list type. - * This function is also responsible for any user facing error-handling. - * @param {string} name The name to validate - * @param {!Blockly.Workspace} workspace The workspace the name should be validated - * against. - * @param {Array} additionalVars A list of additional variable names to check - * for conflicts against. - * @param {boolean} isCloud Whether the variable is a cloud variable. - * @param {string} type The type to validate the variable as. This should be one of - * Blockly.SCALAR_VARIABLE_TYPE or Blockly.LIST_VARIABLE_TYPE. - * @param {string} errorMsg The type-specific error message the user should see - * if a variable of the validated, given name and type already exists. - * @return {string} The validated name, or null if invalid. - * @private - */ -Blockly.Variables.validateScalarVarOrListName_ = function(name, workspace, additionalVars, - isCloud, type, errorMsg) { - // For scalar variables, we don't want leading or trailing white space - name = Blockly.Variables.trimName_(name); - if (!name) { - return null; - } - if (isCloud) { - name = Blockly.Variables.CLOUD_PREFIX + name; - } - if (workspace.getVariable(name, type) || additionalVars.indexOf(name) >= 0) { - // error - Blockly.alert(errorMsg.replace('%1', name)); - return null; - } else { // trimmed name is valid - return name; - } -}; - -/** - * Rename a variable with the given workspace, variableType, and oldName. - * @param {!Blockly.Workspace} workspace The workspace on which to rename the - * variable. - * @param {Blockly.VariableModel} variable Variable to rename. - * @param {function(?string=)=} opt_callback A callback. It will - * be passed an acceptable new variable name, or null if change is to be - * aborted (cancel button), or undefined if an existing variable was chosen. - */ -Blockly.Variables.renameVariable = function(workspace, variable, - opt_callback) { - // Validation and modal message/title depends on the variable type - var promptMsg, modalTitle; - var varType = variable.type; - if (varType == Blockly.BROADCAST_MESSAGE_VARIABLE_TYPE) { - console.warn('Unexpected attempt to rename a broadcast message with ' + - 'id: ' + variable.getId() + ' and name: ' + variable.name); - return; - } - if (varType == Blockly.LIST_VARIABLE_TYPE) { - promptMsg = Blockly.Msg.RENAME_LIST_TITLE; - modalTitle = Blockly.Msg.RENAME_LIST_MODAL_TITLE; - } else { - // Default for all other types of variables - promptMsg = Blockly.Msg.RENAME_VARIABLE_TITLE; - modalTitle = Blockly.Msg.RENAME_VARIABLE_MODAL_TITLE; - } - var validate = Blockly.Variables.nameValidator_.bind(null, varType); - - var promptText = promptMsg.replace('%1', variable.name); - var promptDefaultText = variable.name; - if (variable.isCloud && variable.name.indexOf(Blockly.Variables.CLOUD_PREFIX) == 0) { - promptDefaultText = promptDefaultText.substring(Blockly.Variables.CLOUD_PREFIX.length); - } - - Blockly.prompt(promptText, promptDefaultText, - function(newName, additionalVars) { - if (variable.isCloud && - newName.length > 0 && newName.indexOf(Blockly.Variables.CLOUD_PREFIX) == 0) { - newName = newName.substring(Blockly.Variables.CLOUD_PREFIX.length); - // The name validator will add the prefix back - } - additionalVars = additionalVars || []; - var additionalVarNames = variable.isLocal ? [] : additionalVars; - var validatedText = validate(newName, workspace, additionalVarNames, variable.isCloud); - if (validatedText) { - workspace.renameVariableById(variable.getId(), validatedText); - if (opt_callback) { - opt_callback(newName); - } - } else { - // User canceled prompt without a value. - if (opt_callback) { - opt_callback(null); - } - } - }, modalTitle, varType); -}; - -/** - * Strip leading and trailing whitespace from the given name, for use with - * user provided name for scalar variables and lists. - * @param {string} name The user-provided name of the variable. - * @return {string} The trimmed name, or whatever falsey value was originally provided. - */ -Blockly.Variables.trimName_ = function(name) { - if (name) { - return goog.string.trim(name); - } else { - // Return whatever was provided - return name; - } -}; - -/** - * Generate XML string for variable field. - * @param {!Blockly.VariableModel} variableModel The variable model to generate - * an XML string from. - * @param {?string} opt_name The optional name of the field, such as "VARIABLE" - * or "LIST". Defaults to "VARIABLE". - * @return {string} The generated XML. - * @private - */ -Blockly.Variables.generateVariableFieldXml_ = function(variableModel, opt_name) { - // The variable name may be user input, so it may contain characters that need - // to be escaped to create valid XML. - var typeString = variableModel.type; - if (typeString == '') { - typeString = '\'\''; - } - var fieldName = opt_name || 'VARIABLE'; - var text = '' + goog.string.htmlEscape(variableModel.name) + ''; - return text; -}; - -/** - * Helper function to look up or create a variable on the given workspace. - * If no variable exists, creates and returns it. - * @param {!Blockly.Workspace} workspace The workspace to search for the - * variable. It may be a flyout workspace or main workspace. - * @param {string} id The ID to use to look up or create the variable, or null. - * @param {string=} opt_name The string to use to look up or create the - * variable. - * @param {string=} opt_type The type to use to look up or create the variable. - * @return {!Blockly.VariableModel} The variable corresponding to the given ID - * or name + type combination. - * @package - */ -Blockly.Variables.getOrCreateVariablePackage = function(workspace, id, opt_name, - opt_type) { - var variable = Blockly.Variables.getVariable(workspace, id, opt_name, - opt_type); - if (!variable) { - variable = Blockly.Variables.createVariable_(workspace, id, opt_name, - opt_type); - } - return variable; -}; - -/** - * Look up a variable on the given workspace. - * Always looks in the main workspace before looking in the flyout workspace. - * Always prefers lookup by ID to lookup by name + type. - * @param {!Blockly.Workspace} workspace The workspace to search for the - * variable. It may be a flyout workspace or main workspace. - * @param {string} id The ID to use to look up the variable, or null. - * @param {string=} opt_name The string to use to look up the variable. Only - * used if lookup by ID fails. - * @param {string=} opt_type The type to use to look up the variable. Only used - * if lookup by ID fails. - * @return {?Blockly.VariableModel} The variable corresponding to the given ID - * or name + type combination, or null if not found. - * @package - */ -Blockly.Variables.getVariable = function(workspace, id, opt_name, opt_type) { - var potentialVariableMap = workspace.getPotentialVariableMap(); - // Try to just get the variable, by ID if possible. - if (id) { - // Look in the real variable map before checking the potential variable map. - var variable = workspace.getVariableById(id); - if (!variable && potentialVariableMap) { - variable = potentialVariableMap.getVariableById(id); - } - } else if (opt_name) { - if (opt_type == undefined) { - throw new Error('Tried to look up a variable by name without a type'); - } - // Otherwise look up by name and type. - var variable = workspace.getVariable(opt_name, opt_type); - if (!variable && potentialVariableMap) { - variable = potentialVariableMap.getVariable(opt_name, opt_type); - } - } - return variable; -}; - -/** - * Helper function to create a variable on the given workspace. - * @param {!Blockly.Workspace} workspace The workspace in which to create the - * variable. It may be a flyout workspace or main workspace. - * @param {string} id The ID to use to create the variable, or null. - * @param {string=} opt_name The string to use to create the variable. - * @param {string=} opt_type The type to use to create the variable. - * @return {!Blockly.VariableModel} The variable corresponding to the given ID - * or name + type combination. - * @private - */ -Blockly.Variables.createVariable_ = function(workspace, id, opt_name, - opt_type) { - var potentialVariableMap = workspace.getPotentialVariableMap(); - // Variables without names get uniquely named for this workspace. - if (!opt_name) { - var ws = workspace.isFlyout ? workspace.targetWorkspace : workspace; - opt_name = Blockly.Variables.generateUniqueName(ws); - } - - // Create a potential variable if in the flyout. - if (potentialVariableMap) { - var variable = potentialVariableMap.createVariable(opt_name, opt_type, id); - } else { // In the main workspace, create a real variable. - var variable = workspace.createVariable(opt_name, opt_type, id); - } - return variable; -}; - -/** - * Helper function to get the list of variables that have been added to the - * workspace after adding a new block, using the given list of variables that - * were in the workspace before the new block was added. - * @param {!Blockly.Workspace} workspace The workspace to inspect. - * @param {!Array.} originalVariables The array of - * variables that existed in the workspace before adding the new block. - * @return {!Array.} The new array of variables that were - * freshly added to the workspace after creating the new block, or [] if no - * new variables were added to the workspace. - * @package - */ -Blockly.Variables.getAddedVariables = function(workspace, originalVariables) { - var allCurrentVariables = workspace.getAllVariables(); - var addedVariables = []; - if (originalVariables.length != allCurrentVariables.length) { - for (var i = 0; i < allCurrentVariables.length; i++) { - var variable = allCurrentVariables[i]; - // For any variable that is present in allCurrentVariables but not - // present in originalVariables, add the variable to addedVariables. - if (!originalVariables.includes(variable)) { - addedVariables.push(variable); - } - } - } - return addedVariables; -}; diff --git a/src/index.js b/src/index.js index 3011f69149..917665e6f1 100644 --- a/src/index.js +++ b/src/index.js @@ -23,6 +23,7 @@ import "../blocks_vertical/procedures.js"; import "../blocks_vertical/sensing.js"; import "../blocks_vertical/sound.js"; import * as scratchBlocksUtils from "../core/scratch_blocks_utils.js"; +import * as ScratchVariables from "./variables.js"; import "../core/css.js"; import "../core/field_vertical_separator.js"; import { @@ -58,6 +59,7 @@ export * from "../msg/scratch_msgs.js"; export { glowStack }; export { scratchBlocksUtils }; export { CheckableContinuousFlyout }; +export { ScratchVariables }; export function inject(container, options) { Object.assign(options, { diff --git a/src/variables.js b/src/variables.js new file mode 100644 index 0000000000..ffa2967bc7 --- /dev/null +++ b/src/variables.js @@ -0,0 +1,347 @@ +/** + * @license + * Visual Blocks Editor + * + * Copyright 2012 Google Inc. + * https://developers.google.com/blockly/ + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @fileoverview Utility functions for handling variables. + * @author fraser@google.com (Neil Fraser) + */ +import * as Blockly from "blockly/core"; +import { + LIST_VARIABLE_TYPE, + BROADCAST_MESSAGE_VARIABLE_TYPE, +} from "./constants.js"; + +/** + * Constant prefix to differentiate cloud variable names from other types + * of variables. + * This is the \u2601 cloud unicode character followed by a space. + * @type {string} + * @package + */ +const CLOUD_PREFIX = "☁ "; + +/** + * Create a new variable on the given workspace. + * @param {!Blockly.Workspace} workspace The workspace on which to create the + * variable. + * @param {function(?string=)=} opt_callback An optional callback function to act + * on the id of the variable that is created from the user's input, or null + * if the change is to be aborted (cancel button or an invalid name was provided). + * @param {string} opt_type Optional type of the variable to be created, + * like 'string' or 'list'. + */ +export function createVariable(workspace, opt_callback, opt_type) { + // Decide on a modal message based on the opt_type. If opt_type was not + // provided, default to the original message for scalar variables. + var newMsg, modalTitle; + if (opt_type === BROADCAST_MESSAGE_VARIABLE_TYPE) { + newMsg = Blockly.Msg.NEW_BROADCAST_MESSAGE_TITLE; + modalTitle = Blockly.Msg.BROADCAST_MODAL_TITLE; + } else if (opt_type === LIST_VARIABLE_TYPE) { + newMsg = Blockly.Msg.NEW_LIST_TITLE; + modalTitle = Blockly.Msg.LIST_MODAL_TITLE; + } else { + // Note: this case covers 1) scalar variables, 2) any new type of + // variable not explicitly checked for above, and 3) a null or undefined + // opt_type -- turns a falsey opt_type into '' + // TODO (#1251) Warn developers that they didn't provide an opt_type/provided + // a falsey opt_type + opt_type = opt_type ? opt_type : ""; + newMsg = Blockly.Msg.NEW_VARIABLE_TITLE; + modalTitle = Blockly.Msg.VARIABLE_MODAL_TITLE; + } + var validate = nameValidator.bind(null, opt_type); + + // Prompt the user to enter a name for the variable + Blockly.dialog.prompt( + newMsg, + "", + function (text, additionalVars, variableOptions) { + variableOptions = variableOptions || {}; + var scope = variableOptions.scope; + var isLocal = scope === "local" || false; + var isCloud = variableOptions.isCloud || false; + // Default to [] if additionalVars is not provided + additionalVars = additionalVars || []; + // Only use additionalVars for global variable creation. + var additionalVarNames = isLocal ? [] : additionalVars; + + var validatedText = validate( + text, + workspace, + additionalVarNames, + isCloud, + opt_callback + ); + if (validatedText) { + const VariableModel = Blockly.registry.getObject( + Blockly.registry.Type.VARIABLE_MODEL, + Blockly.registry.DEFAULT, + true + ); + const variable = new VariableModel( + workspace, + validatedText, + opt_type, + null, + isLocal, + isCloud + ); + workspace.getVariableMap().addVariable(variable); + Blockly.Events.fire( + new (Blockly.Events.get(Blockly.Events.VAR_CREATE))(variable) + ); + + var flyout = workspace.isFlyout ? workspace : workspace.getFlyout(); + var variableBlockId = variable.getId(); + if (flyout.setCheckboxState) { + flyout.setCheckboxState(variableBlockId, true); + } + + if (opt_callback) { + opt_callback(variableBlockId); + } + } else { + // User canceled prompt without a value. + if (opt_callback) { + opt_callback(null); + } + } + }, + modalTitle, + opt_type + ); +} + +/** + * This function provides a common interface for variable name validation agnostic + * of type. This is so that functions like Blockly.Variables.createVariable and + * Blockly.Variables.renameVariable can call a single function (with a single + * type signature) to validate the user-provided name for a variable. + * @param {string} type The type of the variable for which the provided name + * should be validated. + * @param {string} text The user-provided text that should be validated as a + * variable name. + * @param {!Blockly.Workspace} workspace The workspace on which to validate the + * variable name. This is the workspace used to check whether the variable + * already exists. + * @param {Array} additionalVars A list of additional var names to check + * for conflicts against. + * @param {boolean} isCloud Whether the variable is a cloud variable. + * @param {function(?string=)=} opt_callback An optional function to be called on + * a pre-existing variable of the user-provided name. This function is currently + * only used for broadcast messages. + * @return {string} The validated name according to the parameters given, if + * the name is determined to be valid, or null if the name + * is determined to be invalid/in-use, and the calling function should not + * proceed with creating or renaming the variable. + * @private + */ +function nameValidator( + type, + text, + workspace, + additionalVars, + isCloud, + opt_callback +) { + // The validators for the different variable types require slightly different arguments. + // For broadcast messages, if a broadcast message of the provided name already exists, + // the validator needs to call a function that updates the selected + // field option of the dropdown menu of the block that was used to create the new message. + // For scalar variables and lists, the validator has the same validation behavior, but needs + // to know which type of variable to check for and needs a type-specific error message + // that is displayed when a variable of the given name and type already exists. + + if (type === BROADCAST_MESSAGE_VARIABLE_TYPE) { + return validateBroadcastMessageName(text, workspace, opt_callback); + } else if (type === LIST_VARIABLE_TYPE) { + return validateScalarVarOrListName( + text, + workspace, + additionalVars, + false, + type, + Blockly.Msg.LIST_ALREADY_EXISTS + ); + } else { + return validateScalarVarOrListName( + text, + workspace, + additionalVars, + isCloud, + type, + Blockly.Msg.VARIABLE_ALREADY_EXISTS + ); + } +} + +/** + * Validate the given name as a broadcast message type. + * @param {string} name The name to validate + * @param {!Blockly.Workspace} workspace The workspace the name should be validated + * against. + * @param {function(?string=)=} opt_callback An optional function to call if a broadcast + * message already exists with the given name. This function will be called on the id + * of the existing variable. + * @return {string} The validated name, or null if invalid. + * @private + */ +function validateBroadcastMessageName(name, workspace, opt_callback) { + if (!name) { + // no name was provided or the user cancelled the prompt + return null; + } + var variable = workspace.getVariable(name, BROADCAST_MESSAGE_VARIABLE_TYPE); + if (variable) { + // If the user provided a name for a broadcast message that already exists, + // use the provided callback function to update the selected option in + // the field of the block that was used to create + // this message. + if (opt_callback) { + opt_callback(variable.getId()); + } + // Return null to signal to the calling function that we do not want to create + // a new variable since one already exists. + return null; + } else { + // The name provided is actually a new name, so the calling + // function should go ahead and create it as a new variable. + return name; + } +} + +/** + * Validate the given name as a scalar variable or list type. + * This function is also responsible for any user facing error-handling. + * @param {string} name The name to validate + * @param {!Blockly.Workspace} workspace The workspace the name should be validated + * against. + * @param {Array} additionalVars A list of additional variable names to check + * for conflicts against. + * @param {boolean} isCloud Whether the variable is a cloud variable. + * @param {string} type The type to validate the variable as. This should be one of + * Blockly.SCALAR_VARIABLE_TYPE or Blockly.LIST_VARIABLE_TYPE. + * @param {string} errorMsg The type-specific error message the user should see + * if a variable of the validated, given name and type already exists. + * @return {string} The validated name, or null if invalid. + * @private + */ +function validateScalarVarOrListName( + name, + workspace, + additionalVars, + isCloud, + type, + errorMsg +) { + // For scalar variables, we don't want leading or trailing white space + name = name.trim(); + if (!name) { + return null; + } + if (isCloud) { + name = CLOUD_PREFIX + name; + } + if (workspace.getVariable(name, type) || additionalVars.indexOf(name) >= 0) { + // error + Blockly.dialog.alert(errorMsg.replace("%1", name)); + return null; + } else { + // trimmed name is valid + return name; + } +} + +/** + * Rename a variable with the given workspace, variableType, and oldName. + * @param {!Blockly.Workspace} workspace The workspace on which to rename the + * variable. + * @param {Blockly.VariableModel} variable Variable to rename. + * @param {function(?string=)=} opt_callback A callback. It will + * be passed an acceptable new variable name, or null if change is to be + * aborted (cancel button), or undefined if an existing variable was chosen. + */ +export function renameVariable(workspace, variable, opt_callback) { + // Validation and modal message/title depends on the variable type + var promptMsg, modalTitle; + var varType = variable.type; + if (varType === BROADCAST_MESSAGE_VARIABLE_TYPE) { + console.warn( + "Unexpected attempt to rename a broadcast message with " + + "id: " + + variable.getId() + + " and name: " + + variable.name + ); + return; + } + if (varType === LIST_VARIABLE_TYPE) { + promptMsg = Blockly.Msg.RENAME_LIST_TITLE; + modalTitle = Blockly.Msg.RENAME_LIST_MODAL_TITLE; + } else { + // Default for all other types of variables + promptMsg = Blockly.Msg.RENAME_VARIABLE_TITLE; + modalTitle = Blockly.Msg.RENAME_VARIABLE_MODAL_TITLE; + } + var validate = nameValidator.bind(null, varType); + + var promptText = promptMsg.replace("%1", variable.name); + var promptDefaultText = variable.name; + if (variable.isCloud && variable.name.indexOf(CLOUD_PREFIX) == 0) { + promptDefaultText = promptDefaultText.substring(CLOUD_PREFIX.length); + } + + Blockly.dialog.prompt( + promptText, + promptDefaultText, + function (newName, additionalVars) { + if ( + variable.isCloud && + newName.length > 0 && + newName.indexOf(CLOUD_PREFIX) == 0 + ) { + newName = newName.substring(CLOUD_PREFIX.length); + // The name validator will add the prefix back + } + additionalVars = additionalVars || []; + var additionalVarNames = variable.isLocal ? [] : additionalVars; + var validatedText = validate( + newName, + workspace, + additionalVarNames, + variable.isCloud + ); + if (validatedText) { + workspace.renameVariableById(variable.getId(), validatedText); + if (opt_callback) { + opt_callback(newName); + } + } else { + // User canceled prompt without a value. + if (opt_callback) { + opt_callback(null); + } + } + }, + modalTitle, + varType + ); +} From dcfbf391cfcf2dbdf04c84b7e5c4d1463c18ed1d Mon Sep 17 00:00:00 2001 From: Aaron Dodson Date: Tue, 30 Jul 2024 08:13:17 -0700 Subject: [PATCH 048/130] feat: readd support for the custom Data toolbox category (#87) * chore: move data_category.js into src * chore: format data_category.js * chore: format constants.js * chore: add SCALAR_VARIABLE_TYPE constant * refactor: clean up data_category.js --- src/constants.js | 32 +-- {core => src}/data_category.js | 357 +++++++++++++++++++-------------- 2 files changed, 227 insertions(+), 162 deletions(-) rename {core => src}/data_category.js (61%) diff --git a/src/constants.js b/src/constants.js index 39cc18d098..66fc9fe5f8 100644 --- a/src/constants.js +++ b/src/constants.js @@ -1,12 +1,20 @@ +/** + * String representing the variable type of scalar variables. + * This string, for use in differentiating between types of variables, + * indicates that the current variable is a scalar variable. + * @const {string} + */ +const SCALAR_VARIABLE_TYPE = ""; +export { SCALAR_VARIABLE_TYPE }; + /** * String representing the variable type of broadcast message blocks. * This string, for use in differentiating between types of variables, * indicates that the current variable is a broadcast message. * @const {string} */ -const BROADCAST_MESSAGE_VARIABLE_TYPE = 'broadcast_msg'; -export {BROADCAST_MESSAGE_VARIABLE_TYPE}; - +const BROADCAST_MESSAGE_VARIABLE_TYPE = "broadcast_msg"; +export { BROADCAST_MESSAGE_VARIABLE_TYPE }; /** * String representing the variable type of list blocks. @@ -14,29 +22,29 @@ export {BROADCAST_MESSAGE_VARIABLE_TYPE}; * indicates that the current variable is a list. * @const {string} */ -const LIST_VARIABLE_TYPE = 'list'; -export {LIST_VARIABLE_TYPE}; +const LIST_VARIABLE_TYPE = "list"; +export { LIST_VARIABLE_TYPE }; /* * The type of all procedure definition blocks. * @const {string} */ -const PROCEDURES_DEFINITION_BLOCK_TYPE = 'procedures_definition'; -export {PROCEDURES_DEFINITION_BLOCK_TYPE}; +const PROCEDURES_DEFINITION_BLOCK_TYPE = "procedures_definition"; +export { PROCEDURES_DEFINITION_BLOCK_TYPE }; /** * The type of all procedure prototype blocks. * @const {string} */ -const PROCEDURES_PROTOTYPE_BLOCK_TYPE = 'procedures_prototype'; -export {PROCEDURES_PROTOTYPE_BLOCK_TYPE}; +const PROCEDURES_PROTOTYPE_BLOCK_TYPE = "procedures_prototype"; +export { PROCEDURES_PROTOTYPE_BLOCK_TYPE }; /** * The type of all procedure call blocks. * @const {string} */ -const PROCEDURES_CALL_BLOCK_TYPE = 'procedures_call'; -export {PROCEDURES_CALL_BLOCK_TYPE}; +const PROCEDURES_CALL_BLOCK_TYPE = "procedures_call"; +export { PROCEDURES_CALL_BLOCK_TYPE }; const OUTPUT_SHAPE_ROUND = 2; -export {OUTPUT_SHAPE_ROUND}; +export { OUTPUT_SHAPE_ROUND }; diff --git a/core/data_category.js b/src/data_category.js similarity index 61% rename from core/data_category.js rename to src/data_category.js index aa1a0ebd19..303300e929 100644 --- a/core/data_category.js +++ b/src/data_category.js @@ -22,96 +22,93 @@ * @fileoverview Data Flyout components including variable and list blocks. * @author marisaleung@google.com (Marisa Leung) */ -'use strict'; +"use strict"; /** * @name Blockly.DataCategory * @namespace **/ -goog.provide('Blockly.DataCategory'); - -goog.require('Blockly.Blocks'); -goog.require('Blockly.VariableModel'); -goog.require('Blockly.Variables'); -goog.require('Blockly.Workspace'); +import * as Blockly from "blockly/core"; +import { createVariable } from "./variables.js"; +import { LIST_VARIABLE_TYPE, SCALAR_VARIABLE_TYPE } from "./constants.js"; /** * Construct the blocks required by the flyout for the variable category. * @param {!Blockly.Workspace} workspace The workspace containing variables. * @return {!Array.} Array of XML block elements. */ -Blockly.DataCategory = function(workspace) { - var variableModelList = workspace.getVariablesOfType(''); - variableModelList.sort(Blockly.VariableModel.compareByName); +export function getVariablesCategory(workspace) { + var variableModelList = workspace.getVariablesOfType(SCALAR_VARIABLE_TYPE); + variableModelList.sort(Blockly.Variables.compareByName); var xmlList = []; - Blockly.DataCategory.addCreateButton(xmlList, workspace, 'VARIABLE'); + addCreateButton(xmlList, workspace, "VARIABLE"); for (var i = 0; i < variableModelList.length; i++) { - Blockly.DataCategory.addDataVariable(xmlList, variableModelList[i]); + addDataVariable(xmlList, variableModelList[i]); } if (variableModelList.length > 0) { - xmlList[xmlList.length - 1].setAttribute('gap', 24); + xmlList[xmlList.length - 1].setAttribute("gap", 24); var firstVariable = variableModelList[0]; - Blockly.DataCategory.addSetVariableTo(xmlList, firstVariable); - Blockly.DataCategory.addChangeVariableBy(xmlList, firstVariable); - Blockly.DataCategory.addShowVariable(xmlList, firstVariable); - Blockly.DataCategory.addHideVariable(xmlList, firstVariable); + addSetVariableTo(xmlList, firstVariable); + addChangeVariableBy(xmlList, firstVariable); + addShowVariable(xmlList, firstVariable); + addHideVariable(xmlList, firstVariable); } // Now add list variables to the flyout - Blockly.DataCategory.addCreateButton(xmlList, workspace, 'LIST'); - variableModelList = workspace.getVariablesOfType(Blockly.LIST_VARIABLE_TYPE); - variableModelList.sort(Blockly.VariableModel.compareByName); + addCreateButton(xmlList, workspace, "LIST"); + variableModelList = workspace.getVariablesOfType(LIST_VARIABLE_TYPE); + variableModelList.sort(Blockly.Variables.compareByName); for (var i = 0; i < variableModelList.length; i++) { - Blockly.DataCategory.addDataList(xmlList, variableModelList[i]); + addDataList(xmlList, variableModelList[i]); } if (variableModelList.length > 0) { - xmlList[xmlList.length - 1].setAttribute('gap', 24); + xmlList[xmlList.length - 1].setAttribute("gap", 24); var firstVariable = variableModelList[0]; - Blockly.DataCategory.addAddToList(xmlList, firstVariable); - Blockly.DataCategory.addSep(xmlList); - Blockly.DataCategory.addDeleteOfList(xmlList, firstVariable); - Blockly.DataCategory.addDeleteAllOfList(xmlList, firstVariable); - Blockly.DataCategory.addInsertAtList(xmlList, firstVariable); - Blockly.DataCategory.addReplaceItemOfList(xmlList, firstVariable); - Blockly.DataCategory.addSep(xmlList); - Blockly.DataCategory.addItemOfList(xmlList, firstVariable); - Blockly.DataCategory.addItemNumberOfList(xmlList, firstVariable); - Blockly.DataCategory.addLengthOfList(xmlList, firstVariable); - Blockly.DataCategory.addListContainsItem(xmlList, firstVariable); - Blockly.DataCategory.addSep(xmlList); - Blockly.DataCategory.addShowList(xmlList, firstVariable); - Blockly.DataCategory.addHideList(xmlList, firstVariable); + addAddToList(xmlList, firstVariable); + addSep(xmlList); + addDeleteOfList(xmlList, firstVariable); + addDeleteAllOfList(xmlList, firstVariable); + addInsertAtList(xmlList, firstVariable); + addReplaceItemOfList(xmlList, firstVariable); + addSep(xmlList); + addItemOfList(xmlList, firstVariable); + addItemNumberOfList(xmlList, firstVariable); + addLengthOfList(xmlList, firstVariable); + addListContainsItem(xmlList, firstVariable); + addSep(xmlList); + addShowList(xmlList, firstVariable); + addHideList(xmlList, firstVariable); } return xmlList; -}; +} /** * Construct and add a data_variable block to xmlList. * @param {!Array.} xmlList Array of XML block elements. * @param {?Blockly.VariableModel} variable Variable to select in the field. */ -Blockly.DataCategory.addDataVariable = function(xmlList, variable) { +function addDataVariable(xmlList, variable) { // // variablename // - Blockly.DataCategory.addBlock(xmlList, variable, 'data_variable', 'VARIABLE'); + addBlock(xmlList, variable, "data_variable", "VARIABLE"); // In the flyout, this ID must match variable ID for monitor syncing reasons - xmlList[xmlList.length - 1].setAttribute('id', variable.getId()); -}; + xmlList[xmlList.length - 1].setAttribute("id", variable.getId()); +} /** * Construct and add a data_setvariableto block to xmlList. * @param {!Array.} xmlList Array of XML block elements. * @param {?Blockly.VariableModel} variable Variable to select in the field. */ -Blockly.DataCategory.addSetVariableTo = function(xmlList, variable) { +function addSetVariableTo(xmlList, variable) { // // // @@ -122,16 +119,19 @@ Blockly.DataCategory.addSetVariableTo = function(xmlList, variable) { // // // - Blockly.DataCategory.addBlock(xmlList, variable, 'data_setvariableto', - 'VARIABLE', ['VALUE', 'text', 0]); -}; + addBlock(xmlList, variable, "data_setvariableto", "VARIABLE", [ + "VALUE", + "text", + 0, + ]); +} /** * Construct and add a data_changevariableby block to xmlList. * @param {!Array.} xmlList Array of XML block elements. * @param {?Blockly.VariableModel} variable Variable to select in the field. */ -Blockly.DataCategory.addChangeVariableBy = function(xmlList, variable) { +function addChangeVariableBy(xmlList, variable) { // // // @@ -142,60 +142,61 @@ Blockly.DataCategory.addChangeVariableBy = function(xmlList, variable) { // // // - Blockly.DataCategory.addBlock(xmlList, variable, 'data_changevariableby', - 'VARIABLE', ['VALUE', 'math_number', 1]); -}; + addBlock(xmlList, variable, "data_changevariableby", "VARIABLE", [ + "VALUE", + "math_number", + 1, + ]); +} /** * Construct and add a data_showVariable block to xmlList. * @param {!Array.} xmlList Array of XML block elements. * @param {?Blockly.VariableModel} variable Variable to select in the field. */ -Blockly.DataCategory.addShowVariable = function(xmlList, variable) { +function addShowVariable(xmlList, variable) { // // // // // - Blockly.DataCategory.addBlock(xmlList, variable, 'data_showvariable', - 'VARIABLE'); -}; + addBlock(xmlList, variable, "data_showvariable", "VARIABLE"); +} /** * Construct and add a data_hideVariable block to xmlList. * @param {!Array.} xmlList Array of XML block elements. * @param {?Blockly.VariableModel} variable Variable to select in the field. */ -Blockly.DataCategory.addHideVariable = function(xmlList, variable) { +function addHideVariable(xmlList, variable) { // // // // // - Blockly.DataCategory.addBlock(xmlList, variable, 'data_hidevariable', - 'VARIABLE'); -}; + addBlock(xmlList, variable, "data_hidevariable", "VARIABLE"); +} /** * Construct and add a data_listcontents block to xmlList. * @param {!Array.} xmlList Array of XML block elements. * @param {?Blockly.VariableModel} variable Variable to select in the field. */ -Blockly.DataCategory.addDataList = function(xmlList, variable) { +function addDataList(xmlList, variable) { // // variablename // - Blockly.DataCategory.addBlock(xmlList, variable, 'data_listcontents', 'LIST'); + addBlock(xmlList, variable, "data_listcontents", "LIST"); // In the flyout, this ID must match variable ID for monitor syncing reasons - xmlList[xmlList.length - 1].setAttribute('id', variable.getId()); -}; + xmlList[xmlList.length - 1].setAttribute("id", variable.getId()); +} /** * Construct and add a data_addtolist block to xmlList. * @param {!Array.} xmlList Array of XML block elements. * @param {?Blockly.VariableModel} variable Variable to select in the field. */ -Blockly.DataCategory.addAddToList = function(xmlList, variable) { +function addAddToList(xmlList, variable) { // // variablename // @@ -204,16 +205,19 @@ Blockly.DataCategory.addAddToList = function(xmlList, variable) { // // // - Blockly.DataCategory.addBlock(xmlList, variable, 'data_addtolist', 'LIST', - ['ITEM', 'text', Blockly.Msg.DEFAULT_LIST_ITEM]); -}; + addBlock(xmlList, variable, "data_addtolist", "LIST", [ + "ITEM", + "text", + Blockly.Msg.DEFAULT_LIST_ITEM, + ]); +} /** * Construct and add a data_deleteoflist block to xmlList. * @param {!Array.} xmlList Array of XML block elements. * @param {?Blockly.VariableModel} variable Variable to select in the field. */ -Blockly.DataCategory.addDeleteOfList = function(xmlList, variable) { +function addDeleteOfList(xmlList, variable) { // // variablename // @@ -222,29 +226,31 @@ Blockly.DataCategory.addDeleteOfList = function(xmlList, variable) { // // // - Blockly.DataCategory.addBlock(xmlList, variable, 'data_deleteoflist', 'LIST', - ['INDEX', 'math_integer', 1]); -}; + addBlock(xmlList, variable, "data_deleteoflist", "LIST", [ + "INDEX", + "math_integer", + 1, + ]); +} /** * Construct and add a data_deleteoflist block to xmlList. * @param {!Array.} xmlList Array of XML block elements. * @param {?Blockly.VariableModel} variable Variable to select in the field. */ -Blockly.DataCategory.addDeleteAllOfList = function(xmlList, variable) { +function addDeleteAllOfList(xmlList, variable) { // // variablename // - Blockly.DataCategory.addBlock(xmlList, variable, 'data_deletealloflist', - 'LIST'); -}; + addBlock(xmlList, variable, "data_deletealloflist", "LIST"); +} /** * Construct and add a data_insertatlist block to xmlList. * @param {!Array.} xmlList Array of XML block elements. * @param {?Blockly.VariableModel} variable Variable to select in the field. */ -Blockly.DataCategory.addInsertAtList = function(xmlList, variable) { +function addInsertAtList(xmlList, variable) { // // variablename // @@ -258,16 +264,22 @@ Blockly.DataCategory.addInsertAtList = function(xmlList, variable) { // // // - Blockly.DataCategory.addBlock(xmlList, variable, 'data_insertatlist', 'LIST', - ['INDEX', 'math_integer', 1], ['ITEM', 'text', Blockly.Msg.DEFAULT_LIST_ITEM]); -}; + addBlock( + xmlList, + variable, + "data_insertatlist", + "LIST", + ["INDEX", "math_integer", 1], + ["ITEM", "text", Blockly.Msg.DEFAULT_LIST_ITEM] + ); +} /** * Construct and add a data_replaceitemoflist block to xmlList. * @param {!Array.} xmlList Array of XML block elements. * @param {?Blockly.VariableModel} variable Variable to select in the field. */ -Blockly.DataCategory.addReplaceItemOfList = function(xmlList, variable) { +function addReplaceItemOfList(xmlList, variable) { // // variablename // @@ -281,16 +293,22 @@ Blockly.DataCategory.addReplaceItemOfList = function(xmlList, variable) { // // // - Blockly.DataCategory.addBlock(xmlList, variable, 'data_replaceitemoflist', - 'LIST', ['INDEX', 'math_integer', 1], ['ITEM', 'text', Blockly.Msg.DEFAULT_LIST_ITEM]); -}; + addBlock( + xmlList, + variable, + "data_replaceitemoflist", + "LIST", + ["INDEX", "math_integer", 1], + ["ITEM", "text", Blockly.Msg.DEFAULT_LIST_ITEM] + ); +} /** * Construct and add a data_itemoflist block to xmlList. * @param {!Array.} xmlList Array of XML block elements. * @param {?Blockly.VariableModel} variable Variable to select in the field. */ -Blockly.DataCategory.addItemOfList = function(xmlList, variable) { +function addItemOfList(xmlList, variable) { // // variablename // @@ -299,15 +317,18 @@ Blockly.DataCategory.addItemOfList = function(xmlList, variable) { // // // - Blockly.DataCategory.addBlock(xmlList, variable, 'data_itemoflist', 'LIST', - ['INDEX', 'math_integer', 1]); -}; + addBlock(xmlList, variable, "data_itemoflist", "LIST", [ + "INDEX", + "math_integer", + 1, + ]); +} /** Construct and add a data_itemnumoflist block to xmlList. * @param {!Array.} xmlList Array of XML block elements. * @param {?Blockly.VariableModel} variable Variable to select in the field. */ -Blockly.DataCategory.addItemNumberOfList = function(xmlList, variable) { +function addItemNumberOfList(xmlList, variable) { // // // @@ -316,28 +337,31 @@ Blockly.DataCategory.addItemNumberOfList = function(xmlList, variable) { // // variablename // - Blockly.DataCategory.addBlock(xmlList, variable, 'data_itemnumoflist', - 'LIST', ['ITEM', 'text', Blockly.Msg.DEFAULT_LIST_ITEM]); -}; + addBlock(xmlList, variable, "data_itemnumoflist", "LIST", [ + "ITEM", + "text", + Blockly.Msg.DEFAULT_LIST_ITEM, + ]); +} /** * Construct and add a data_lengthoflist block to xmlList. * @param {!Array.} xmlList Array of XML block elements. * @param {?Blockly.VariableModel} variable Variable to select in the field. */ -Blockly.DataCategory.addLengthOfList = function(xmlList, variable) { +function addLengthOfList(xmlList, variable) { // // variablename // - Blockly.DataCategory.addBlock(xmlList, variable, 'data_lengthoflist', 'LIST'); -}; + addBlock(xmlList, variable, "data_lengthoflist", "LIST"); +} /** * Construct and add a data_listcontainsitem block to xmlList. * @param {!Array.} xmlList Array of XML block elements. * @param {?Blockly.VariableModel} variable Variable to select in the field. */ -Blockly.DataCategory.addListContainsItem = function(xmlList, variable) { +function addListContainsItem(xmlList, variable) { // // variablename // @@ -346,33 +370,36 @@ Blockly.DataCategory.addListContainsItem = function(xmlList, variable) { // // // - Blockly.DataCategory.addBlock(xmlList, variable, 'data_listcontainsitem', - 'LIST', ['ITEM', 'text', Blockly.Msg.DEFAULT_LIST_ITEM]); -}; + addBlock(xmlList, variable, "data_listcontainsitem", "LIST", [ + "ITEM", + "text", + Blockly.Msg.DEFAULT_LIST_ITEM, + ]); +} /** * Construct and add a data_showlist block to xmlList. * @param {!Array.} xmlList Array of XML block elements. * @param {?Blockly.VariableModel} variable Variable to select in the field. */ -Blockly.DataCategory.addShowList = function(xmlList, variable) { +function addShowList(xmlList, variable) { // // variablename // - Blockly.DataCategory.addBlock(xmlList, variable, 'data_showlist', 'LIST'); -}; + addBlock(xmlList, variable, "data_showlist", "LIST"); +} /** * Construct and add a data_hidelist block to xmlList. * @param {!Array.} xmlList Array of XML block elements. * @param {?Blockly.VariableModel} variable Variable to select in the field. */ -Blockly.DataCategory.addHideList = function(xmlList, variable) { +function addHideList(xmlList, variable) { // // variablename // - Blockly.DataCategory.addBlock(xmlList, variable, 'data_hidelist', 'LIST'); -}; + addBlock(xmlList, variable, "data_hidelist", "LIST"); +} /** * Construct a create variable button and push it to the xmlList. @@ -381,26 +408,27 @@ Blockly.DataCategory.addHideList = function(xmlList, variable) { * @param {string} type Type of variable this is for. For example, 'LIST' or * 'VARIABLE'. */ -Blockly.DataCategory.addCreateButton = function(xmlList, workspace, type) { - var button = goog.dom.createDom('button'); +function addCreateButton(xmlList, workspace, type) { + var button = document.createElement("button"); // Set default msg, callbackKey, and callback values for type 'VARIABLE' var msg = Blockly.Msg.NEW_VARIABLE; - var callbackKey = 'CREATE_VARIABLE'; - var callback = function(button) { - Blockly.Variables.createVariable(button.getTargetWorkspace(), null, '');}; + var callbackKey = "CREATE_VARIABLE"; + var callback = function (button) { + createVariable(button.getTargetWorkspace(), null, SCALAR_VARIABLE_TYPE); + }; - if (type === 'LIST') { + if (type === "LIST") { msg = Blockly.Msg.NEW_LIST; - callbackKey = 'CREATE_LIST'; - callback = function(button) { - Blockly.Variables.createVariable(button.getTargetWorkspace(), null, - Blockly.LIST_VARIABLE_TYPE);}; + callbackKey = "CREATE_LIST"; + callback = function (button) { + createVariable(button.getTargetWorkspace(), null, LIST_VARIABLE_TYPE); + }; } - button.setAttribute('text', msg); - button.setAttribute('callbackKey', callbackKey); + button.setAttribute("text", msg); + button.setAttribute("callbackKey", callbackKey); workspace.registerButtonCallback(callbackKey, callback); xmlList.push(button); -}; +} /** * Construct a variable block with the given variable, blockType, and optional @@ -416,31 +444,54 @@ Blockly.DataCategory.addCreateButton = function(xmlList, workspace, type) { * @param {?Array.} opt_secondValue Optional array containing the value * name and shadow type of a second pair of value tags. */ -Blockly.DataCategory.addBlock = function(xmlList, variable, blockType, - fieldName, opt_value, opt_secondValue) { +function addBlock( + xmlList, + variable, + blockType, + fieldName, + opt_value, + opt_secondValue +) { if (Blockly.Blocks[blockType]) { var firstValueField; var secondValueField; if (opt_value) { - firstValueField = Blockly.DataCategory.createValue(opt_value[0], - opt_value[1], opt_value[2]); + firstValueField = createValue(opt_value[0], opt_value[1], opt_value[2]); } if (opt_secondValue) { - secondValueField = Blockly.DataCategory.createValue(opt_secondValue[0], - opt_secondValue[1], opt_secondValue[2]); + secondValueField = createValue( + opt_secondValue[0], + opt_secondValue[1], + opt_secondValue[2] + ); } var gap = 8; - var blockText = '' + - '' + - Blockly.Variables.generateVariableFieldXml_(variable, fieldName) + - firstValueField + secondValueField + - '' + - ''; - var block = Blockly.Xml.textToDom(blockText).firstChild; + var blockText = + "" + + '' + + generateVariableFieldXml(variable, fieldName) + + firstValueField + + secondValueField + + "" + + ""; + var block = Blockly.utils.xml.textToDom(blockText).firstChild; xmlList.push(block); } -}; +} + +function generateVariableFieldXml(variableModel, opt_name) { + const field = document.createElement("field"); + field.setAttribute("name", opt_name || "VARIABLE"); + field.setAttribute("id", variableModel.getId()); + field.setAttribute("variabletype", variableModel.getType()); + field.textContent = variableModel.getName(); + return field.outerHTML; +} /** * Create the text representation of a value dom element with a shadow of the @@ -450,41 +501,47 @@ Blockly.DataCategory.addBlock = function(xmlList, variable, blockType, * @param {string|number} value The default shadow value. * @return {string} The generated dom element in text. */ -Blockly.DataCategory.createValue = function(valueName, type, value) { +function createValue(valueName, type, value) { var fieldName; switch (valueName) { - case 'ITEM': - fieldName = 'TEXT'; + case "ITEM": + fieldName = "TEXT"; break; - case 'INDEX': - fieldName = 'NUM'; + case "INDEX": + fieldName = "NUM"; break; - case 'VALUE': - if (type === 'math_number') { - fieldName = 'NUM'; + case "VALUE": + if (type === "math_number") { + fieldName = "NUM"; } else { - fieldName = 'TEXT'; + fieldName = "TEXT"; } break; } var valueField = - '' + - '' + - '' + value + '' + - '' + - ''; + '' + + '' + + '' + + value + + "" + + "" + + ""; return valueField; -}; +} /** * Construct a block separator. Add the separator to the given xmlList. * @param {!Array.} xmlList Array of XML block elements. */ -Blockly.DataCategory.addSep = function(xmlList) { +function addSep(xmlList) { var gap = 36; - var sepText = '' + - '' + - ''; - var sep = Blockly.Xml.textToDom(sepText).firstChild; + var sepText = "" + '' + ""; + var sep = Blockly.utils.xml.textToDom(sepText).firstChild; xmlList.push(sep); -}; +} From 9ea96e27f43688bcf81bdc006adac129a1b286c8 Mon Sep 17 00:00:00 2001 From: Aaron Dodson Date: Fri, 2 Aug 2024 10:36:55 -0700 Subject: [PATCH 049/130] fix: clean up data block definitions (#90) * chore: format data blocks * fix: fix data block definitions compatibility --- blocks_vertical/data.js | 619 +++++++++++++++++++++------------------- 1 file changed, 320 insertions(+), 299 deletions(-) diff --git a/blocks_vertical/data.js b/blocks_vertical/data.js index 7e18f2fe7f..b76d4ec5f5 100644 --- a/blocks_vertical/data.js +++ b/blocks_vertical/data.js @@ -18,476 +18,492 @@ * limitations under the License. */ -import * as Blockly from 'blockly/core'; -import {Categories} from '../src/categories.js'; -import * as Constants from '../src/constants.js'; -import * as scratchBlocksUtils from '../core/scratch_blocks_utils.js'; +import * as Blockly from "blockly/core"; +import { Categories } from "../src/categories.js"; +import * as Constants from "../src/constants.js"; +import * as scratchBlocksUtils from "../core/scratch_blocks_utils.js"; - -Blockly.Blocks['data_variable'] = { +Blockly.Blocks["data_variable"] = { /** * Block of Variables * @this Blockly.Block */ - init: function() { + init: function () { this.jsonInit({ - "message0": "%1", - "lastDummyAlign0": "CENTRE", - "args0": [ + message0: "%1", + lastDummyAlign0: "CENTRE", + args0: [ { - "type": "field_variable_getter", - "text": "", - "name": "VARIABLE", - "variableType": "" - } + type: "field_variable_getter", + name: "VARIABLE", + allowedVariableType: Constants.SCALAR_VARIABLE_TYPE, + }, + ], + category: Categories.data, + extensions: [ + "contextMenu_getVariableBlock", + "colours_data", + "output_string", ], - "category": Categories.data, - "extensions": ["contextMenu_getVariableBlock", "colours_data", "output_string"] }); this.checkboxInFlyout = true; - } + }, }; -Blockly.Blocks['data_setvariableto'] = { +Blockly.Blocks["data_setvariableto"] = { /** * Block to set variable to a certain value * @this Blockly.Block */ - init: function() { + init: function () { this.jsonInit({ - "message0": Blockly.Msg.DATA_SETVARIABLETO, - "args0": [ + message0: Blockly.Msg.DATA_SETVARIABLETO, + args0: [ { - "type": "field_variable", - "name": "VARIABLE" + type: "field_variable", + name: "VARIABLE", }, { - "type": "input_value", - "name": "VALUE" - } + type: "input_value", + name: "VALUE", + }, ], - "category": Categories.data, - "extensions": ["colours_data", "shape_statement"] + category: Categories.data, + extensions: ["colours_data", "shape_statement"], }); - } + }, }; -Blockly.Blocks['data_changevariableby'] = { +Blockly.Blocks["data_changevariableby"] = { /** * Block to change variable by a certain value * @this Blockly.Block */ - init: function() { + init: function () { this.jsonInit({ - "message0": Blockly.Msg.DATA_CHANGEVARIABLEBY, - "args0": [ + message0: Blockly.Msg.DATA_CHANGEVARIABLEBY, + args0: [ { - "type": "field_variable", - "name": "VARIABLE" + type: "field_variable", + name: "VARIABLE", }, { - "type": "input_value", - "name": "VALUE" - } + type: "input_value", + name: "VALUE", + }, ], - "category": Categories.data, - "extensions": ["colours_data", "shape_statement"] + category: Categories.data, + extensions: ["colours_data", "shape_statement"], }); - } + }, }; -Blockly.Blocks['data_showvariable'] = { +Blockly.Blocks["data_showvariable"] = { /** * Block to show a variable * @this Blockly.Block */ - init: function() { + init: function () { this.jsonInit({ - "message0": Blockly.Msg.DATA_SHOWVARIABLE, - "args0": [ + message0: Blockly.Msg.DATA_SHOWVARIABLE, + args0: [ { - "type": "field_variable", - "name": "VARIABLE" - } + type: "field_variable", + name: "VARIABLE", + }, ], - "previousStatement": null, - "nextStatement": null, - "category": Categories.data, - "extensions": ["colours_data"] + previousStatement: null, + nextStatement: null, + category: Categories.data, + extensions: ["colours_data"], }); - } + }, }; -Blockly.Blocks['data_hidevariable'] = { +Blockly.Blocks["data_hidevariable"] = { /** * Block to hide a variable * @this Blockly.Block */ - init: function() { + init: function () { this.jsonInit({ - "message0": Blockly.Msg.DATA_HIDEVARIABLE, - "args0": [ + message0: Blockly.Msg.DATA_HIDEVARIABLE, + args0: [ { - "type": "field_variable", - "name": "VARIABLE" - } + type: "field_variable", + name: "VARIABLE", + }, ], - "previousStatement": null, - "nextStatement": null, - "category": Categories.data, - "extensions": ["colours_data"] + previousStatement: null, + nextStatement: null, + category: Categories.data, + extensions: ["colours_data"], }); - } + }, }; -Blockly.Blocks['data_listcontents'] = { +Blockly.Blocks["data_listcontents"] = { /** * List reporter. * @this Blockly.Block */ - init: function() { + init: function () { this.jsonInit({ - "message0": "%1", - "args0": [ + message0: "%1", + args0: [ { - "type": "field_variable_getter", - "text": "", - "name": "LIST", - "variableType": Constants.LIST_VARIABLE_TYPE - } + type: "field_variable_getter", + name: "LIST", + allowedVariableType: Constants.LIST_VARIABLE_TYPE, + }, + ], + category: Categories.dataLists, + extensions: [ + "contextMenu_getListBlock", + "colours_data_lists", + "output_string", ], - "category": Categories.dataLists, - "extensions": ["contextMenu_getListBlock", "colours_data_lists", "output_string"], }); this.checkboxInFlyout = true; - } + }, }; -Blockly.Blocks['data_listindexall'] = { +Blockly.Blocks["data_listindexall"] = { /** * List index menu, with all option. * @this Blockly.Block */ - init: function() { + init: function () { this.jsonInit({ - "message0": "%1", - "args0": [ + message0: "%1", + args0: [ { - "type": "field_numberdropdown", - "name": "INDEX", - "value": "1", - "min": 1, - "precision": 1, - "options": [ + type: "field_numberdropdown", + name: "INDEX", + value: "1", + min: 1, + precision: 1, + options: [ ["1", "1"], [Blockly.Msg.DATA_INDEX_LAST, "last"], - [Blockly.Msg.DATA_INDEX_ALL, "all"] - ] - } + [Blockly.Msg.DATA_INDEX_ALL, "all"], + ], + }, ], - "category": Categories.data, - "extensions": ["colours_textfield", "output_string"] + category: Categories.data, + extensions: ["colours_textfield", "output_string"], }); - } + }, }; -Blockly.Blocks['data_listindexrandom'] = { +Blockly.Blocks["data_listindexrandom"] = { /** * List index menu, with random option. * @this Blockly.Block */ - init: function() { + init: function () { this.jsonInit({ - "message0": "%1", - "args0": [ + message0: "%1", + args0: [ { - "type": "field_numberdropdown", - "name": "INDEX", - "value": "1", - "min": 1, - "precision": 1, - "options": [ + type: "field_numberdropdown", + name: "INDEX", + value: "1", + min: 1, + precision: 1, + options: [ ["1", "1"], [Blockly.Msg.DATA_INDEX_LAST, "last"], - [Blockly.Msg.DATA_INDEX_RANDOM, "random"] - ] - } + [Blockly.Msg.DATA_INDEX_RANDOM, "random"], + ], + }, ], - "category": Categories.data, - "extensions": ["colours_textfield", "output_string"] + category: Categories.data, + extensions: ["colours_textfield", "output_string"], }); - } + }, }; -Blockly.Blocks['data_addtolist'] = { +Blockly.Blocks["data_addtolist"] = { /** * Block to add item to list. * @this Blockly.Block */ - init: function() { + init: function () { this.jsonInit({ - "message0": Blockly.Msg.DATA_ADDTOLIST, - "args0": [ + message0: Blockly.Msg.DATA_ADDTOLIST, + args0: [ { - "type": "input_value", - "name": "ITEM" + type: "input_value", + name: "ITEM", }, { - "type": "field_variable", - "name": "LIST", - "variableTypes": [Constants.LIST_VARIABLE_TYPE] - } + type: "field_variable", + name: "LIST", + variableTypes: [Constants.LIST_VARIABLE_TYPE], + defaultType: Constants.LIST_VARIABLE_TYPE, + }, ], - "category": Categories.dataLists, - "extensions": ["colours_data_lists", "shape_statement"] + category: Categories.dataLists, + extensions: ["colours_data_lists", "shape_statement"], }); - } + }, }; -Blockly.Blocks['data_deleteoflist'] = { +Blockly.Blocks["data_deleteoflist"] = { /** * Block to delete item from list. * @this Blockly.Block */ - init: function() { + init: function () { this.jsonInit({ - "message0": Blockly.Msg.DATA_DELETEOFLIST, - "args0": [ + message0: Blockly.Msg.DATA_DELETEOFLIST, + args0: [ { - "type": "input_value", - "name": "INDEX" + type: "input_value", + name: "INDEX", }, { - "type": "field_variable", - "name": "LIST", - "variableTypes": [Constants.LIST_VARIABLE_TYPE] - } + type: "field_variable", + name: "LIST", + variableTypes: [Constants.LIST_VARIABLE_TYPE], + defaultType: Constants.LIST_VARIABLE_TYPE, + }, ], - "category": Categories.dataLists, - "extensions": ["colours_data_lists", "shape_statement"] + category: Categories.dataLists, + extensions: ["colours_data_lists", "shape_statement"], }); - } + }, }; -Blockly.Blocks['data_deletealloflist'] = { +Blockly.Blocks["data_deletealloflist"] = { /** * Block to delete all items from list. * @this Blockly.Block */ - init: function() { + init: function () { this.jsonInit({ - "message0": Blockly.Msg.DATA_DELETEALLOFLIST, - "args0": [ + message0: Blockly.Msg.DATA_DELETEALLOFLIST, + args0: [ { - "type": "field_variable", - "name": "LIST", - "variableTypes": [Constants.LIST_VARIABLE_TYPE] - } + type: "field_variable", + name: "LIST", + variableTypes: [Constants.LIST_VARIABLE_TYPE], + defaultType: Constants.LIST_VARIABLE_TYPE, + }, ], - "category": Categories.dataLists, - "extensions": ["colours_data_lists", "shape_statement"] + category: Categories.dataLists, + extensions: ["colours_data_lists", "shape_statement"], }); - } + }, }; -Blockly.Blocks['data_insertatlist'] = { +Blockly.Blocks["data_insertatlist"] = { /** * Block to insert item to list. * @this Blockly.Block */ - init: function() { + init: function () { this.jsonInit({ - "message0": Blockly.Msg.DATA_INSERTATLIST, - "args0": [ + message0: Blockly.Msg.DATA_INSERTATLIST, + args0: [ { - "type": "input_value", - "name": "ITEM" + type: "input_value", + name: "ITEM", }, { - "type": "input_value", - "name": "INDEX" + type: "input_value", + name: "INDEX", }, { - "type": "field_variable", - "name": "LIST", - "variableTypes": [Constants.LIST_VARIABLE_TYPE] - } + type: "field_variable", + name: "LIST", + variableTypes: [Constants.LIST_VARIABLE_TYPE], + defaultType: Constants.LIST_VARIABLE_TYPE, + }, ], - "category": Categories.dataLists, - "extensions": ["colours_data_lists", "shape_statement"] + category: Categories.dataLists, + extensions: ["colours_data_lists", "shape_statement"], }); - } + }, }; -Blockly.Blocks['data_replaceitemoflist'] = { +Blockly.Blocks["data_replaceitemoflist"] = { /** * Block to insert item to list. * @this Blockly.Block */ - init: function() { + init: function () { this.jsonInit({ - "message0": Blockly.Msg.DATA_REPLACEITEMOFLIST, - "args0": [ + message0: Blockly.Msg.DATA_REPLACEITEMOFLIST, + args0: [ { - "type": "input_value", - "name": "INDEX" + type: "input_value", + name: "INDEX", }, { - "type": "field_variable", - "name": "LIST", - "variableTypes": [Constants.LIST_VARIABLE_TYPE] + type: "field_variable", + name: "LIST", + variableTypes: [Constants.LIST_VARIABLE_TYPE], + defaultType: Constants.LIST_VARIABLE_TYPE, }, { - "type": "input_value", - "name": "ITEM" - } + type: "input_value", + name: "ITEM", + }, ], - "category": Categories.dataLists, - "extensions": ["colours_data_lists", "shape_statement"] + category: Categories.dataLists, + extensions: ["colours_data_lists", "shape_statement"], }); - } + }, }; -Blockly.Blocks['data_itemoflist'] = { +Blockly.Blocks["data_itemoflist"] = { /** * Block for reporting item of list. * @this Blockly.Block */ - init: function() { + init: function () { this.jsonInit({ - "message0": Blockly.Msg.DATA_ITEMOFLIST, - "args0": [ + message0: Blockly.Msg.DATA_ITEMOFLIST, + args0: [ { - "type": "input_value", - "name": "INDEX" + type: "input_value", + name: "INDEX", }, { - "type": "field_variable", - "name": "LIST", - "variableTypes": [Constants.LIST_VARIABLE_TYPE] - } + type: "field_variable", + name: "LIST", + variableTypes: [Constants.LIST_VARIABLE_TYPE], + defaultType: Constants.LIST_VARIABLE_TYPE, + }, ], - "output": null, - "category": Categories.dataLists, - "extensions": ["colours_data_lists"], - "outputShape": Blockly.OUTPUT_SHAPE_ROUND + output: null, + category: Categories.dataLists, + extensions: ["colours_data_lists"], + outputShape: Blockly.OUTPUT_SHAPE_ROUND, }); - } + }, }; -Blockly.Blocks['data_itemnumoflist'] = { +Blockly.Blocks["data_itemnumoflist"] = { /** * Block for reporting the item # of a string in a list. * @this Blockly.Block */ - init: function() { + init: function () { this.jsonInit({ - "message0": Blockly.Msg.DATA_ITEMNUMOFLIST, - "args0": [ + message0: Blockly.Msg.DATA_ITEMNUMOFLIST, + args0: [ { - "type": "input_value", - "name": "ITEM" + type: "input_value", + name: "ITEM", }, { - "type": "field_variable", - "name": "LIST", - "variableTypes": [Constants.LIST_VARIABLE_TYPE] - } + type: "field_variable", + name: "LIST", + variableTypes: [Constants.LIST_VARIABLE_TYPE], + defaultType: Constants.LIST_VARIABLE_TYPE, + }, ], - "output": null, - "category": Categories.dataLists, - "extensions": ["colours_data_lists"], - "outputShape": Blockly.OUTPUT_SHAPE_ROUND + output: null, + category: Categories.dataLists, + extensions: ["colours_data_lists"], + outputShape: Blockly.OUTPUT_SHAPE_ROUND, }); - } + }, }; -Blockly.Blocks['data_lengthoflist'] = { +Blockly.Blocks["data_lengthoflist"] = { /** * Block for reporting length of list. * @this Blockly.Block */ - init: function() { + init: function () { this.jsonInit({ - "message0": Blockly.Msg.DATA_LENGTHOFLIST, - "args0": [ + message0: Blockly.Msg.DATA_LENGTHOFLIST, + args0: [ { - "type": "field_variable", - "name": "LIST", - "variableTypes": [Constants.LIST_VARIABLE_TYPE] - } + type: "field_variable", + name: "LIST", + variableTypes: [Constants.LIST_VARIABLE_TYPE], + defaultType: Constants.LIST_VARIABLE_TYPE, + }, ], - "category": Categories.dataLists, - "extensions": ["colours_data_lists", "output_number"] + category: Categories.dataLists, + extensions: ["colours_data_lists", "output_number"], }); - } + }, }; -Blockly.Blocks['data_listcontainsitem'] = { +Blockly.Blocks["data_listcontainsitem"] = { /** * Block to report whether list contains item. * @this Blockly.Block */ - init: function() { + init: function () { this.jsonInit({ - "message0": Blockly.Msg.DATA_LISTCONTAINSITEM, - "args0": [ + message0: Blockly.Msg.DATA_LISTCONTAINSITEM, + args0: [ { - "type": "field_variable", - "name": "LIST", - "variableTypes": [Constants.LIST_VARIABLE_TYPE] + type: "field_variable", + name: "LIST", + variableTypes: [Constants.LIST_VARIABLE_TYPE], + defaultType: Constants.LIST_VARIABLE_TYPE, }, { - "type": "input_value", - "name": "ITEM" - } + type: "input_value", + name: "ITEM", + }, ], - "category": Categories.dataLists, - "extensions": ["colours_data_lists", "output_boolean"] + category: Categories.dataLists, + extensions: ["colours_data_lists", "output_boolean"], }); - } + }, }; -Blockly.Blocks['data_showlist'] = { +Blockly.Blocks["data_showlist"] = { /** * Block to show a list. * @this Blockly.Block */ - init: function() { + init: function () { this.jsonInit({ - "message0": Blockly.Msg.DATA_SHOWLIST, - "args0": [ + message0: Blockly.Msg.DATA_SHOWLIST, + args0: [ { - "type": "field_variable", - "name": "LIST", - "variableTypes": [Constants.LIST_VARIABLE_TYPE] - } + type: "field_variable", + name: "LIST", + variableTypes: [Constants.LIST_VARIABLE_TYPE], + defaultType: Constants.LIST_VARIABLE_TYPE, + }, ], - "category": Categories.dataLists, - "extensions": ["colours_data_lists", "shape_statement"] + category: Categories.dataLists, + extensions: ["colours_data_lists", "shape_statement"], }); - } + }, }; -Blockly.Blocks['data_hidelist'] = { +Blockly.Blocks["data_hidelist"] = { /** * Block to hide a list. * @this Blockly.Block */ - init: function() { + init: function () { this.jsonInit({ - "message0": Blockly.Msg.DATA_HIDELIST, - "args0": [ + message0: Blockly.Msg.DATA_HIDELIST, + args0: [ { - "type": "field_variable", - "name": "LIST", - "variableTypes": [Constants.LIST_VARIABLE_TYPE] - } + type: "field_variable", + name: "LIST", + variableTypes: [Constants.LIST_VARIABLE_TYPE], + defaultType: Constants.LIST_VARIABLE_TYPE, + }, ], - "category": Categories.dataLists, - "extensions": ["colours_data_lists", "shape_statement"] + category: Categories.dataLists, + extensions: ["colours_data_lists", "shape_statement"], }); - } + }, }; /** @@ -504,50 +520,54 @@ const CUSTOM_CONTEXT_MENU_GET_VARIABLE_MIXIN = { * @param {!Array} options List of menu options to add to. * @this Blockly.Block */ - customContextMenu: function(options) { - var fieldName = 'VARIABLE'; + customContextMenu: function (options) { + var fieldName = "VARIABLE"; if (this.isCollapsed()) { return; } - var currentVarName = this.getField(fieldName).text_; + var currentVarName = this.getField(fieldName).getVariable().getName(); if (!this.isInFlyout) { - var variablesList = this.workspace.getVariablesOfType(''); - variablesList.sort(function(a, b) { - return scratchBlocksUtils.compareStrings(a.name, b.name); + var variablesList = this.workspace.getVariablesOfType( + Constants.SCALAR_VARIABLE_TYPE + ); + variablesList.sort(function (a, b) { + return scratchBlocksUtils.compareStrings(a.getName(), b.getName()); }); for (var i = 0; i < variablesList.length; i++) { - var varName = variablesList[i].name; + var varName = variablesList[i].getName(); if (varName == currentVarName) continue; - var option = {enabled: true}; + var option = { enabled: true }; option.text = varName; - option.callback = - VARIABLE_OPTION_CALLBACK_FACTORY(this, - variablesList[i].getId(), fieldName); + option.callback = VARIABLE_OPTION_CALLBACK_FACTORY( + this, + variablesList[i].getId(), + fieldName + ); options.push(option); } } else { var renameOption = { text: Blockly.Msg.RENAME_VARIABLE, enabled: true, - callback: RENAME_OPTION_CALLBACK_FACTORY(this, - fieldName) + callback: RENAME_OPTION_CALLBACK_FACTORY(this, fieldName), }; var deleteOption = { - text: Blockly.Msg.DELETE_VARIABLE.replace('%1', currentVarName), + text: Blockly.Msg.DELETE_VARIABLE.replace("%1", currentVarName), enabled: true, - callback: DELETE_OPTION_CALLBACK_FACTORY(this, - fieldName) + callback: DELETE_OPTION_CALLBACK_FACTORY(this, fieldName), }; options.push(renameOption); options.push(deleteOption); } - } + }, }; -Blockly.Extensions.registerMixin('contextMenu_getVariableBlock', - CUSTOM_CONTEXT_MENU_GET_VARIABLE_MIXIN); +Blockly.Extensions.registerMixin( + "contextMenu_getVariableBlock", + CUSTOM_CONTEXT_MENU_GET_VARIABLE_MIXIN +); /** * Mixin to add a context menu for a data_listcontents block. It adds one item for @@ -563,49 +583,53 @@ const CUSTOM_CONTEXT_MENU_GET_LIST_MIXIN = { * @param {!Array} options List of menu options to add to. * @this Blockly.Block */ - customContextMenu: function(options) { - var fieldName = 'LIST'; + customContextMenu: function (options) { + var fieldName = "LIST"; if (this.isCollapsed()) { return; } var currentVarName = this.getField(fieldName).text_; if (!this.isInFlyout) { - var variablesList = this.workspace.getVariablesOfType('list'); - variablesList.sort(function(a, b) { - return scratchBlocksUtils.compareStrings(a.name, b.name); + var variablesList = this.workspace.getVariablesOfType( + Constants.LIST_VARIABLE_TYPE + ); + variablesList.sort(function (a, b) { + return scratchBlocksUtils.compareStrings(a.getName(), b.getName()); }); for (var i = 0; i < variablesList.length; i++) { - var varName = variablesList[i].name; + var varName = variablesList[i].getName(); if (varName == currentVarName) continue; - var option = {enabled: true}; + var option = { enabled: true }; option.text = varName; - option.callback = - VARIABLE_OPTION_CALLBACK_FACTORY(this, - variablesList[i].getId(), fieldName); + option.callback = VARIABLE_OPTION_CALLBACK_FACTORY( + this, + variablesList[i].getId(), + fieldName + ); options.push(option); } } else { var renameOption = { text: Blockly.Msg.RENAME_LIST, enabled: true, - callback: RENAME_OPTION_CALLBACK_FACTORY(this, - fieldName) + callback: RENAME_OPTION_CALLBACK_FACTORY(this, fieldName), }; var deleteOption = { - text: Blockly.Msg.DELETE_LIST.replace('%1', currentVarName), + text: Blockly.Msg.DELETE_LIST.replace("%1", currentVarName), enabled: true, - callback: DELETE_OPTION_CALLBACK_FACTORY(this, - fieldName) + callback: DELETE_OPTION_CALLBACK_FACTORY(this, fieldName), }; options.push(renameOption); options.push(deleteOption); } - } + }, }; -Blockly.Extensions.registerMixin('contextMenu_getListBlock', - CUSTOM_CONTEXT_MENU_GET_LIST_MIXIN); +Blockly.Extensions.registerMixin( + "contextMenu_getListBlock", + CUSTOM_CONTEXT_MENU_GET_LIST_MIXIN +); /** * Callback factory for dropdown menu options associated with a variable getter @@ -617,9 +641,8 @@ Blockly.Extensions.registerMixin('contextMenu_getListBlock', * @param {string} fieldName The name of the field to update on the block. * @return {!function()} A function that updates the block with the new name. */ -const VARIABLE_OPTION_CALLBACK_FACTORY = function(block, - id, fieldName) { - return function() { +const VARIABLE_OPTION_CALLBACK_FACTORY = function (block, id, fieldName) { + return function () { var variableField = block.getField(fieldName); if (!variableField) { console.log("Tried to get a variable field on the wrong type of block."); @@ -635,9 +658,8 @@ const VARIABLE_OPTION_CALLBACK_FACTORY = function(block, * @param {string} fieldName The name of the field to inspect on the block. * @return {!function()} A function that renames the variable. */ -const RENAME_OPTION_CALLBACK_FACTORY = function(block, - fieldName) { - return function() { +const RENAME_OPTION_CALLBACK_FACTORY = function (block, fieldName) { + return function () { var workspace = block.workspace; var variable = block.getField(fieldName).getVariable(); Blockly.Variables.renameVariable(workspace, variable); @@ -651,9 +673,8 @@ const RENAME_OPTION_CALLBACK_FACTORY = function(block, * @param {string} fieldName The name of the field to inspect on the block. * @return {!function()} A function that deletes the variable. */ -const DELETE_OPTION_CALLBACK_FACTORY = function(block, - fieldName) { - return function() { +const DELETE_OPTION_CALLBACK_FACTORY = function (block, fieldName) { + return function () { var workspace = block.workspace; var variable = block.getField(fieldName).getVariable(); workspace.deleteVariableById(variable.getId()); From 7c891e35207b6f561917f27739917cb84755d57c Mon Sep 17 00:00:00 2001 From: Aaron Dodson Date: Fri, 2 Aug 2024 13:05:42 -0700 Subject: [PATCH 050/130] feat: reenable Scratch's FieldVariable subclass (#91) * chore: move field_variable.js into src * chore: format field_variable.js * feat: reenable Scratch's FieldVariable subclass --- core/field_variable.js | 385 ----------------------------------------- src/field_variable.js | 139 +++++++++++++++ src/index.js | 1 + 3 files changed, 140 insertions(+), 385 deletions(-) delete mode 100644 core/field_variable.js create mode 100644 src/field_variable.js diff --git a/core/field_variable.js b/core/field_variable.js deleted file mode 100644 index c188482bd6..0000000000 --- a/core/field_variable.js +++ /dev/null @@ -1,385 +0,0 @@ -/** - * @license - * Visual Blocks Editor - * - * Copyright 2012 Google Inc. - * https://developers.google.com/blockly/ - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @fileoverview Variable input field. - * @author fraser@google.com (Neil Fraser) - */ -'use strict'; - -goog.provide('Blockly.FieldVariable'); - -goog.require('Blockly.FieldDropdown'); -goog.require('Blockly.Msg'); -goog.require('Blockly.VariableModel'); -goog.require('Blockly.Variables'); -goog.require('goog.asserts'); -goog.require('goog.string'); - - -/** - * Class for a variable's dropdown field. - * @param {?string} varname The default name for the variable. If null, - * a unique variable name will be generated. - * @param {Function=} opt_validator A function that is executed when a new - * option is selected. Its sole argument is the new option value. - * @param {Array.} opt_variableTypes A list of the types of variables to - * include in the dropdown. - * @extends {Blockly.FieldDropdown} - * @constructor - */ -Blockly.FieldVariable = function(varname, opt_validator, opt_variableTypes) { - // The FieldDropdown constructor would call setValue, which might create a - // spurious variable. Just do the relevant parts of the constructor. - this.menuGenerator_ = Blockly.FieldVariable.dropdownCreate; - this.size_ = new goog.math.Size(Blockly.BlockSvg.FIELD_WIDTH, - Blockly.BlockSvg.FIELD_HEIGHT); - this.setValidator(opt_validator); - // TODO (blockly #1499): Add opt_default_type to match default value. - // If not set, ''. - this.defaultVariableName = (varname || ''); - var hasSingleVarType = opt_variableTypes && (opt_variableTypes.length == 1); - this.defaultType_ = hasSingleVarType ? opt_variableTypes[0] : ''; - this.variableTypes = opt_variableTypes; - this.addArgType('variable'); - - this.value_ = null; -}; -goog.inherits(Blockly.FieldVariable, Blockly.FieldDropdown); - -/** - * Construct a FieldVariable from a JSON arg object, - * dereferencing any string table references. - * @param {!Object} options A JSON object with options (variable, - * variableTypes, and defaultType). - * @returns {!Blockly.FieldVariable} The new field instance. - * @package - * @nocollapse - */ -Blockly.FieldVariable.fromJson = function(options) { - var varname = Blockly.utils.replaceMessageReferences(options['variable']); - var variableTypes = options['variableTypes']; - return new Blockly.FieldVariable(varname, null, variableTypes); -}; - -/** - * Initialize everything needed to render this field. This includes making sure - * that the field's value is valid. - * @public - */ -Blockly.FieldVariable.prototype.init = function() { - if (this.fieldGroup_) { - // Dropdown has already been initialized once. - return; - } - Blockly.FieldVariable.superClass_.init.call(this); - - // TODO (blockly #1010): Change from init/initModel to initView/initModel - this.initModel(); -}; - -/** - * Initialize the model for this field if it has not already been initialized. - * If the value has not been set to a variable by the first render, we make up a - * variable rather than let the value be invalid. - * @package - */ -Blockly.FieldVariable.prototype.initModel = function() { - if (this.variable_) { - return; // Initialization already happened. - } - this.workspace_ = this.sourceBlock_.workspace; - // Initialize this field if it's in a broadcast block in the flyout - var variable = this.initFlyoutBroadcast_(this.workspace_); - if (!variable) { - var variable = Blockly.Variables.getOrCreateVariablePackage( - this.workspace_, null, this.defaultVariableName, this.defaultType_); - } - // Don't fire a change event for this setValue. It would have null as the - // old value, which is not valid. - Blockly.Events.disable(); - try { - this.setValue(variable.getId()); - } finally { - Blockly.Events.enable(); - } -}; - -/** - * Initialize broadcast blocks in the flyout. - * Implicit deletion of broadcast messages from the scratch vm may cause - * broadcast blocks in the flyout to change which variable they display as the - * selected option when the workspace is refreshed. - * Re-sort the broadcast messages by name, and set the field value to the id - * of the variable that comes first in sorted order. - * @param {!Blockly.Workspace} workspace The flyout workspace containing the - * broadcast block. - * @return {string} The variable of type 'broadcast_msg' that comes - * first in sorted order. - */ -Blockly.FieldVariable.prototype.initFlyoutBroadcast_ = function(workspace) { - // Using shorter name for this constant - var broadcastMsgType = Blockly.BROADCAST_MESSAGE_VARIABLE_TYPE; - var broadcastVars = workspace.getVariablesOfType(broadcastMsgType); - if(workspace.isFlyout && this.defaultType_ == broadcastMsgType && - broadcastVars.length != 0) { - broadcastVars.sort(Blockly.VariableModel.compareByName); - return broadcastVars[0]; - } -}; - -/** - * Dispose of this field. - * @public - */ -Blockly.FieldVariable.dispose = function() { - Blockly.FieldVariable.superClass_.dispose.call(this); - this.workspace_ = null; - this.variableMap_ = null; -}; - -/** - * Attach this field to a block. - * @param {!Blockly.Block} block The block containing this field. - */ -Blockly.FieldVariable.prototype.setSourceBlock = function(block) { - goog.asserts.assert(!block.isShadow(), - 'Variable fields are not allowed to exist on shadow blocks.'); - Blockly.FieldVariable.superClass_.setSourceBlock.call(this, block); -}; - -/** - * Get the variable's ID. - * @return {string} Current variable's ID. - */ -Blockly.FieldVariable.prototype.getValue = function() { - return this.variable_ ? this.variable_.getId() : null; -}; - -/** - * Get the text from this field, which is the selected variable's name. - * @return {string} The selected variable's name, or the empty string if no - * variable is selected. - */ -Blockly.FieldVariable.prototype.getText = function() { - return this.variable_ ? this.variable_.name : ''; -}; - -/** - * Get the variable model for the selected variable. - * Not guaranteed to be in the variable map on the workspace (e.g. if accessed - * after the variable has been deleted). - * @return {?Blockly.VariableModel} the selected variable, or null if none was - * selected. - * @package - */ -Blockly.FieldVariable.prototype.getVariable = function() { - return this.variable_; -}; - -/** - * Set the variable ID. - * @param {string} id New variable ID, which must reference an existing - * variable. - */ -Blockly.FieldVariable.prototype.setValue = function(id) { - var workspace = this.sourceBlock_.workspace; - var variable = Blockly.Variables.getVariable(workspace, id); - - if (!variable) { - throw new Error('Variable id doesn\'t point to a real variable! ID was ' + - id); - } - // Type checks! - var type = variable.type; - if (!this.typeIsAllowed_(type)) { - throw new Error('Variable type doesn\'t match this field! Type was ' + - type); - } - if (this.sourceBlock_ && Blockly.Events.isEnabled()) { - var oldValue = this.variable_ ? this.variable_.getId() : null; - Blockly.Events.fire(new Blockly.Events.BlockChange( - this.sourceBlock_, 'field', this.name, oldValue, id)); - } - this.variable_ = variable; - this.value_ = id; - this.setText(variable.name); -}; - -/** - * Check whether the given variable type is allowed on this field. - * @param {string} type The type to check. - * @return {boolean} True if the type is in the list of allowed types. - * @private - */ -Blockly.FieldVariable.prototype.typeIsAllowed_ = function(type) { - var typeList = this.getVariableTypes_(); - if (!typeList) { - return true; // If it's null, all types are valid. - } - for (var i = 0; i < typeList.length; i++) { - if (type == typeList[i]) { - return true; - } - } - return false; -}; - -/** - * Return a list of variable types to include in the dropdown. - * @return {!Array.} Array of variable types. - * @throws {Error} if variableTypes is an empty array. - * @private - */ -Blockly.FieldVariable.prototype.getVariableTypes_ = function() { - // TODO (#1513): Try to avoid calling this every time the field is edited. - var variableTypes = this.variableTypes; - if (variableTypes === null) { - // If variableTypes is null, return all variable types. - if (this.sourceBlock_) { - var workspace = this.sourceBlock_.workspace; - return workspace.getVariableTypes(); - } - } - variableTypes = variableTypes || ['']; - if (variableTypes.length == 0) { - // Throw an error if variableTypes is an empty list. - var name = this.getText(); - throw new Error('\'variableTypes\' of field variable ' + - name + ' was an empty list'); - } - return variableTypes; -}; - -/** - * Return a sorted list of variable names for variable dropdown menus. - * Include a special option at the end for creating a new variable name. - * @return {!Array.} Array of variable names. - * @this {Blockly.FieldVariable} - */ -Blockly.FieldVariable.dropdownCreate = function() { - if (!this.variable_) { - throw new Error('Tried to call dropdownCreate on a variable field with no' + - ' variable selected.'); - } - var variableModelList = []; - var name = this.getText(); - var workspace = null; - if (this.sourceBlock_) { - workspace = this.sourceBlock_.workspace; - } - if (workspace) { - var variableTypes = this.getVariableTypes_(); - var variableModelList = []; - // Get a copy of the list, so that adding rename and new variable options - // doesn't modify the workspace's list. - for (var i = 0; i < variableTypes.length; i++) { - var variableType = variableTypes[i]; - var variables = workspace.getVariablesOfType(variableType); - variableModelList = variableModelList.concat(variables); - - var potentialVarMap = workspace.getPotentialVariableMap(); - if (potentialVarMap) { - var potentialVars = potentialVarMap.getVariablesOfType(variableType); - variableModelList = variableModelList.concat(potentialVars); - } - } - } - variableModelList.sort(Blockly.VariableModel.compareByName); - - var options = []; - for (var i = 0; i < variableModelList.length; i++) { - // Set the uuid as the internal representation of the variable. - options[i] = [variableModelList[i].name, variableModelList[i].getId()]; - } - if (this.defaultType_ == Blockly.BROADCAST_MESSAGE_VARIABLE_TYPE) { - options.unshift( - [Blockly.Msg.NEW_BROADCAST_MESSAGE, Blockly.NEW_BROADCAST_MESSAGE_ID]); - } else { - // Scalar variables and lists have the same backing action, but the option - // text is different. - if (this.defaultType_ == Blockly.LIST_VARIABLE_TYPE) { - var renameText = Blockly.Msg.RENAME_LIST; - var deleteText = Blockly.Msg.DELETE_LIST; - } else { - var renameText = Blockly.Msg.RENAME_VARIABLE; - var deleteText = Blockly.Msg.DELETE_VARIABLE; - } - options.push([renameText, Blockly.RENAME_VARIABLE_ID]); - if (deleteText) { - options.push( - [ - deleteText.replace('%1', name), - Blockly.DELETE_VARIABLE_ID - ]); - } - } - - return options; -}; - -/** - * Handle the selection of an item in the variable dropdown menu. - * Special case the 'Rename variable...', 'Delete variable...', - * and 'New message...' options. - * In the rename case, prompt the user for a new name. - * @param {!goog.ui.Menu} menu The Menu component clicked. - * @param {!goog.ui.MenuItem} menuItem The MenuItem selected within menu. - */ -Blockly.FieldVariable.prototype.onItemSelected = function(menu, menuItem) { - var id = menuItem.getValue(); - if (this.sourceBlock_ && this.sourceBlock_.workspace) { - var workspace = this.sourceBlock_.workspace; - if (id == Blockly.RENAME_VARIABLE_ID) { - // Rename variable. - Blockly.Variables.renameVariable(workspace, this.variable_); - return; - } else if (id == Blockly.DELETE_VARIABLE_ID) { - // Delete variable. - workspace.deleteVariableById(this.variable_.getId()); - return; - } else if (id == Blockly.NEW_BROADCAST_MESSAGE_ID) { - var thisField = this; - var updateField = function(varId) { - if (varId) { - thisField.setValue(varId); - } - }; - Blockly.Variables.createVariable(workspace, updateField, - Blockly.BROADCAST_MESSAGE_VARIABLE_TYPE); - return; - } - - // TODO (blockly #1529): Call any validation function, and allow it to override. - } - this.setValue(id); -}; - -/** - * Overrides referencesVariables(), indicating this field refers to a variable. - * @return {boolean} True. - * @package - * @override - */ -Blockly.FieldVariable.prototype.referencesVariables = function() { - return true; -}; - -Blockly.Field.register('field_variable', Blockly.FieldVariable); diff --git a/src/field_variable.js b/src/field_variable.js new file mode 100644 index 0000000000..0617fd688b --- /dev/null +++ b/src/field_variable.js @@ -0,0 +1,139 @@ +/** + * @license + * Visual Blocks Editor + * + * Copyright 2012 Google Inc. + * https://developers.google.com/blockly/ + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @fileoverview Variable input field. + * @author fraser@google.com (Neil Fraser) + */ +import * as Blockly from "blockly/core"; +import * as Constants from "./constants.js"; +import { ScratchMsgs } from "../msg/scratch_msgs.js"; +import { createVariable } from "./variables.js"; + +class FieldVariable extends Blockly.FieldVariable { + constructor(varName, validator, variableTypes, defaultType, config) { + super(varName, validator, variableTypes, defaultType, config); + this.menuGenerator_ = FieldVariable.dropdownCreate; + } + + initModel() { + if (!this.variable) { + const sourceBlock = this.getSourceBlock(); + if (sourceBlock) { + const broadcastVariable = this.initFlyoutBroadcast( + sourceBlock.workspace + ); + if (broadcastVariable) { + this.doValueUpdate_(broadcastVariable.getId()); + return; + } + } + } + + super.initModel(); + } + + /** + * Initialize broadcast blocks in the flyout. + * Implicit deletion of broadcast messages from the scratch vm may cause + * broadcast blocks in the flyout to change which variable they display as the + * selected option when the workspace is refreshed. + * Re-sort the broadcast messages by name, and set the field value to the id + * of the variable that comes first in sorted order. + * @param {!Blockly.Workspace} workspace The flyout workspace containing the + * broadcast block. + * @return {string} The variable of type 'broadcast_msg' that comes + * first in sorted order. + */ + initFlyoutBroadcast(workspace) { + const broadcastVars = workspace.getVariablesOfType( + Constants.BROADCAST_MESSAGE_VARIABLE_TYPE + ); + if ( + workspace.isFlyout && + this.getDefaultType() == Constants.BROADCAST_MESSAGE_VARIABLE_TYPE && + broadcastVars.length != 0 + ) { + broadcastVars.sort(Blockly.Variables.compareByName); + return broadcastVars[0]; + } + } + + /** + * Return a sorted list of variable names for variable dropdown menus. + * Include a special option at the end for creating a new variable name. + * @return {!Array.} Array of variable names. + * @this {Blockly.FieldVariable} + */ + static dropdownCreate() { + const options = super.dropdownCreate(); + const type = this.getDefaultType(); + if (type === Constants.BROADCAST_MESSAGE_VARIABLE_TYPE) { + options.splice(-2, 2, [ + ScratchMsgs.translate("NEW_BROADCAST_MESSAGE"), + Constants.NEW_BROADCAST_MESSAGE_ID, + ]); + } else if (type === Constants.LIST_VARIABLE_TYPE) { + for (const option of options) { + if (option[1] === Blockly.RENAME_VARIABLE_ID) { + option[0] = ScratchMsgs.translate("RENAME_LIST"); + } else if (option[1] === Blockly.DELETE_VARIABLE_ID) { + option[0] = ScratchMsgs.translate("DELETE_LIST").replace( + "%1", + this.getText() + ); + } + } + } + + return options; + } + + /** Handle the selection of an item in the variable dropdown menu. + * Special case the 'Rename variable...', 'Delete variable...', + * and 'New message...' options. + * In the rename case, prompt the user for a new name. + * @param {!Blockly.Menu} menu The Menu component clicked. + * @param {!Blockly.MenuItem} menuItem The MenuItem selected within menu. + */ + onItemSelected_(menu, menuItem) { + const sourceBlock = this.getSourceBlock(); + if ( + sourceBlock && + !sourceBlock.isDeadOrDying() && + menuItem.getValue() === Constants.NEW_BROADCAST_MESSAGE_ID + ) { + createVariable( + sourceBlock.workspace, + (varId) => { + if (varId) { + this.setValue(varId); + } + }, + Constants.BROADCAST_MESSAGE_VARIABLE_TYPE + ); + return; + } + super.onItemSelected_(menu, menuItem); + } +} + +Blockly.fieldRegistry.unregister("field_variable"); +Blockly.fieldRegistry.register("field_variable", FieldVariable); diff --git a/src/index.js b/src/index.js index 917665e6f1..da6176eb5b 100644 --- a/src/index.js +++ b/src/index.js @@ -44,6 +44,7 @@ import "./events_block_comment_delete.js"; import "./events_block_comment_move.js"; import "./events_block_comment_resize.js"; import "./events_scratch_variable_create.js"; +import "./field_variable.js"; import { buildShadowFilter } from "./shadows.js"; export * from "blockly"; From 28ad0760d2f59f43be0757e4f19ce1e6aa935bde Mon Sep 17 00:00:00 2001 From: Aaron Dodson Date: Fri, 2 Aug 2024 13:30:17 -0700 Subject: [PATCH 051/130] chore: add exports/imports needed for variable support (#92) --- src/constants.js | 10 ++++++++++ src/index.js | 2 ++ src/variables.js | 2 ++ 3 files changed, 14 insertions(+) diff --git a/src/constants.js b/src/constants.js index 66fc9fe5f8..39d916e791 100644 --- a/src/constants.js +++ b/src/constants.js @@ -48,3 +48,13 @@ export { PROCEDURES_CALL_BLOCK_TYPE }; const OUTPUT_SHAPE_ROUND = 2; export { OUTPUT_SHAPE_ROUND }; + +/** + * String for use in the dropdown created in field_variable, + * specifically for broadcast messages. + * This string indicates that this option in the dropdown is 'New message...' + * and if selected, should trigger the prompt to create a new message. + * @const {string} + */ +const NEW_BROADCAST_MESSAGE_ID = "NEW_BROADCAST_MESSAGE_ID"; +export { NEW_BROADCAST_MESSAGE_ID }; diff --git a/src/index.js b/src/index.js index da6176eb5b..51001a69c6 100644 --- a/src/index.js +++ b/src/index.js @@ -45,6 +45,7 @@ import "./events_block_comment_move.js"; import "./events_block_comment_resize.js"; import "./events_scratch_variable_create.js"; import "./field_variable.js"; +import "./field_variable_getter.js"; import { buildShadowFilter } from "./shadows.js"; export * from "blockly"; @@ -57,6 +58,7 @@ export * from "../core/field_matrix.js"; export * from "../core/field_note.js"; export * from "../core/field_number.js"; export * from "../msg/scratch_msgs.js"; +export * from "./constants.js"; export { glowStack }; export { scratchBlocksUtils }; export { CheckableContinuousFlyout }; diff --git a/src/variables.js b/src/variables.js index ffa2967bc7..a171730293 100644 --- a/src/variables.js +++ b/src/variables.js @@ -345,3 +345,5 @@ export function renameVariable(workspace, variable, opt_callback) { varType ); } + +export { getVariablesCategory } from "./data_category.js"; From 747854658b5db2f4cfc00d827ef00c1081ab3c28 Mon Sep 17 00:00:00 2001 From: Aaron Dodson Date: Mon, 5 Aug 2024 11:11:14 -0700 Subject: [PATCH 052/130] fix: fix exception when editing custom blocks (#105) * chore: format procedures.js * fix: fix exception when editing custom blocks --- blocks_vertical/procedures.js | 419 ++++++++++++++++++---------------- 1 file changed, 216 insertions(+), 203 deletions(-) diff --git a/blocks_vertical/procedures.js b/blocks_vertical/procedures.js index 71f103257e..d0da81bff2 100644 --- a/blocks_vertical/procedures.js +++ b/blocks_vertical/procedures.js @@ -22,9 +22,9 @@ * @fileoverview Procedure blocks for Scratch. */ -import * as Blockly from 'blockly/core'; -import {Colours} from '../core/colours.js'; -import {FieldTextInputRemovable} from '../core/field_textinput_removable.js'; +import * as Blockly from "blockly/core"; +import { Colours } from "../core/colours.js"; +import { FieldTextInputRemovable } from "../core/field_textinput_removable.js"; // Serialization and deserialization. @@ -35,10 +35,10 @@ import {FieldTextInputRemovable} from '../core/field_textinput_removable.js'; * @this Blockly.Block */ function callerMutationToDom() { - var container = document.createElement('mutation'); - container.setAttribute('proccode', this.procCode_); - container.setAttribute('argumentids', JSON.stringify(this.argumentIds_)); - container.setAttribute('warp', JSON.stringify(this.warp_)); + var container = document.createElement("mutation"); + container.setAttribute("proccode", this.procCode_); + container.setAttribute("argumentids", JSON.stringify(this.argumentIds_)); + container.setAttribute("warp", JSON.stringify(this.warp_)); return container; } @@ -49,11 +49,12 @@ function callerMutationToDom() { * @this Blockly.Block */ function callerDomToMutation(xmlElement) { - this.procCode_ = xmlElement.getAttribute('proccode'); - this.generateShadows_ = - JSON.parse(xmlElement.getAttribute('generateshadows')); - this.argumentIds_ = JSON.parse(xmlElement.getAttribute('argumentids')); - this.warp_ = JSON.parse(xmlElement.getAttribute('warp')); + this.procCode_ = xmlElement.getAttribute("proccode"); + this.generateShadows_ = JSON.parse( + xmlElement.getAttribute("generateshadows") + ); + this.argumentIds_ = JSON.parse(xmlElement.getAttribute("argumentids")); + this.warp_ = JSON.parse(xmlElement.getAttribute("warp")); this.updateDisplay_(); } @@ -65,19 +66,20 @@ function callerDomToMutation(xmlElement) { * @return {!Element} XML storage element. * @this Blockly.Block */ -function definitionMutationToDom( - opt_generateShadows) { - var container = document.createElement('mutation'); +function definitionMutationToDom(opt_generateShadows) { + var container = document.createElement("mutation"); if (opt_generateShadows) { - container.setAttribute('generateshadows', true); - } - container.setAttribute('proccode', this.procCode_); - container.setAttribute('argumentids', JSON.stringify(this.argumentIds_)); - container.setAttribute('argumentnames', JSON.stringify(this.displayNames_)); - container.setAttribute('argumentdefaults', - JSON.stringify(this.argumentDefaults_)); - container.setAttribute('warp', JSON.stringify(this.warp_)); + container.setAttribute("generateshadows", true); + } + container.setAttribute("proccode", this.procCode_); + container.setAttribute("argumentids", JSON.stringify(this.argumentIds_)); + container.setAttribute("argumentnames", JSON.stringify(this.displayNames_)); + container.setAttribute( + "argumentdefaults", + JSON.stringify(this.argumentDefaults_) + ); + container.setAttribute("warp", JSON.stringify(this.warp_)); return container; } @@ -88,16 +90,17 @@ function definitionMutationToDom( * @this Blockly.Block */ function definitionDomToMutation(xmlElement) { - this.procCode_ = xmlElement.getAttribute('proccode'); - this.warp_ = JSON.parse(xmlElement.getAttribute('warp')); + this.procCode_ = xmlElement.getAttribute("proccode"); + this.warp_ = JSON.parse(xmlElement.getAttribute("warp")); var prevArgIds = this.argumentIds_; var prevDisplayNames = this.displayNames_; - this.argumentIds_ = JSON.parse(xmlElement.getAttribute('argumentids')); - this.displayNames_ = JSON.parse(xmlElement.getAttribute('argumentnames')); + this.argumentIds_ = JSON.parse(xmlElement.getAttribute("argumentids")); + this.displayNames_ = JSON.parse(xmlElement.getAttribute("argumentnames")); this.argumentDefaults_ = JSON.parse( - xmlElement.getAttribute('argumentdefaults')); + xmlElement.getAttribute("argumentdefaults") + ); this.updateDisplay_(); if (this.updateArgumentReporterNames_) { this.updateArgumentReporterNames_(prevArgIds, prevDisplayNames); @@ -125,20 +128,10 @@ function getProcCode() { * @this Blockly.Block */ function updateDisplay_() { - var wasRendered = this.rendered; - this.rendered = false; - var connectionMap = this.disconnectOldBlocks_(); this.removeAllInputs_(); - this.createAllInputs_(connectionMap); this.deleteShadows_(connectionMap); - - this.rendered = wasRendered; - if (wasRendered && !this.isInsertionMarker()) { - this.initSvg(); - this.render(); - } } /** @@ -154,12 +147,12 @@ function updateDisplay_() { function disconnectOldBlocks_() { // Remove old stuff var connectionMap = {}; - for (var i = 0, input; input = this.inputList[i]; i++) { + for (var i = 0, input; (input = this.inputList[i]); i++) { if (input.connection) { var target = input.connection.targetBlock(); var saveInfo = { shadow: input.connection.getShadowDom(), - block: target + block: target, }; connectionMap[input.name] = saveInfo; @@ -180,7 +173,7 @@ function disconnectOldBlocks_() { function removeAllInputs_() { // Delete inputs directly instead of with block.removeInput to avoid splicing // out of the input list at every index. - for (var i = 0, input; input = this.inputList[i]; i++) { + for (var i = 0, input; (input = this.inputList[i]); i++) { input.dispose(); } this.inputList = []; @@ -197,34 +190,42 @@ function removeAllInputs_() { function createAllInputs_(connectionMap) { // Split the proc into components, by %n, %b, and %s (ignoring escaped). var procComponents = this.procCode_.split(/(?=[^\\]%[nbs])/); - procComponents = procComponents.map(function(c) { + procComponents = procComponents.map(function (c) { return c.trim(); // Strip whitespace. }); // Create arguments and labels as appropriate. var argumentCount = 0; - for (var i = 0, component; component = procComponents[i]; i++) { + for (var i = 0, component; (component = procComponents[i]); i++) { var labelText; - if (component.substring(0, 1) == '%') { + if (component.substring(0, 1) == "%") { var argumentType = component.substring(1, 2); - if (!(argumentType == 'n' || argumentType == 'b' || argumentType == 's')) { + if ( + !(argumentType == "n" || argumentType == "b" || argumentType == "s") + ) { throw new Error( - 'Found an custom procedure with an invalid type: ' + argumentType); + "Found an custom procedure with an invalid type: " + argumentType + ); } labelText = component.substring(2).trim(); var id = this.argumentIds_[argumentCount]; var input = this.appendValueInput(id); - if (argumentType == 'b') { - input.setCheck('Boolean'); + if (argumentType == "b") { + input.setCheck("Boolean"); } - this.populateArgument_(argumentType, argumentCount, connectionMap, id, - input); + this.populateArgument_( + argumentType, + argumentCount, + connectionMap, + id, + input + ); argumentCount++; } else { labelText = component.trim(); } - this.addProcedureLabel_(labelText.replace(/\\%/, '%')); + this.addProcedureLabel_(labelText.replace(/\\%/, "%")); } } @@ -242,7 +243,7 @@ function deleteShadows_(connectionMap) { for (var id in connectionMap) { var saveInfo = connectionMap[id]; if (saveInfo) { - var block = saveInfo['block']; + var block = saveInfo["block"]; if (block && block.isShadow()) { block.dispose(); connectionMap[id] = null; @@ -274,8 +275,9 @@ function addLabelField_(text) { */ function addLabelEditor_(text) { if (text) { - this.appendDummyInput(Blockly.utils.idGenerator.genUid()). - appendField(new FieldTextInputRemovable(text)); + this.appendDummyInput(Blockly.utils.idGenerator.genUid()).appendField( + new FieldTextInputRemovable(text) + ); } } @@ -287,19 +289,19 @@ function addLabelEditor_(text) { * @this Blockly.Block */ function buildShadowDom_(type) { - var shadowDom = goog.dom.createDom('shadow'); - if (type == 'n') { - var shadowType = 'math_number'; - var fieldName = 'NUM'; - var fieldValue = '1'; + var shadowDom = goog.dom.createDom("shadow"); + if (type == "n") { + var shadowType = "math_number"; + var fieldName = "NUM"; + var fieldValue = "1"; } else { - var shadowType = 'text'; - var fieldName = 'TEXT'; - var fieldValue = ''; + var shadowType = "text"; + var fieldName = "TEXT"; + var fieldValue = ""; } - shadowDom.setAttribute('type', shadowType); - var fieldDom = goog.dom.createDom('field', null, fieldValue); - fieldDom.setAttribute('name', fieldName); + shadowDom.setAttribute("type", shadowType); + var fieldDom = goog.dom.createDom("field", null, fieldValue); + fieldDom.setAttribute("name", fieldName); shadowDom.appendChild(fieldDom); return shadowDom; } @@ -312,17 +314,16 @@ function buildShadowDom_(type) { * @private * @this Blockly.Block */ -function attachShadow_(input, - argumentType) { - if (argumentType == 'n' || argumentType == 's') { - var blockType = argumentType == 'n' ? 'math_number' : 'text'; +function attachShadow_(input, argumentType) { + if (argumentType == "n" || argumentType == "s") { + var blockType = argumentType == "n" ? "math_number" : "text"; Blockly.Events.disable(); try { var newBlock = this.workspace.newBlock(blockType); - if (argumentType == 'n') { - newBlock.setFieldValue('1', 'NUM'); + if (argumentType == "n") { + newBlock.setFieldValue("1", "NUM"); } else { - newBlock.setFieldValue('', 'TEXT'); + newBlock.setFieldValue("", "TEXT"); } newBlock.setShadow(true); if (!this.isInsertionMarker()) { @@ -333,7 +334,9 @@ function attachShadow_(input, Blockly.Events.enable(); } if (Blockly.Events.isEnabled()) { - Blockly.Events.fire(new (Blockly.Events.get(Blockly.Events.BLOCK_CREATE))(newBlock)); + Blockly.Events.fire( + new (Blockly.Events.get(Blockly.Events.BLOCK_CREATE))(newBlock) + ); } newBlock.outputConnection.connect(input.connection); } @@ -349,18 +352,17 @@ function attachShadow_(input, * @private * @this Blockly.Block */ -function createArgumentReporter_( - argumentType, displayName) { - if (argumentType == 'n' || argumentType == 's') { - var blockType = 'argument_reporter_string_number'; +function createArgumentReporter_(argumentType, displayName) { + if (argumentType == "n" || argumentType == "s") { + var blockType = "argument_reporter_string_number"; } else { - var blockType = 'argument_reporter_boolean'; + var blockType = "argument_reporter_boolean"; } Blockly.Events.disable(); try { var newBlock = this.workspace.newBlock(blockType); newBlock.setShadow(true); - newBlock.setFieldValue(displayName, 'VALUE'); + newBlock.setFieldValue(displayName, "VALUE"); if (!this.isInsertionMarker()) { newBlock.initSvg(); newBlock.render(false); @@ -369,7 +371,9 @@ function createArgumentReporter_( Blockly.Events.enable(); } if (Blockly.Events.isEnabled()) { - Blockly.Events.fire(new (Blockly.Events.get(Blockly.Events.BLOCK_CREATE))(newBlock)); + Blockly.Events.fire( + new (Blockly.Events.get(Blockly.Events.BLOCK_CREATE))(newBlock) + ); } return newBlock; } @@ -386,21 +390,20 @@ function createArgumentReporter_( * @private * @this Blockly.Block */ -function populateArgumentOnCaller_(type, - index, connectionMap, id, input) { +function populateArgumentOnCaller_(type, index, connectionMap, id, input) { var oldBlock = null; var oldShadow = null; - if (connectionMap && (id in connectionMap)) { + if (connectionMap && id in connectionMap) { var saveInfo = connectionMap[id]; - oldBlock = saveInfo['block']; - oldShadow = saveInfo['shadow']; + oldBlock = saveInfo["block"]; + oldShadow = saveInfo["shadow"]; } if (connectionMap && oldBlock) { // Reattach the old block and shadow DOM. connectionMap[input.name] = null; oldBlock.outputConnection.connect(input.connection); - if (type != 'b' && this.generateShadows_) { + if (type != "b" && this.generateShadows_) { var shadowDom = oldShadow || this.buildShadowDom_(type); console.log("setting shadow dom: " + shadowDom); input.connection.setShadowDom(shadowDom); @@ -423,12 +426,11 @@ function populateArgumentOnCaller_(type, * @private * @this Blockly.Block */ -function populateArgumentOnPrototype_( - type, index, connectionMap, id, input) { +function populateArgumentOnPrototype_(type, index, connectionMap, id, input) { var oldBlock = null; - if (connectionMap && (id in connectionMap)) { + if (connectionMap && id in connectionMap) { var saveInfo = connectionMap[id]; - oldBlock = saveInfo['block']; + oldBlock = saveInfo["block"]; } var oldTypeMatches = checkOldTypeMatches_(oldBlock, type); @@ -439,7 +441,7 @@ function populateArgumentOnPrototype_( // Update the text if needed. The old argument reporter is the same type, // and on the same input, but the argument's display name may have changed. var argumentReporter = oldBlock; - argumentReporter.setFieldValue(displayName, 'VALUE'); + argumentReporter.setFieldValue(displayName, "VALUE"); connectionMap[input.name] = null; } else { var argumentReporter = this.createArgumentReporter_(type, displayName); @@ -462,13 +464,11 @@ function populateArgumentOnPrototype_( * @private * @this Blockly.Block */ -function populateArgumentOnDeclaration_( - type, index, connectionMap, id, input) { - +function populateArgumentOnDeclaration_(type, index, connectionMap, id, input) { var oldBlock = null; - if (connectionMap && (id in connectionMap)) { + if (connectionMap && id in connectionMap) { var saveInfo = connectionMap[id]; - oldBlock = saveInfo['block']; + oldBlock = saveInfo["block"]; } // TODO: This always returns false, because it checks for argument reporter @@ -480,7 +480,7 @@ function populateArgumentOnDeclaration_( // Decide which block to attach. if (oldBlock && oldTypeMatches) { var argumentEditor = oldBlock; - oldBlock.setFieldValue(displayName, 'TEXT'); + oldBlock.setFieldValue(displayName, "TEXT"); connectionMap[input.name] = null; } else { var argumentEditor = this.createArgumentEditor_(type, displayName); @@ -497,16 +497,17 @@ function populateArgumentOnDeclaration_( * @param {string} type The argument type. One of 'n', 'n', or 's'. * @return {boolean} True if the type matches, false otherwise. */ -function checkOldTypeMatches_(oldBlock, - type) { +function checkOldTypeMatches_(oldBlock, type) { if (!oldBlock) { return false; } - if ((type == 'n' || type == 's') && - oldBlock.type == 'argument_reporter_string_number') { + if ( + (type == "n" || type == "s") && + oldBlock.type == "argument_reporter_string_number" + ) { return true; } - if (type == 'b' && oldBlock.type == 'argument_reporter_boolean') { + if (type == "b" && oldBlock.type == "argument_reporter_boolean") { return true; } return false; @@ -524,16 +525,15 @@ function checkOldTypeMatches_(oldBlock, * @private * @this Blockly.Block */ -function createArgumentEditor_( - argumentType, displayName) { +function createArgumentEditor_(argumentType, displayName) { Blockly.Events.disable(); try { - if (argumentType == 'n' || argumentType == 's') { - var newBlock = this.workspace.newBlock('argument_editor_string_number'); + if (argumentType == "n" || argumentType == "s") { + var newBlock = this.workspace.newBlock("argument_editor_string_number"); } else { - var newBlock = this.workspace.newBlock('argument_editor_boolean'); + var newBlock = this.workspace.newBlock("argument_editor_boolean"); } - newBlock.setFieldValue(displayName, 'TEXT'); + newBlock.setFieldValue(displayName, "TEXT"); newBlock.setShadow(true); if (!this.isInsertionMarker()) { newBlock.initSvg(); @@ -543,7 +543,9 @@ function createArgumentEditor_( Blockly.Events.enable(); } if (Blockly.Events.isEnabled()) { - Blockly.Events.fire(new (Blockly.Events.get(Blockly.Events.BLOCK_CREATE))(newBlock)); + Blockly.Events.fire( + new (Blockly.Events.get(Blockly.Events.BLOCK_CREATE))(newBlock) + ); } return newBlock; } @@ -553,12 +555,12 @@ function createArgumentEditor_( * and their text. */ function updateDeclarationProcCode_() { - this.procCode_ = ''; + this.procCode_ = ""; this.displayNames_ = []; this.argumentIds_ = []; for (var i = 0; i < this.inputList.length; i++) { if (i != 0) { - this.procCode_ += ' '; + this.procCode_ += " "; } var input = this.inputList[i]; if (input.type == Blockly.inputs.inputTypes.DUMMY) { @@ -566,16 +568,17 @@ function updateDeclarationProcCode_() { } else if (input.type == Blockly.inputs.inputTypes.VALUE) { // Inspect the argument editor. var target = input.connection.targetBlock(); - this.displayNames_.push(target.getFieldValue('TEXT')); + this.displayNames_.push(target.getFieldValue("TEXT")); this.argumentIds_.push(input.name); - if (target.type == 'argument_editor_boolean') { - this.procCode_ += '%b'; + if (target.type == "argument_editor_boolean") { + this.procCode_ += "%b"; } else { - this.procCode_ += '%s'; + this.procCode_ += "%s"; } } else { throw new Error( - 'Unexpected input type on a procedure mutator root: ' + input.type); + "Unexpected input type on a procedure mutator root: " + input.type + ); } } } @@ -592,7 +595,7 @@ function focusLastEditor_() { } else if (newInput.type == Blockly.inputs.inputTypes.VALUE) { // Inspect the argument editor. var target = newInput.connection.targetBlock(); - target.getField('TEXT').showEditor_(); + target.getField("TEXT").showEditor_(); } } } @@ -603,7 +606,7 @@ function focusLastEditor_() { */ function addLabelExternal() { Blockly.WidgetDiv.hide(true); - this.procCode_ = this.procCode_ + ' label text'; + this.procCode_ = this.procCode_ + " label text"; this.updateDisplay_(); this.focusLastEditor_(); } @@ -615,10 +618,10 @@ function addLabelExternal() { */ function addBooleanExternal() { Blockly.WidgetDiv.hide(true); - this.procCode_ = this.procCode_ + ' %b'; - this.displayNames_.push('boolean'); + this.procCode_ = this.procCode_ + " %b"; + this.displayNames_.push("boolean"); this.argumentIds_.push(Blockly.utils.idGenerator.genUid()); - this.argumentDefaults_.push('false'); + this.argumentDefaults_.push("false"); this.updateDisplay_(); this.focusLastEditor_(); } @@ -630,10 +633,10 @@ function addBooleanExternal() { */ function addStringNumberExternal() { Blockly.WidgetDiv.hide(true); - this.procCode_ = this.procCode_ + ' %s'; - this.displayNames_.push('number or text'); + this.procCode_ = this.procCode_ + " %s"; + this.displayNames_.push("number or text"); this.argumentIds_.push(Blockly.utils.idGenerator.genUid()); - this.argumentDefaults_.push(''); + this.argumentDefaults_.push(""); this.updateDisplay_(); this.focusLastEditor_(); } @@ -695,8 +698,7 @@ function removeFieldCallback(field) { * @param {Blockly.Field} field The field being removed. * @public */ -function removeArgumentCallback_( - field) { +function removeArgumentCallback_(field) { if (this.parentBlock_ && this.parentBlock_.removeFieldCallback) { this.parentBlock_.removeFieldCallback(field); } @@ -725,16 +727,19 @@ function updateArgumentReporterNames_(prevArgIds, prevDisplayNames) { var allBlocks = definitionBlock.getDescendants(false); for (var i = 0; i < allBlocks.length; i++) { var block = allBlocks[i]; - if ((block.type === 'argument_reporter_string_number' || - block.type === 'argument_reporter_boolean') && - !block.isShadow()) { // Exclude arg reporters in the prototype block, which are shadows. + if ( + (block.type === "argument_reporter_string_number" || + block.type === "argument_reporter_boolean") && + !block.isShadow() + ) { + // Exclude arg reporters in the prototype block, which are shadows. argReporters.push(block); } } // Create a list of "name changes", including the new name and blocks matching the old name // Only search over the current set of argument ids, ignore args that have been removed - for (var i = 0, id; id = this.argumentIds_[i]; i++) { + for (var i = 0, id; (id = this.argumentIds_[i]); i++) { // Find the previous index of this argument id. Could be -1 if it is newly added. var prevIndex = prevArgIds.indexOf(id); if (prevIndex == -1) continue; // Newly added argument, no corresponding previous argument to update. @@ -742,51 +747,55 @@ function updateArgumentReporterNames_(prevArgIds, prevDisplayNames) { if (prevName != this.displayNames_[i]) { nameChanges.push({ newName: this.displayNames_[i], - blocks: argReporters.filter(function(block) { - return block.getFieldValue('VALUE') == prevName; - }) + blocks: argReporters.filter(function (block) { + return block.getFieldValue("VALUE") == prevName; + }), }); } } // Finally update the blocks for each name change. // Do this after creating the lists to avoid cycles of renaming. - for (var j = 0, nameChange; nameChange = nameChanges[j]; j++) { - for (var k = 0, block; block = nameChange.blocks[k]; k++) { - block.setFieldValue(nameChange.newName, 'VALUE'); + for (var j = 0, nameChange; (nameChange = nameChanges[j]); j++) { + for (var k = 0, block; (block = nameChange.blocks[k]); k++) { + block.setFieldValue(nameChange.newName, "VALUE"); } } } -Blockly.Blocks['procedures_definition'] = { +Blockly.Blocks["procedures_definition"] = { /** * Block for defining a procedure with no return value. * @this Blockly.Block */ - init: function() { + init: function () { this.jsonInit({ - "message0": Blockly.Msg.PROCEDURES_DEFINITION, - "args0": [ + message0: Blockly.Msg.PROCEDURES_DEFINITION, + args0: [ { - "type": "input_statement", - "name": "custom_block" - } + type: "input_statement", + name: "custom_block", + }, ], - "extensions": ["colours_more", "shape_hat", "procedure_def_contextmenu"] + extensions: ["colours_more", "shape_hat", "procedure_def_contextmenu"], }); - } + }, }; -Blockly.Blocks['procedures_call'] = { +Blockly.Blocks["procedures_call"] = { /** * Block for calling a procedure with no return value. * @this Blockly.Block */ - init: function() { + init: function () { this.jsonInit({ - "extensions": ["colours_more", "shape_statement", "procedure_call_contextmenu"] + extensions: [ + "colours_more", + "shape_statement", + "procedure_call_contextmenu", + ], }); - this.procCode_ = ''; + this.procCode_ = ""; this.argumentIds_ = []; this.warp_ = false; @@ -810,19 +819,19 @@ Blockly.Blocks['procedures_call'] = { }, }; -Blockly.Blocks['procedures_prototype'] = { +Blockly.Blocks["procedures_prototype"] = { /** * Block for calling a procedure with no return value, for rendering inside * define block. * @this Blockly.Block */ - init: function() { + init: function () { this.jsonInit({ - "extensions": ["colours_more", "shape_statement"] + extensions: ["colours_more", "shape_statement"], }); /* Data known about the procedure. */ - this.procCode_ = ''; + this.procCode_ = ""; this.displayNames_ = []; this.argumentIds_ = []; this.argumentDefaults_ = []; @@ -847,17 +856,17 @@ Blockly.Blocks['procedures_prototype'] = { }, }; -Blockly.Blocks['procedures_declaration'] = { +Blockly.Blocks["procedures_declaration"] = { /** * The root block in the procedure declaration editor. * @this Blockly.Block */ - init: function() { + init: function () { this.jsonInit({ - "extensions": ["colours_more", "shape_statement"] + extensions: ["colours_more", "shape_statement"], }); /* Data known about the procedure. */ - this.procCode_ = ''; + this.procCode_ = ""; this.displayNames_ = []; this.argumentIds_ = []; this.argumentDefaults_ = []; @@ -892,51 +901,54 @@ Blockly.Blocks['procedures_declaration'] = { }, }; -Blockly.Blocks['argument_reporter_boolean'] = { - init: function() { - this.jsonInit({ "message0": " %1", - "args0": [ +Blockly.Blocks["argument_reporter_boolean"] = { + init: function () { + this.jsonInit({ + message0: " %1", + args0: [ { - "type": "field_label_serializable", - "name": "VALUE", - "text": "" - } + type: "field_label_serializable", + name: "VALUE", + text: "", + }, ], - "extensions": ["colours_more", "output_boolean"] + extensions: ["colours_more", "output_boolean"], }); - } + }, }; -Blockly.Blocks['argument_reporter_string_number'] = { - init: function() { - this.jsonInit({ "message0": " %1", - "args0": [ +Blockly.Blocks["argument_reporter_string_number"] = { + init: function () { + this.jsonInit({ + message0: " %1", + args0: [ { - "type": "field_label_serializable", - "name": "VALUE", - "text": "" - } + type: "field_label_serializable", + name: "VALUE", + text: "", + }, ], - "extensions": ["colours_more", "output_number", "output_string"] + extensions: ["colours_more", "output_number", "output_string"], }); - } + }, }; -Blockly.Blocks['argument_editor_boolean'] = { - init: function() { - this.jsonInit({ "message0": " %1", - "args0": [ +Blockly.Blocks["argument_editor_boolean"] = { + init: function () { + this.jsonInit({ + message0: " %1", + args0: [ { - "type": "field_input_removable", - "name": "TEXT", - "text": "foo" - } + type: "field_input_removable", + name: "TEXT", + text: "foo", + }, ], - "colour": Colours.textField, - "colourSecondary": Colours.textField, - "colourTertiary": Colours.textField, - "colourQuaternary": Colours.textField, - "extensions": ["output_boolean"] + colour: Colours.textField, + colourSecondary: Colours.textField, + colourTertiary: Colours.textField, + colourQuaternary: Colours.textField, + extensions: ["output_boolean"], }); // Exist on declaration and arguments editors, with different implementations. @@ -944,21 +956,22 @@ Blockly.Blocks['argument_editor_boolean'] = { }, }; -Blockly.Blocks['argument_editor_string_number'] = { - init: function() { - this.jsonInit({ "message0": " %1", - "args0": [ +Blockly.Blocks["argument_editor_string_number"] = { + init: function () { + this.jsonInit({ + message0: " %1", + args0: [ { - "type": "field_input_removable", - "name": "TEXT", - "text": "foo" - } + type: "field_input_removable", + name: "TEXT", + text: "foo", + }, ], - "colour": Colours.textField, - "colourSecondary": Colours.textField, - "colourTertiary": Colours.textField, - "colourQuaternary": Colours.textField, - "extensions": ["output_number", "output_string"] + colour: Colours.textField, + colourSecondary: Colours.textField, + colourTertiary: Colours.textField, + colourQuaternary: Colours.textField, + extensions: ["output_number", "output_string"], }); // Exist on declaration and arguments editors, with different implementations. From 4cfe66fa0419e6140ff6f7cad1c1bfc884917a72 Mon Sep 17 00:00:00 2001 From: Aaron Dodson Date: Mon, 5 Aug 2024 13:32:31 -0700 Subject: [PATCH 053/130] fix: allow specifying the function to be used for prompting about variable creation/edits (#106) --- src/variables.js | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/variables.js b/src/variables.js index a171730293..7fac2359aa 100644 --- a/src/variables.js +++ b/src/variables.js @@ -37,6 +37,12 @@ import { */ const CLOUD_PREFIX = "☁ "; +let prompt = null; + +export function setPromptHandler(handler) { + prompt = handler; +} + /** * Create a new variable on the given workspace. * @param {!Blockly.Workspace} workspace The workspace on which to create the @@ -70,7 +76,7 @@ export function createVariable(workspace, opt_callback, opt_type) { var validate = nameValidator.bind(null, opt_type); // Prompt the user to enter a name for the variable - Blockly.dialog.prompt( + prompt( newMsg, "", function (text, additionalVars, variableOptions) { @@ -309,7 +315,7 @@ export function renameVariable(workspace, variable, opt_callback) { promptDefaultText = promptDefaultText.substring(CLOUD_PREFIX.length); } - Blockly.dialog.prompt( + prompt( promptText, promptDefaultText, function (newName, additionalVars) { From 936967b06e6a90b9a3efd28d824394fee752a705 Mon Sep 17 00:00:00 2001 From: Aaron Dodson Date: Tue, 6 Aug 2024 09:40:28 -0700 Subject: [PATCH 054/130] refactor: enforce procedure deletion validation (#107) * chore: format vertical_extensions.js * chore: format procedures.js * refactor: enforce procedure deletion validation --- blocks_vertical/vertical_extensions.js | 176 +++++++++++++++---------- src/procedures.js | 174 +++++++++++++----------- 2 files changed, 197 insertions(+), 153 deletions(-) diff --git a/blocks_vertical/vertical_extensions.js b/blocks_vertical/vertical_extensions.js index 54378d5e46..992623f5aa 100644 --- a/blocks_vertical/vertical_extensions.js +++ b/blocks_vertical/vertical_extensions.js @@ -25,9 +25,9 @@ * would have the "colours_operators" and "output_number" extensions. * @author fenichel@google.com (Rachel Fenichel) */ -import * as Blockly from 'blockly/core'; -import {Colours} from '../core/colours.js'; -import {ScratchProcedures} from '../src/procedures.js'; +import * as Blockly from "blockly/core"; +import { Colours } from "../core/colours.js"; +import { ScratchProcedures } from "../src/procedures.js"; const VerticalExtensions = {}; /** @@ -38,10 +38,17 @@ const VerticalExtensions = {}; * @return {function} An extension function that sets colours based on the given * category. */ -VerticalExtensions.colourHelper = function(category) { +VerticalExtensions.colourHelper = function (category) { var colours = Colours[category]; - if (!(colours && colours.primary && colours.secondary && colours.tertiary && - colours.quaternary)) { + if ( + !( + colours && + colours.primary && + colours.secondary && + colours.tertiary && + colours.quaternary + ) + ) { throw new Error('Could not find colours for category "' + category + '"'); } /** @@ -49,7 +56,7 @@ VerticalExtensions.colourHelper = function(category) { * the given category. * @this {Blockly.Block} */ - return function() { + return function () { this.setColour(colours.primary); // this.setColourFromRawValues_(colours.primary, colours.secondary, // colours.tertiary, colours.quaternary); @@ -59,7 +66,7 @@ VerticalExtensions.colourHelper = function(category) { /** * Extension to set the colours of a text field, which are all the same. */ -VerticalExtensions.COLOUR_TEXTFIELD = function() { +VerticalExtensions.COLOUR_TEXTFIELD = function () { this.setColour(colours.textField); // this.setColourFromRawValues_(Colours.textField, // Colours.textField, Colours.textField, @@ -73,7 +80,7 @@ VerticalExtensions.COLOUR_TEXTFIELD = function() { * @this {Blockly.Block} * @readonly */ -VerticalExtensions.SHAPE_STATEMENT = function() { +VerticalExtensions.SHAPE_STATEMENT = function () { this.setInputsInline(true); this.setPreviousStatement(true, null); this.setNextStatement(true, null); @@ -86,7 +93,7 @@ VerticalExtensions.SHAPE_STATEMENT = function() { * @this {Blockly.Block} * @readonly */ -VerticalExtensions.SHAPE_HAT = function() { +VerticalExtensions.SHAPE_HAT = function () { this.setInputsInline(true); this.setNextStatement(true, null); }; @@ -98,7 +105,7 @@ VerticalExtensions.SHAPE_HAT = function() { * @this {Blockly.Block} * @readonly */ -VerticalExtensions.SHAPE_END = function() { +VerticalExtensions.SHAPE_END = function () { this.setInputsInline(true); this.setPreviousStatement(true, null); }; @@ -110,10 +117,10 @@ VerticalExtensions.SHAPE_END = function() { * @this {Blockly.Block} * @readonly */ -VerticalExtensions.OUTPUT_NUMBER = function() { +VerticalExtensions.OUTPUT_NUMBER = function () { this.setInputsInline(true); this.setOutputShape(Blockly.OUTPUT_SHAPE_ROUND); - this.setOutput(true, 'Number'); + this.setOutput(true, "Number"); }; /** @@ -123,10 +130,10 @@ VerticalExtensions.OUTPUT_NUMBER = function() { * @this {Blockly.Block} * @readonly */ -VerticalExtensions.OUTPUT_STRING = function() { +VerticalExtensions.OUTPUT_STRING = function () { this.setInputsInline(true); this.setOutputShape(Blockly.OUTPUT_SHAPE_ROUND); - this.setOutput(true, 'String'); + this.setOutput(true, "String"); }; /** @@ -136,10 +143,10 @@ VerticalExtensions.OUTPUT_STRING = function() { * @this {Blockly.Block} * @readonly */ -VerticalExtensions.OUTPUT_BOOLEAN = function() { +VerticalExtensions.OUTPUT_BOOLEAN = function () { this.setInputsInline(true); this.setOutputShape(Blockly.OUTPUT_SHAPE_HEXAGONAL); - this.setOutput(true, 'Boolean'); + this.setOutput(true, "Boolean"); }; /** @@ -150,46 +157,44 @@ VerticalExtensions.OUTPUT_BOOLEAN = function() { * @package * @readonly */ -VerticalExtensions.PROCEDURE_DEF_CONTEXTMENU = { +VerticalExtensions.PROCEDURE_DEF_CONTEXTMENU = function () { /** * Add the "edit" option and removes the "duplicate" option from the context * menu. * @param {!Array.} menuOptions List of menu options to edit. * @this Blockly.Block */ - customContextMenu: function(menuOptions) { - // Add the edit option at the end. - menuOptions.push(ScratchProcedures.makeEditOption(this)); + this.mixin( + { + customContextMenu: function (menuOptions) { + // Add the edit option at the end. + menuOptions.push(ScratchProcedures.makeEditOption(this)); - // Find the delete option and update its callback to be specific to - // functions. - for (var i = 0, option; option = menuOptions[i]; i++) { - if (option.text == Blockly.Msg.DELETE_BLOCK) { - var input = this.getInput('custom_block'); + // Find and remove the duplicate option + for (var i = 0, option; (option = menuOptions[i]); i++) { + if (option.text == Blockly.Msg.DUPLICATE) { + menuOptions.splice(i, 1); + break; + } + } + }, + checkAndDelete: function () { + var input = this.getInput("custom_block"); // this is the root block, not the shadow block. if (input && input.connection && input.connection.targetBlock()) { var procCode = input.connection.targetBlock().getProcCode(); - } else { - return; - } - var rootBlock = this; - option.callback = function() { var didDelete = ScratchProcedures.deleteProcedureDefCallback( - procCode, rootBlock); + procCode, + this + ); if (!didDelete) { alert(Blockly.Msg.PROCEDURE_USED); } - }; - } - } - // Find and remove the duplicate option - for (var i = 0, option; option = menuOptions[i]; i++) { - if (option.text == Blockly.Msg.DUPLICATE) { - menuOptions.splice(i, 1); - break; - } - } - } + } + }, + }, + true + ); }; /** @@ -207,59 +212,84 @@ VerticalExtensions.PROCEDURE_CALL_CONTEXTMENU = { * @param {!Array.} menuOptions List of menu options to edit. * @this Blockly.Block */ - customContextMenu: function(menuOptions) { + customContextMenu: function (menuOptions) { menuOptions.push(ScratchProcedures.makeEditOption(this)); - } + }, }; - -VerticalExtensions.SCRATCH_EXTENSION = function() { +VerticalExtensions.SCRATCH_EXTENSION = function () { this.isScratchExtension = true; }; /** * Register all extensions for scratch-blocks. * @package */ -VerticalExtensions.registerAll = function() { - var categoryNames = - ['control', 'data', 'data_lists', 'sounds', 'motion', 'looks', 'event', - 'sensing', 'pen', 'operators', 'more']; +VerticalExtensions.registerAll = function () { + var categoryNames = [ + "control", + "data", + "data_lists", + "sounds", + "motion", + "looks", + "event", + "sensing", + "pen", + "operators", + "more", + ]; // Register functions for all category colours. for (var i = 0; i < categoryNames.length; i++) { var name = categoryNames[i]; - Blockly.Extensions.register('colours_' + name, - VerticalExtensions.colourHelper(name)); + Blockly.Extensions.register( + "colours_" + name, + VerticalExtensions.colourHelper(name) + ); } // Text fields transcend categories. - Blockly.Extensions.register('colours_textfield', - VerticalExtensions.COLOUR_TEXTFIELD); + Blockly.Extensions.register( + "colours_textfield", + VerticalExtensions.COLOUR_TEXTFIELD + ); // Register extensions for common block shapes. - Blockly.Extensions.register('shape_statement', - VerticalExtensions.SHAPE_STATEMENT); - Blockly.Extensions.register('shape_hat', - VerticalExtensions.SHAPE_HAT); - Blockly.Extensions.register('shape_end', - VerticalExtensions.SHAPE_END); + Blockly.Extensions.register( + "shape_statement", + VerticalExtensions.SHAPE_STATEMENT + ); + Blockly.Extensions.register("shape_hat", VerticalExtensions.SHAPE_HAT); + Blockly.Extensions.register("shape_end", VerticalExtensions.SHAPE_END); // Output shapes and types are related. - Blockly.Extensions.register('output_number', - VerticalExtensions.OUTPUT_NUMBER); - Blockly.Extensions.register('output_string', - VerticalExtensions.OUTPUT_STRING); - Blockly.Extensions.register('output_boolean', - VerticalExtensions.OUTPUT_BOOLEAN); + Blockly.Extensions.register( + "output_number", + VerticalExtensions.OUTPUT_NUMBER + ); + Blockly.Extensions.register( + "output_string", + VerticalExtensions.OUTPUT_STRING + ); + Blockly.Extensions.register( + "output_boolean", + VerticalExtensions.OUTPUT_BOOLEAN + ); // Custom procedures have interesting context menus. - Blockly.Extensions.registerMixin('procedure_def_contextmenu', - VerticalExtensions.PROCEDURE_DEF_CONTEXTMENU); - Blockly.Extensions.registerMixin('procedure_call_contextmenu', - VerticalExtensions.PROCEDURE_CALL_CONTEXTMENU); + Blockly.Extensions.register( + "procedure_def_contextmenu", + VerticalExtensions.PROCEDURE_DEF_CONTEXTMENU + ); + Blockly.Extensions.registerMixin( + "procedure_call_contextmenu", + VerticalExtensions.PROCEDURE_CALL_CONTEXTMENU + ); // Extension blocks have slightly different block rendering. - Blockly.Extensions.register('scratch_extension', - VerticalExtensions.SCRATCH_EXTENSION); + Blockly.Extensions.register( + "scratch_extension", + VerticalExtensions.SCRATCH_EXTENSION + ); }; VerticalExtensions.registerAll(); diff --git a/src/procedures.js b/src/procedures.js index bc1c76c3b5..09f1381f2c 100644 --- a/src/procedures.js +++ b/src/procedures.js @@ -23,9 +23,9 @@ * @author fraser@google.com (Neil Fraser) */ -import * as Blockly from 'blockly/core'; -import * as Constants from './constants.js'; -import * as scratchBlocksUtils from '../core/scratch_blocks_utils.js'; +import * as Blockly from "blockly/core"; +import * as Constants from "./constants.js"; +import * as scratchBlocksUtils from "../core/scratch_blocks_utils.js"; /** * Find all user-created procedure definition mutations in a workspace. @@ -57,9 +57,9 @@ function allProcedureMutations(root) { function sortProcedureMutations_(mutations) { var newMutations = mutations.slice(); - newMutations.sort(function(a, b) { - var procCodeA = a.getAttribute('proccode'); - var procCodeB = b.getAttribute('proccode'); + newMutations.sort(function (a, b) { + var procCodeA = a.getAttribute("proccode"); + var procCodeB = b.getAttribute("proccode"); return scratchBlocksUtils.compareStrings(procCodeA, procCodeB); }); @@ -85,9 +85,9 @@ function getProceduresCategory(workspace) { // // // - var block = document.createElement('block'); - block.setAttribute('type', 'procedures_call'); - block.setAttribute('gap', 16); + var block = document.createElement("block"); + block.setAttribute("type", "procedures_call"); + block.setAttribute("gap", 16); block.appendChild(mutation); xmlList.push(block); } @@ -101,14 +101,14 @@ function getProceduresCategory(workspace) { * @private */ function addCreateButton_(workspace, xmlList) { - var button = document.createElement('button'); + var button = document.createElement("button"); var msg = Blockly.Msg.NEW_PROCEDURE; - var callbackKey = 'CREATE_PROCEDURE'; - var callback = function() { + var callbackKey = "CREATE_PROCEDURE"; + var callback = function () { createProcedureDefCallback(workspace); }; - button.setAttribute('text', msg); - button.setAttribute('callbackKey', callbackKey); + button.setAttribute("text", msg); + button.setAttribute("callbackKey", callbackKey); workspace.registerButtonCallback(callbackKey, callback); xmlList.push(button); } @@ -125,8 +125,7 @@ function addCreateButton_(workspace, xmlList) { * @return {!Array.} Array of caller blocks. * @package */ -function getCallers(name, ws, definitionRoot, - allowRecursive) { +function getCallers(name, ws, definitionRoot, allowRecursive) { var allBlocks = []; var topBlocks = ws.getTopBlocks(); @@ -142,7 +141,7 @@ function getCallers(name, ws, definitionRoot, var callers = []; for (var i = 0; i < allBlocks.length; i++) { var block = allBlocks[i]; - if (block.type == Constants.PROCEDURES_CALL_BLOCK_TYPE ) { + if (block.type == Constants.PROCEDURES_CALL_BLOCK_TYPE) { var procCode = block.getProcCode(); if (procCode && procCode == name) { callers.push(block); @@ -163,24 +162,35 @@ function mutateCallersAndPrototype(name, ws, mutation) { var defineBlock = getDefineBlock(name, ws); var prototypeBlock = getPrototypeBlock(name, ws); if (defineBlock && prototypeBlock) { - var callers = getCallers(name, - defineBlock.workspace, defineBlock, true /* allowRecursive */); + var callers = getCallers( + name, + defineBlock.workspace, + defineBlock, + true /* allowRecursive */ + ); callers.push(prototypeBlock); Blockly.Events.setGroup(true); - for (var i = 0, caller; caller = callers[i]; i++) { + for (var i = 0, caller; (caller = callers[i]); i++) { var oldMutationDom = caller.mutationToDom(); var oldMutation = oldMutationDom && Blockly.Xml.domToText(oldMutationDom); caller.domToMutation(mutation); var newMutationDom = caller.mutationToDom(); var newMutation = newMutationDom && Blockly.Xml.domToText(newMutationDom); if (oldMutation != newMutation) { - Blockly.Events.fire(new Blockly.Events.BlockChange( - caller, 'mutation', null, oldMutation, newMutation)); + Blockly.Events.fire( + new Blockly.Events.BlockChange( + caller, + "mutation", + null, + oldMutation, + newMutation + ) + ); } } Blockly.Events.setGroup(false); } else { - alert('No define block on workspace'); // TODO decide what to do about this. + alert("No define block on workspace"); // TODO decide what to do about this. } } @@ -196,8 +206,13 @@ function getDefineBlock(procCode, workspace) { var blocks = workspace.getTopBlocks(false); for (var i = 0; i < blocks.length; i++) { if (blocks[i].type == Constants.PROCEDURES_DEFINITION_BLOCK_TYPE) { - var prototypeBlock = blocks[i].getInput('custom_block').connection.targetBlock(); - if (prototypeBlock.getProcCode && prototypeBlock.getProcCode() == procCode) { + var prototypeBlock = blocks[i] + .getInput("custom_block") + .connection.targetBlock(); + if ( + prototypeBlock.getProcCode && + prototypeBlock.getProcCode() == procCode + ) { return blocks[i]; } } @@ -215,7 +230,7 @@ function getDefineBlock(procCode, workspace) { function getPrototypeBlock(procCode, workspace) { var defineBlock = getDefineBlock(procCode, workspace); if (defineBlock) { - return defineBlock.getInput('custom_block').connection.targetBlock(); + return defineBlock.getInput("custom_block").connection.targetBlock(); } return null; } @@ -226,15 +241,18 @@ function getPrototypeBlock(procCode, workspace) { * @package */ function newProcedureMutation() { - var mutationText = '' + - '' + - '' + - ''; + var mutationText = + "" + + "' + + "" + + ""; return Blockly.utils.xml.textToDom(mutationText).firstChild; } @@ -245,8 +263,8 @@ function newProcedureMutation() { */ function createProcedureDefCallback(workspace) { ScratchProcedures.externalProcedureDefCallback( - newProcedureMutation(), - createProcedureCallbackFactory_(workspace) + newProcedureMutation(), + createProcedureCallbackFactory_(workspace) ); } @@ -257,17 +275,18 @@ function createProcedureDefCallback(workspace) { * @private */ function createProcedureCallbackFactory_(workspace) { - return function(mutation) { + return function (mutation) { if (mutation) { - var blockText = '' + - '' + - '' + - '' + - Blockly.Xml.domToText(mutation) + - '' + - '' + - '' + - ''; + var blockText = + "" + + '' + + '' + + '' + + Blockly.Xml.domToText(mutation) + + "" + + "" + + "" + + ""; var blockDom = Blockly.utils.xml.textToDom(blockText).firstChild; Blockly.Events.setGroup(true); var block = Blockly.Xml.domToBlock(blockDom, workspace); @@ -296,35 +315,37 @@ function editProcedureCallback_(block) { // Edit can come from one of three block types (call, define, prototype) // Normalize by setting the block to the prototype block for the procedure. if (block.type == Constants.PROCEDURES_DEFINITION_BLOCK_TYPE) { - var input = block.getInput('custom_block'); + var input = block.getInput("custom_block"); if (!input) { - alert('Bad input'); // TODO: Decide what to do about this. + alert("Bad input"); // TODO: Decide what to do about this. return; } var conn = input.connection; if (!conn) { - alert('Bad connection'); // TODO: Decide what to do about this. + alert("Bad connection"); // TODO: Decide what to do about this. return; } var innerBlock = conn.targetBlock(); - if (!innerBlock || - !innerBlock.type == Constants.PROCEDURES_PROTOTYPE_BLOCK_TYPE) { - alert('Bad inner block'); // TODO: Decide what to do about this. + if ( + !innerBlock || + !innerBlock.type == Constants.PROCEDURES_PROTOTYPE_BLOCK_TYPE + ) { + alert("Bad inner block"); // TODO: Decide what to do about this. return; } block = innerBlock; } else if (block.type == Constants.PROCEDURES_CALL_BLOCK_TYPE) { // This is a call block, find the prototype corresponding to the procCode. // Make sure to search the correct workspace, call block can be in flyout. - var workspaceToSearch = block.workspace.isFlyout ? - block.workspace.targetWorkspace : block.workspace; - block = getPrototypeBlock( - block.getProcCode(), workspaceToSearch); + var workspaceToSearch = block.workspace.isFlyout + ? block.workspace.targetWorkspace + : block.workspace; + block = getPrototypeBlock(block.getProcCode(), workspaceToSearch); } // Block now refers to the procedure prototype block, it is safe to proceed. ScratchProcedures.externalProcedureDefCallback( - block.mutationToDom(), - editProcedureCallbackFactory_(block) + block.mutationToDom(), + editProcedureCallbackFactory_(block) ); } @@ -335,10 +356,9 @@ function editProcedureCallback_(block) { * @private */ function editProcedureCallbackFactory_(block) { - return function(mutation) { + return function (mutation) { if (mutation) { - mutateCallersAndPrototype(block.getProcCode(), - block.workspace, mutation); + mutateCallersAndPrototype(block.getProcCode(), block.workspace, mutation); } }; } @@ -355,9 +375,9 @@ function makeEditOption(block) { var editOption = { enabled: true, text: Blockly.Msg.EDIT_PROCEDURE, - callback: function() { + callback: function () { editProcedureCallback_(block); - } + }, }; return editOption; } @@ -370,25 +390,19 @@ function makeEditOption(block) { * @return {boolean} True if the custom procedure was deleted, false otherwise. * @package */ -function deleteProcedureDefCallback(procCode, - definitionRoot) { - var callers = getCallers(procCode, - definitionRoot.workspace, definitionRoot, false /* allowRecursive */); +function deleteProcedureDefCallback(procCode, definitionRoot) { + const callers = getCallers( + procCode, + definitionRoot.workspace, + definitionRoot, + false /* allowRecursive */ + ); if (callers.length > 0) { return false; } - var workspace = definitionRoot.workspace; - - // Delete the whole stack. - Blockly.Events.setGroup(true); - definitionRoot.dispose(); - Blockly.Events.setGroup(false); - - // TODO (#1354) Update this function when '_' is removed - // Refresh toolbox, so caller doesn't appear there anymore - workspace.refreshToolboxSelection_(); - + const workspace = definitionRoot.workspace; + Blockly.BlockSvg.prototype.checkAndDelete.call(definitionRoot); return true; } @@ -399,4 +413,4 @@ const ScratchProcedures = { getProceduresCategory, makeEditOption, }; -export {ScratchProcedures}; +export { ScratchProcedures }; From 2a543f56f6d45bcc970cfe56dbfdea6ff26c833a Mon Sep 17 00:00:00 2001 From: Aaron Dodson Date: Thu, 8 Aug 2024 15:13:44 -0700 Subject: [PATCH 055/130] fix: render the procedure definition block like Scratch (#115) * fix: render the procedure definition block like Scratch * chore: add comment about cleanup opportunity * refactor: specify the theme and renderer in inject() * refactor: don't misstype the width field in BowlerHat * chore: add warning about multi-row bowler hat blocks --- blocks_vertical/procedures.js | 6 +- blocks_vertical/vertical_extensions.js | 17 +++++ src/index.js | 3 + src/renderer/bowler_hat.js | 17 +++++ src/renderer/drawer.js | 51 +++++++++++++++ src/renderer/render_info.js | 89 ++++++++++++++++++++++++++ src/renderer/renderer.js | 21 ++++++ 7 files changed, 203 insertions(+), 1 deletion(-) create mode 100644 src/renderer/bowler_hat.js create mode 100644 src/renderer/drawer.js create mode 100644 src/renderer/render_info.js create mode 100644 src/renderer/renderer.js diff --git a/blocks_vertical/procedures.js b/blocks_vertical/procedures.js index d0da81bff2..7fb54c9477 100644 --- a/blocks_vertical/procedures.js +++ b/blocks_vertical/procedures.js @@ -777,7 +777,11 @@ Blockly.Blocks["procedures_definition"] = { name: "custom_block", }, ], - extensions: ["colours_more", "shape_hat", "procedure_def_contextmenu"], + extensions: [ + "colours_more", + "shape_bowler_hat", + "procedure_def_contextmenu", + ], }); }, }; diff --git a/blocks_vertical/vertical_extensions.js b/blocks_vertical/vertical_extensions.js index 992623f5aa..89a046b9d3 100644 --- a/blocks_vertical/vertical_extensions.js +++ b/blocks_vertical/vertical_extensions.js @@ -96,6 +96,19 @@ VerticalExtensions.SHAPE_STATEMENT = function () { VerticalExtensions.SHAPE_HAT = function () { this.setInputsInline(true); this.setNextStatement(true, null); + this.hat = "cap"; +}; + +/** + * Extension to make a block be shaped as a bowler hat block, with rounded + * corners on both sides and no indentation for statement blocks. + * @this {Blockly.Block} + * @readonly + */ +VerticalExtensions.SHAPE_BOWLER_HAT = function () { + this.setInputsInline(true); + this.setNextStatement(true, null); + this.hat = "bowler"; }; /** @@ -259,6 +272,10 @@ VerticalExtensions.registerAll = function () { VerticalExtensions.SHAPE_STATEMENT ); Blockly.Extensions.register("shape_hat", VerticalExtensions.SHAPE_HAT); + Blockly.Extensions.register( + "shape_bowler_hat", + VerticalExtensions.SHAPE_BOWLER_HAT + ); Blockly.Extensions.register("shape_end", VerticalExtensions.SHAPE_END); // Output shapes and types are related. diff --git a/src/index.js b/src/index.js index 51001a69c6..4fe9ec8b27 100644 --- a/src/index.js +++ b/src/index.js @@ -26,6 +26,7 @@ import * as scratchBlocksUtils from "../core/scratch_blocks_utils.js"; import * as ScratchVariables from "./variables.js"; import "../core/css.js"; import "../core/field_vertical_separator.js"; +import "./renderer/renderer.js"; import { ContinuousToolbox, ContinuousFlyout, @@ -66,6 +67,8 @@ export { ScratchVariables }; export function inject(container, options) { Object.assign(options, { + renderer: "scratch", + theme: "zelos", plugins: { toolbox: ScratchContinuousToolbox, flyoutsVerticalToolbox: CheckableContinuousFlyout, diff --git a/src/renderer/bowler_hat.js b/src/renderer/bowler_hat.js new file mode 100644 index 0000000000..ba435cfd70 --- /dev/null +++ b/src/renderer/bowler_hat.js @@ -0,0 +1,17 @@ +/** + * @license + * Copyright 2024 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + +import * as Blockly from "blockly/core"; + +export class BowlerHat extends Blockly.blockRendering.Hat { + constructor(constants) { + super(constants); + // Calculated dynamically by computeBounds_(). + this.width = 0; + this.height = 20; + this.ascenderHeight = this.height; + } +} diff --git a/src/renderer/drawer.js b/src/renderer/drawer.js new file mode 100644 index 0000000000..90b3cf3ff4 --- /dev/null +++ b/src/renderer/drawer.js @@ -0,0 +1,51 @@ +/** + * @license + * Copyright 2024 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + +import * as Blockly from "blockly/core"; + +export class Drawer extends Blockly.zelos.Drawer { + drawStatementInput_(row) { + if (this.info_.isBowlerHatBlock()) { + // Bowler hat blocks have straight sides with no C-shape/indentation for + // statement blocks. + this.drawRightSideRow_(row); + this.positionStatementInputConnection_(row); + } else { + super.drawStatementInput_(row); + } + } + + drawRightSideRow_(row) { + if ( + this.info_.isBowlerHatBlock() && + Blockly.blockRendering.Types.isSpacer(row) + ) { + // Multi-row bowler hat blocks are not supported, this may need + // adjustment to do so. + Blockly.blockRendering.Drawer.prototype.drawRightSideRow_.call(this, row); + } else { + super.drawRightSideRow_(row); + } + } + + drawTop_() { + super.drawTop_(); + // This is a horrible hack, but the superclass' implementation of drawTop_() + // provides no way to cleanly override a hat's path without copying and + // pasting the entire implementation here. We know that there will only be + // one hat on a block, and its path is a known constant, so we just find and + // replace it with the desired bowler hat path here. + // If https://github.com/google/blockly/issues/7292 is resolved, this should + // be revisited. + if (this.info_.isBowlerHatBlock()) { + const capHatPath = this.constants_.START_HAT.path; + const bowlerHatPath = `a20,20 0 0,1 20,-20 l ${ + this.info_.width - 40 + } 0 a20,20 0 0,1 20,20`; + this.outlinePath_ = this.outlinePath_.replace(capHatPath, bowlerHatPath); + } + } +} diff --git a/src/renderer/render_info.js b/src/renderer/render_info.js new file mode 100644 index 0000000000..6ec561e6a6 --- /dev/null +++ b/src/renderer/render_info.js @@ -0,0 +1,89 @@ +/** + * @license + * Copyright 2024 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + +import * as Blockly from "blockly/core"; +import { BowlerHat } from "./bowler_hat.js"; + +export class RenderInfo extends Blockly.zelos.RenderInfo { + populateTopRow_() { + if (this.isBowlerHatBlock()) { + const bowlerHat = new BowlerHat(this.constants_); + this.topRow.elements.push( + new Blockly.blockRendering.SquareCorner(this.constants_) + ); + this.topRow.elements.push(bowlerHat); + this.topRow.elements.push( + new Blockly.blockRendering.SquareCorner(this.constants_) + ); + this.topRow.minHeight = 0; + this.topRow.capline = bowlerHat.ascenderHeight; + } else { + super.populateTopRow_(); + } + } + + populateBottomRow_() { + super.populateBottomRow_(); + if (this.isBowlerHatBlock()) { + this.bottomRow.minHeight = this.constants_.MEDIUM_PADDING; + } + } + + computeBounds_() { + super.computeBounds_(); + if (this.isBowlerHatBlock()) { + // Resize the render info to the same width as the widest part of a + // bowler hat block. + const statementRow = this.rows.find((r) => r.hasStatement); + this.width = + statementRow.widthWithConnectedBlocks - + statementRow.elements.find((e) => + Blockly.blockRendering.Types.isInput(e) + ).width + + this.constants_.MEDIUM_PADDING; + + // The bowler hat's width is the same as the block's width, so it can't + // be derived from the constants like a normal hat and has to be set here. + const hat = this.topRow.elements.find((e) => + Blockly.blockRendering.Types.isHat(e) + ); + hat.width = this.width; + this.topRow.measure(true); + } + } + + getInRowSpacing_(prev, next) { + if ( + this.isBowlerHatBlock() && + ((prev && Blockly.blockRendering.Types.isHat(prev)) || + (next && Blockly.blockRendering.Types.isHat(next))) + ) { + // Bowler hat rows have no spacing/gaps, just the hat. + return 0; + } + + return super.getInRowSpacing_(prev, next); + } + + getSpacerRowHeight_(prev, next) { + if (this.isBowlerHatBlock() && prev === this.topRow) { + return 0; + } + + return super.getSpacerRowHeight_(prev, next); + } + + getElemCenterline_(row, elem) { + if (this.isBowlerHatBlock() && Blockly.blockRendering.Types.isField(elem)) { + return row.yPos + elem.height; + } + return super.getElemCenterline_(row, elem); + } + + isBowlerHatBlock() { + return this.block_.hat === "bowler"; + } +} diff --git a/src/renderer/renderer.js b/src/renderer/renderer.js new file mode 100644 index 0000000000..53f6a775bd --- /dev/null +++ b/src/renderer/renderer.js @@ -0,0 +1,21 @@ +/** + * @license + * Copyright 2024 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + +import * as Blockly from "blockly/core"; +import { Drawer } from "./drawer.js"; +import { RenderInfo } from "./render_info.js"; + +export class ScratchRenderer extends Blockly.zelos.Renderer { + makeDrawer_(block, info) { + return new Drawer(block, info); + } + + makeRenderInfo_(block) { + return new RenderInfo(this, block); + } +} + +Blockly.blockRendering.register("scratch", ScratchRenderer); From 4b74d5ca4ffaf7dfd7c040bce5cfd725c96d848a Mon Sep 17 00:00:00 2001 From: Aaron Dodson Date: Fri, 9 Aug 2024 09:15:45 -0700 Subject: [PATCH 056/130] fix: resolve various UI issues (#117) * chore: format checkable_continuous_flyout.js * fix: adjust flyout layout constants * fix: align block connection highlights with Scratch * fix: fix various CSS issues --- core/css.js | 33 ++++-- src/checkable_continuous_flyout.js | 166 +++++++++++++++++++---------- src/renderer/constants.js | 11 ++ src/renderer/renderer.js | 9 ++ 4 files changed, 157 insertions(+), 62 deletions(-) create mode 100644 src/renderer/constants.js diff --git a/core/css.js b/core/css.js index 39dfa07ebe..4b6b253161 100644 --- a/core/css.js +++ b/core/css.js @@ -17,7 +17,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import * as Blockly from 'blockly/core'; +import * as Blockly from "blockly/core"; const styles = ` .blocklySvg { @@ -411,18 +411,19 @@ const styles = ` cursor: pointer; } - .zelos-renderer.scratch-theme .blocklyFlyoutLabelText { + .scratch-renderer.zelos-theme .blocklyFlyoutLabelText { font-family: "Helvetica Neue", Helvetica, sans-serif; font-size: 14pt; fill: #575E75; font-weight: bold; } - .zelos-renderer.scratch-theme .blocklyText { + .scratch-renderer.zelos-theme .blocklyText, + .scratch-renderer.zelos-theme .blocklyHtmlInput { font-weight: 500; } - .zelos-renderer.scratch-theme .blocklyFlyoutButton .blocklyText { + .scratch-renderer.zelos-theme .blocklyFlyoutButton .blocklyText { fill: var(--colour-textFieldText); } @@ -850,7 +851,7 @@ const styles = ` cursor: url("<<>>/handdelete.cur"), auto; } - .blocklyTreeSelected { + .blocklyToolboxSelected { background-color: var(--colour-toolboxSelected); } @@ -1319,7 +1320,7 @@ const styles = ` transform: rotate(-180deg); } - .zelos-renderer.scratch-theme .blocklyComment .blocklyTextarea { + .scratch-renderer.zelos-theme .blocklyComment .blocklyTextarea { border: none; --commentFillColour: #fef49c; font-size: 12pt; @@ -1328,10 +1329,28 @@ const styles = ` color: #575e75; } - .zelos-renderer.scratch-theme .blocklyCommentText.blocklyText { + .scratch-renderer.zelos-theme .blocklyCommentText.blocklyText { font-weight: 400; } + .blocklyToolboxCategory { + height: auto; + line-height: auto; + margin-bottom: 0; + padding: 0.375rem 0px; + cursor: pointer; + } + .blocklyToolboxCategory:hover { + color: #4c97ff; + } + .blocklyDropDownDiv .blocklyMenuItem { + color: #fff; + font-weight: bold; + } + .blocklyToolboxSelected .blocklyTreeLabel { + color: var(--colour-toolboxText); + } + .blocklyDeleteIcon { display: block; width: 32px; diff --git a/src/checkable_continuous_flyout.js b/src/checkable_continuous_flyout.js index f14d9047d9..7d0cf6130a 100644 --- a/src/checkable_continuous_flyout.js +++ b/src/checkable_continuous_flyout.js @@ -1,5 +1,5 @@ -import * as Blockly from 'blockly'; -import {ContinuousFlyout} from '@blockly/continuous-toolbox'; +import * as Blockly from "blockly"; +import { ContinuousFlyout } from "@blockly/continuous-toolbox"; export class CheckableContinuousFlyout extends ContinuousFlyout { /** @@ -22,12 +22,18 @@ export class CheckableContinuousFlyout extends ContinuousFlyout { * @const */ static CHECKMARK_PATH = - 'M' + CheckableContinuousFlyout.CHECKBOX_SIZE / 4 + - ' ' + CheckableContinuousFlyout.CHECKBOX_SIZE / 2 + - 'L' + 5 * CheckableContinuousFlyout.CHECKBOX_SIZE / 12 + - ' ' + 2 * CheckableContinuousFlyout.CHECKBOX_SIZE / 3 + - 'L' + 3 * CheckableContinuousFlyout.CHECKBOX_SIZE / 4 + - ' ' + CheckableContinuousFlyout.CHECKBOX_SIZE / 3; + "M" + + CheckableContinuousFlyout.CHECKBOX_SIZE / 4 + + " " + + CheckableContinuousFlyout.CHECKBOX_SIZE / 2 + + "L" + + (5 * CheckableContinuousFlyout.CHECKBOX_SIZE) / 12 + + " " + + (2 * CheckableContinuousFlyout.CHECKBOX_SIZE) / 3 + + "L" + + (3 * CheckableContinuousFlyout.CHECKBOX_SIZE) / 4 + + " " + + CheckableContinuousFlyout.CHECKBOX_SIZE / 3; /** * Size of the checkbox corner radius @@ -48,15 +54,14 @@ export class CheckableContinuousFlyout extends ContinuousFlyout { * @const */ static CHECKBOX_SPACE_X = - CheckableContinuousFlyout.CHECKBOX_SIZE + - 2 * CheckableContinuousFlyout.CHECKBOX_MARGIN; - + CheckableContinuousFlyout.CHECKBOX_SIZE + + 2 * CheckableContinuousFlyout.CHECKBOX_MARGIN; constructor(workspaceOptions) { super(workspaceOptions); - this.tabWidth_ = 0; - this.MARGIN = 10; - this.GAP_Y = 8; + this.tabWidth_ = -2; + this.MARGIN = 12; + this.GAP_Y = 12; CheckableContinuousFlyout.CHECKBOX_MARGIN = this.MARGIN; /** @@ -69,6 +74,13 @@ export class CheckableContinuousFlyout extends ContinuousFlyout { this.checkboxes_ = new Map(); } + initFlyoutButton_(button, x, y) { + if (button.isLabel()) { + button.height = 40; + } + super.initFlyoutButton_(button, x, y); + } + show(flyoutDef) { this.clearOldCheckboxes(); super.show(flyoutDef); @@ -95,16 +107,30 @@ export class CheckableContinuousFlyout extends ContinuousFlyout { if (block.checkboxInFlyout) { const coordinates = block.getRelativeToSurfaceXY(); const checkbox = this.createCheckbox_( - block, coordinates.x, coordinates.y, block.getHeightWidth()); + block, + coordinates.x, + coordinates.y, + block.getHeightWidth() + ); let moveX = coordinates.x; if (this.RTL) { - moveX -= (CheckableContinuousFlyout.CHECKBOX_SIZE + CheckableContinuousFlyout.CHECKBOX_MARGIN); + moveX -= + CheckableContinuousFlyout.CHECKBOX_SIZE + + CheckableContinuousFlyout.CHECKBOX_MARGIN; } else { - moveX += CheckableContinuousFlyout.CHECKBOX_SIZE + CheckableContinuousFlyout.CHECKBOX_MARGIN; + moveX += + CheckableContinuousFlyout.CHECKBOX_SIZE + + CheckableContinuousFlyout.CHECKBOX_MARGIN; } block.moveBy(moveX, 0); - this.listeners.push(Blockly.browserEvents.bind(checkbox.svgRoot, - 'mousedown', null, this.checkboxClicked_(checkbox))); + this.listeners.push( + Blockly.browserEvents.bind( + checkbox.svgRoot, + "mousedown", + null, + this.checkboxClicked_(checkbox) + ) + ); } super.addBlockListeners_(root, block, rect); } @@ -118,7 +144,7 @@ export class CheckableContinuousFlyout extends ContinuousFlyout { * @private */ checkboxClicked_(checkboxObj) { - return function(e) { + return function (e) { this.setCheckboxState(checkboxObj.block.id, !checkboxObj.clicked); // This event has been handled. No need to bubble up to the document. e.stopPropagation(); @@ -138,40 +164,63 @@ export class CheckableContinuousFlyout extends ContinuousFlyout { createCheckbox_(block, cursorX, cursorY, blockHW) { var checkboxState = this.getCheckboxState(block.id); var svgRoot = block.getSvgRoot(); - var extraSpace = CheckableContinuousFlyout.CHECKBOX_SIZE + CheckableContinuousFlyout.CHECKBOX_MARGIN; - var xOffset = this.RTL ? this.getWidth() / this.workspace_.scale - extraSpace : cursorX; - var yOffset = cursorY + blockHW.height / 2 - CheckableContinuousFlyout.CHECKBOX_SIZE / 2; + var extraSpace = + CheckableContinuousFlyout.CHECKBOX_SIZE + + CheckableContinuousFlyout.CHECKBOX_MARGIN; + var xOffset = this.RTL + ? this.getWidth() / this.workspace_.scale - extraSpace + : cursorX; + var yOffset = + cursorY + + blockHW.height / 2 - + CheckableContinuousFlyout.CHECKBOX_SIZE / 2; var touchMargin = CheckableContinuousFlyout.CHECKBOX_TOUCH_PADDING; - var checkboxGroup = Blockly.utils.dom.createSvgElement('g', - { - 'transform': `translate(${xOffset}, ${yOffset})`, - 'fill': 'transparent', - }, null); - Blockly.utils.dom.createSvgElement('rect', - { - 'class': 'blocklyFlyoutCheckbox', - 'height': CheckableContinuousFlyout.CHECKBOX_SIZE, - 'width': CheckableContinuousFlyout.CHECKBOX_SIZE, - 'rx': CheckableContinuousFlyout.CHECKBOX_CORNER_RADIUS, - 'ry': CheckableContinuousFlyout.CHECKBOX_CORNER_RADIUS - }, checkboxGroup); - Blockly.utils.dom.createSvgElement('path', - { - 'class': 'blocklyFlyoutCheckboxPath', - 'd': CheckableContinuousFlyout.CHECKMARK_PATH - }, checkboxGroup); - Blockly.utils.dom.createSvgElement('rect', - { - 'class': 'blocklyTouchTargetBackground', - 'x': -touchMargin + 'px', - 'y': -touchMargin + 'px', - 'height': CheckableContinuousFlyout.CHECKBOX_SIZE + 2 * touchMargin, - 'width': CheckableContinuousFlyout.CHECKBOX_SIZE + 2 * touchMargin, - }, checkboxGroup); - var checkboxObj = {svgRoot: checkboxGroup, clicked: checkboxState, block: block}; + var checkboxGroup = Blockly.utils.dom.createSvgElement( + "g", + { + transform: `translate(${xOffset}, ${yOffset})`, + fill: "transparent", + }, + null + ); + Blockly.utils.dom.createSvgElement( + "rect", + { + class: "blocklyFlyoutCheckbox", + height: CheckableContinuousFlyout.CHECKBOX_SIZE, + width: CheckableContinuousFlyout.CHECKBOX_SIZE, + rx: CheckableContinuousFlyout.CHECKBOX_CORNER_RADIUS, + ry: CheckableContinuousFlyout.CHECKBOX_CORNER_RADIUS, + }, + checkboxGroup + ); + Blockly.utils.dom.createSvgElement( + "path", + { + class: "blocklyFlyoutCheckboxPath", + d: CheckableContinuousFlyout.CHECKMARK_PATH, + }, + checkboxGroup + ); + Blockly.utils.dom.createSvgElement( + "rect", + { + class: "blocklyTouchTargetBackground", + x: -touchMargin + "px", + y: -touchMargin + "px", + height: CheckableContinuousFlyout.CHECKBOX_SIZE + 2 * touchMargin, + width: CheckableContinuousFlyout.CHECKBOX_SIZE + 2 * touchMargin, + }, + checkboxGroup + ); + var checkboxObj = { + svgRoot: checkboxGroup, + clicked: checkboxState, + block: block, + }; if (checkboxState) { - Blockly.utils.dom.addClass((checkboxObj.svgRoot), 'checked'); + Blockly.utils.dom.addClass(checkboxObj.svgRoot, "checked"); } this.workspace_.getCanvas().insertBefore(checkboxGroup, svgRoot); @@ -195,13 +244,20 @@ export class CheckableContinuousFlyout extends ContinuousFlyout { checkboxObj.clicked = value; if (checkboxObj.clicked) { - Blockly.utils.dom.addClass(checkboxObj.svgRoot, 'checked'); + Blockly.utils.dom.addClass(checkboxObj.svgRoot, "checked"); } else { - Blockly.utils.dom.removeClass(checkboxObj.svgRoot, 'checked'); + Blockly.utils.dom.removeClass(checkboxObj.svgRoot, "checked"); } - Blockly.Events.fire(new Blockly.Events.BlockChange( - checkboxObj.block, 'checkbox', null, oldValue, value)); + Blockly.Events.fire( + new Blockly.Events.BlockChange( + checkboxObj.block, + "checkbox", + null, + oldValue, + value + ) + ); } /** diff --git a/src/renderer/constants.js b/src/renderer/constants.js new file mode 100644 index 0000000000..dc821221c6 --- /dev/null +++ b/src/renderer/constants.js @@ -0,0 +1,11 @@ +/** + * @license + * Copyright 2024 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + +import * as Blockly from "blockly/core"; + +export class ConstantProvider extends Blockly.zelos.ConstantProvider { + REPLACEMENT_GLOW_COLOUR = "#ffffff"; +} diff --git a/src/renderer/renderer.js b/src/renderer/renderer.js index 53f6a775bd..d142a10a37 100644 --- a/src/renderer/renderer.js +++ b/src/renderer/renderer.js @@ -7,6 +7,7 @@ import * as Blockly from "blockly/core"; import { Drawer } from "./drawer.js"; import { RenderInfo } from "./render_info.js"; +import { ConstantProvider } from "./constants.js"; export class ScratchRenderer extends Blockly.zelos.Renderer { makeDrawer_(block, info) { @@ -16,6 +17,14 @@ export class ScratchRenderer extends Blockly.zelos.Renderer { makeRenderInfo_(block) { return new RenderInfo(this, block); } + + makeConstants_() { + return new ConstantProvider(); + } + + shouldHighlightConnection(connection) { + return false; + } } Blockly.blockRendering.register("scratch", ScratchRenderer); From 453ffa9654927be023571f5bb496a1d0ff36aad9 Mon Sep 17 00:00:00 2001 From: Aaron Dodson Date: Fri, 9 Aug 2024 13:08:33 -0700 Subject: [PATCH 057/130] fix: prevent dragging blocks into the slot occupied by the procedure definition block's example caller block (#118) * fix: prevent replacing the procedure definition block's example caller block * chore: remove errant logging --- src/index.js | 1 + src/scratch_connection_checker.js | 29 +++++++++++++++++++++++++++++ 2 files changed, 30 insertions(+) create mode 100644 src/scratch_connection_checker.js diff --git a/src/index.js b/src/index.js index 4fe9ec8b27..4bc54f1df9 100644 --- a/src/index.js +++ b/src/index.js @@ -38,6 +38,7 @@ import { ScratchContinuousToolbox } from "./scratch_continuous_toolbox.js"; import "./scratch_continuous_category.js"; import "./scratch_comment_icon.js"; import "./scratch_variable_model.js"; +import "./scratch_connection_checker.js"; import "./events_block_comment_change.js"; import "./events_block_comment_collapse.js"; import "./events_block_comment_create.js"; diff --git a/src/scratch_connection_checker.js b/src/scratch_connection_checker.js new file mode 100644 index 0000000000..ec5988e8af --- /dev/null +++ b/src/scratch_connection_checker.js @@ -0,0 +1,29 @@ +/** + * @license + * Copyright 2024 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + +import * as Blockly from "blockly/core"; + +class ScratchConnectionChecker extends Blockly.ConnectionChecker { + // This check prevents dragging a block into the slot occupied by the + // procedure caller example block in a procedure definition block. + doDragChecks(a, b, distance) { + if ( + b.getSourceBlock().type === "procedures_definition" && + b.getParentInput()?.name === "custom_block" + ) { + return false; + } + + return super.doDragChecks(a, b, distance); + } +} + +Blockly.registry.register( + Blockly.registry.Type.CONNECTION_CHECKER, + Blockly.registry.DEFAULT, + ScratchConnectionChecker, + true +); From 0ca0620aad343cdbb1d632ddf3ae73a70085aa03 Mon Sep 17 00:00:00 2001 From: Aaron Dodson Date: Mon, 12 Aug 2024 09:22:43 -0700 Subject: [PATCH 058/130] fix: enable dragging arguments out of procedure blocks (#119) --- blocks_vertical/procedures.js | 36 +++++++++++++++++++++++++++++++++++ src/index.js | 1 + src/scratch_dragger.js | 20 +++++++++++++++++++ 3 files changed, 57 insertions(+) create mode 100644 src/scratch_dragger.js diff --git a/blocks_vertical/procedures.js b/blocks_vertical/procedures.js index 7fb54c9477..cdde28ff1f 100644 --- a/blocks_vertical/procedures.js +++ b/blocks_vertical/procedures.js @@ -26,6 +26,40 @@ import * as Blockly from "blockly/core"; import { Colours } from "../core/colours.js"; import { FieldTextInputRemovable } from "../core/field_textinput_removable.js"; +class DuplicateOnDragDraggable { + constructor(block) { + this.block = block; + } + + isMovable() { + return true; + } + + startDrag(e) { + const data = this.block.toCopyData(); + this.copy = Blockly.clipboard.paste(data, this.block.workspace); + this.baseStrat = new Blockly.dragging.BlockDragStrategy(this.copy); + this.copy.setDragStrategy(this.baseStrat); + this.baseStrat.startDrag(e); + } + + drag(e) { + this.block.workspace + .getGesture(e) + .getCurrentDragger() + .setDraggable(this.copy); + this.baseStrat.drag(e); + } + + endDrag(e) { + this.baseStrat?.endDrag(e); + } + + revertDrag(e) { + this.copy?.dispose(); + } +} + // Serialization and deserialization. /** @@ -918,6 +952,7 @@ Blockly.Blocks["argument_reporter_boolean"] = { ], extensions: ["colours_more", "output_boolean"], }); + this.setDragStrategy(new DuplicateOnDragDraggable(this)); }, }; @@ -934,6 +969,7 @@ Blockly.Blocks["argument_reporter_string_number"] = { ], extensions: ["colours_more", "output_number", "output_string"], }); + this.setDragStrategy(new DuplicateOnDragDraggable(this)); }, }; diff --git a/src/index.js b/src/index.js index 4bc54f1df9..acaea58aec 100644 --- a/src/index.js +++ b/src/index.js @@ -37,6 +37,7 @@ import { buildGlowFilter, glowStack } from "./glows.js"; import { ScratchContinuousToolbox } from "./scratch_continuous_toolbox.js"; import "./scratch_continuous_category.js"; import "./scratch_comment_icon.js"; +import "./scratch_dragger.js"; import "./scratch_variable_model.js"; import "./scratch_connection_checker.js"; import "./events_block_comment_change.js"; diff --git a/src/scratch_dragger.js b/src/scratch_dragger.js new file mode 100644 index 0000000000..66f4be8bc7 --- /dev/null +++ b/src/scratch_dragger.js @@ -0,0 +1,20 @@ +/** + * @license + * Copyright 2024 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + +import * as Blockly from "blockly/core"; + +class ScratchDragger extends Blockly.dragging.Dragger { + setDraggable(draggable) { + this.draggable = draggable; + } +} + +Blockly.registry.register( + Blockly.registry.Type.BLOCK_DRAGGER, + Blockly.registry.DEFAULT, + ScratchDragger, + true +); From fa9367d975e8c3fd45321248eb365c9cd0477dbb Mon Sep 17 00:00:00 2001 From: Aaron Dodson Date: Mon, 12 Aug 2024 13:57:01 -0700 Subject: [PATCH 059/130] fix: prevent deleting procedure definition blocks with references by dragging to the flyout (#120) --- src/scratch_dragger.js | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/scratch_dragger.js b/src/scratch_dragger.js index 66f4be8bc7..35a1fce299 100644 --- a/src/scratch_dragger.js +++ b/src/scratch_dragger.js @@ -10,6 +10,27 @@ class ScratchDragger extends Blockly.dragging.Dragger { setDraggable(draggable) { this.draggable = draggable; } + + onDragEnd(event) { + if ( + this.draggable instanceof Blockly.BlockSvg && + this.draggable.type === "procedures_definition" + ) { + const procCode = this.draggable + .getInputTargetBlock("custom_block") + .getProcCode(); + const hasCaller = this.workspace + .getBlocksByType("procedures_call") + .some((b) => b.getProcCode() === procCode); + if (hasCaller) { + Blockly.dialog.alert(Blockly.Msg.PROCEDURE_USED); + this.draggable.revertDrag(); + this.draggable.endDrag(); + return; + } + } + super.onDragEnd(event); + } } Blockly.registry.register( From 46854cdb7c9fe92b8621a9e36acd6f94e9383a9f Mon Sep 17 00:00:00 2001 From: Aaron Dodson Date: Mon, 12 Aug 2024 15:50:48 -0700 Subject: [PATCH 060/130] fix: make variable names case-sensitive (#122) --- src/index.js | 1 + src/scratch_variable_map.js | 25 +++++++++++++++++++++++++ 2 files changed, 26 insertions(+) create mode 100644 src/scratch_variable_map.js diff --git a/src/index.js b/src/index.js index acaea58aec..4621666f12 100644 --- a/src/index.js +++ b/src/index.js @@ -38,6 +38,7 @@ import { ScratchContinuousToolbox } from "./scratch_continuous_toolbox.js"; import "./scratch_continuous_category.js"; import "./scratch_comment_icon.js"; import "./scratch_dragger.js"; +import "./scratch_variable_map.js"; import "./scratch_variable_model.js"; import "./scratch_connection_checker.js"; import "./events_block_comment_change.js"; diff --git a/src/scratch_variable_map.js b/src/scratch_variable_map.js new file mode 100644 index 0000000000..5b38b2aa31 --- /dev/null +++ b/src/scratch_variable_map.js @@ -0,0 +1,25 @@ +/** + * @license + * Copyright 2024 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + +import * as Blockly from "blockly/core"; + +class ScratchVariableMap extends Blockly.VariableMap { + getVariable(name, type) { + // Variable names in Blockly are case-insensitive, but case sensitive in + // Scratch. Override the implementation to only return a variable whose name + // is identical to the one requested. + const variables = this.getVariablesOfType(type ?? ""); + if (!variables.length) return null; + return variables.find((v) => v.getName() === name) ?? null; + } +} + +Blockly.registry.register( + Blockly.registry.Type.VARIABLE_MAP, + Blockly.registry.DEFAULT, + ScratchVariableMap, + true +); From 84a9e5b8e9aba2688fd10672a852827311f32259 Mon Sep 17 00:00:00 2001 From: Aaron Dodson Date: Tue, 13 Aug 2024 09:54:48 -0700 Subject: [PATCH 061/130] fix: improve positioning of newly created procedure blocks (#121) --- src/procedures.js | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/src/procedures.js b/src/procedures.js index 09f1381f2c..c6296e9476 100644 --- a/src/procedures.js +++ b/src/procedures.js @@ -290,18 +290,20 @@ function createProcedureCallbackFactory_(workspace) { var blockDom = Blockly.utils.xml.textToDom(blockText).firstChild; Blockly.Events.setGroup(true); var block = Blockly.Xml.domToBlock(blockDom, workspace); - var scale = workspace.scale; // To convert from pixel units to workspace units - // Position the block so that it is at the top left of the visible workspace, - // padded from the edge by 30 units. Position in the top right if RTL. - var posX = -workspace.scrollX; - if (workspace.RTL) { - posX += workspace.getMetrics().contentWidth - 30; - } else { - posX += 30; - } - block.moveBy(posX / scale, (-workspace.scrollY + 30) / scale); - block.scheduleSnapAndBump(); - Blockly.Events.setGroup(false); + Blockly.renderManagement.finishQueuedRenders().then(() => { + var scale = workspace.scale; // To convert from pixel units to workspace units + // Position the block so that it is at the top left of the visible workspace, + // padded from the edge by 30 units. Position in the top right if RTL. + var posX = -workspace.scrollX; + if (workspace.RTL) { + posX += workspace.getMetrics().contentWidth - 30; + } else { + posX += 30; + } + block.moveBy(posX / scale, (-workspace.scrollY + 30) / scale); + block.scheduleSnapAndBump(); + Blockly.Events.setGroup(false); + }); } }; } From 22a6b733636b738d200c67ae53caee3e072e043a Mon Sep 17 00:00:00 2001 From: Aaron Dodson Date: Tue, 13 Aug 2024 11:28:17 -0700 Subject: [PATCH 062/130] fix: don't show global/local options when renaming a variable (#123) --- src/constants.js | 7 +++++++ src/field_variable.js | 34 ++++++++++++++++++---------------- 2 files changed, 25 insertions(+), 16 deletions(-) diff --git a/src/constants.js b/src/constants.js index 39d916e791..89c4635063 100644 --- a/src/constants.js +++ b/src/constants.js @@ -58,3 +58,10 @@ export { OUTPUT_SHAPE_ROUND }; */ const NEW_BROADCAST_MESSAGE_ID = "NEW_BROADCAST_MESSAGE_ID"; export { NEW_BROADCAST_MESSAGE_ID }; + +/** + * String for use in the dropdown created in field_variable. + * This string indicates that this option in the dropdown is 'Rename + * variable...' and if selected, should trigger the prompt to rename a variable. + */ +export const RENAME_VARIABLE_ID = "RENAME_VARIABLE_ID"; diff --git a/src/field_variable.js b/src/field_variable.js index 0617fd688b..bd278c7a4f 100644 --- a/src/field_variable.js +++ b/src/field_variable.js @@ -25,7 +25,7 @@ import * as Blockly from "blockly/core"; import * as Constants from "./constants.js"; import { ScratchMsgs } from "../msg/scratch_msgs.js"; -import { createVariable } from "./variables.js"; +import { createVariable, renameVariable } from "./variables.js"; class FieldVariable extends Blockly.FieldVariable { constructor(varName, validator, variableTypes, defaultType, config) { @@ -115,21 +115,23 @@ class FieldVariable extends Blockly.FieldVariable { */ onItemSelected_(menu, menuItem) { const sourceBlock = this.getSourceBlock(); - if ( - sourceBlock && - !sourceBlock.isDeadOrDying() && - menuItem.getValue() === Constants.NEW_BROADCAST_MESSAGE_ID - ) { - createVariable( - sourceBlock.workspace, - (varId) => { - if (varId) { - this.setValue(varId); - } - }, - Constants.BROADCAST_MESSAGE_VARIABLE_TYPE - ); - return; + if (sourceBlock && !sourceBlock.isDeadOrDying()) { + const selectedItem = menuItem.getValue(); + if (selectedItem === Constants.NEW_BROADCAST_MESSAGE_ID) { + createVariable( + sourceBlock.workspace, + (varId) => { + if (varId) { + this.setValue(varId); + } + }, + Constants.BROADCAST_MESSAGE_VARIABLE_TYPE + ); + return; + } else if (selectedItem === Constants.RENAME_VARIABLE_ID) { + renameVariable(sourceBlock.workspace, this.variable); + return; + } } super.onItemSelected_(menu, menuItem); } From b1e67f62dcedbd35e1b92d1ec1c773ff74b2ef56 Mon Sep 17 00:00:00 2001 From: Aaron Dodson Date: Tue, 13 Aug 2024 11:50:37 -0700 Subject: [PATCH 063/130] fix: fixed bug where broadcast messages would appear in the variable dropdown list (#124) --- blocks_vertical/data.js | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/blocks_vertical/data.js b/blocks_vertical/data.js index b76d4ec5f5..7561156383 100644 --- a/blocks_vertical/data.js +++ b/blocks_vertical/data.js @@ -62,6 +62,8 @@ Blockly.Blocks["data_setvariableto"] = { { type: "field_variable", name: "VARIABLE", + variableTypes: [Constants.SCALAR_VARIABLE_TYPE], + defaultType: Constants.SCALAR_VARIABLE_TYPE, }, { type: "input_value", @@ -86,6 +88,8 @@ Blockly.Blocks["data_changevariableby"] = { { type: "field_variable", name: "VARIABLE", + variableTypes: [Constants.SCALAR_VARIABLE_TYPE], + defaultType: Constants.SCALAR_VARIABLE_TYPE, }, { type: "input_value", @@ -110,6 +114,8 @@ Blockly.Blocks["data_showvariable"] = { { type: "field_variable", name: "VARIABLE", + variableTypes: [Constants.SCALAR_VARIABLE_TYPE], + defaultType: Constants.SCALAR_VARIABLE_TYPE, }, ], previousStatement: null, @@ -132,6 +138,8 @@ Blockly.Blocks["data_hidevariable"] = { { type: "field_variable", name: "VARIABLE", + variableTypes: [Constants.SCALAR_VARIABLE_TYPE], + defaultType: Constants.SCALAR_VARIABLE_TYPE, }, ], previousStatement: null, From a09ae248a1c3aa422942b1f9d21487c79c0c4b86 Mon Sep 17 00:00:00 2001 From: Beka Westberg Date: Tue, 20 Aug 2024 16:26:19 +0000 Subject: [PATCH 064/130] fix: add zoom controls config (#126) --- src/index.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/index.js b/src/index.js index 4621666f12..c29c83248f 100644 --- a/src/index.js +++ b/src/index.js @@ -72,6 +72,12 @@ export function inject(container, options) { Object.assign(options, { renderer: "scratch", theme: "zelos", + zoom: { + controls: true, + wheel: true, + pinch: true, + startScale: 0.675, + }, plugins: { toolbox: ScratchContinuousToolbox, flyoutsVerticalToolbox: CheckableContinuousFlyout, From 8e1dc14483d6e012734a30b666af7aa5427c58f9 Mon Sep 17 00:00:00 2001 From: Beka Westberg Date: Wed, 21 Aug 2024 15:58:18 +0000 Subject: [PATCH 065/130] Revert "fix: add zoom controls config (#126)" (#128) This reverts commit a09ae248a1c3aa422942b1f9d21487c79c0c4b86. --- src/index.js | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/index.js b/src/index.js index c29c83248f..4621666f12 100644 --- a/src/index.js +++ b/src/index.js @@ -72,12 +72,6 @@ export function inject(container, options) { Object.assign(options, { renderer: "scratch", theme: "zelos", - zoom: { - controls: true, - wheel: true, - pinch: true, - startScale: 0.675, - }, plugins: { toolbox: ScratchContinuousToolbox, flyoutsVerticalToolbox: CheckableContinuousFlyout, From a65d24a38daf8a740d5230ee9a7fbac5ae70e2af Mon Sep 17 00:00:00 2001 From: Beka Westberg Date: Wed, 21 Aug 2024 16:22:47 +0000 Subject: [PATCH 066/130] fix: delete context menu to display the correct number of blocks (#127) --- src/context_menu_items.js | 146 ++++++++++++++++++++++++++++++++++++++ src/index.js | 6 ++ 2 files changed, 152 insertions(+) create mode 100644 src/context_menu_items.js diff --git a/src/context_menu_items.js b/src/context_menu_items.js new file mode 100644 index 0000000000..aca1ae0796 --- /dev/null +++ b/src/context_menu_items.js @@ -0,0 +1,146 @@ +/** + * @license + * Copyright 2024 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + +import * as Blockly from "blockly/core"; + +/** + * Registers a block delete option that ignores shadows in the block count. + */ +export function registerDeleteBlock() { + const deleteOption = { + displayText(scope) { + const descendantCount = getDeletableBlocksInStack(scope.block).length; + return descendantCount === 1 + ? Blockly.Msg["DELETE_BLOCK"] + : Blockly.Msg["DELETE_X_BLOCKS"].replace("%1", `${descendantCount}`); + }, + preconditionFn(scope) { + if (!scope.block.isInFlyout && scope.block.isDeletable()) { + return "enabled"; + } + return "hidden"; + }, + callback(scope) { + Blockly.Events.setGroup(true); + scope.block.dispose(true, true); + Blockly.Events.setGroup(false); + }, + scopeType: Blockly.ContextMenuRegistry.ScopeType.BLOCK, + id: "blockDelete", + weight: 6, + }; + Blockly.ContextMenuRegistry.registry.register(deleteOption); +} + +function getDeletableBlocksInStack(block) { + let descendants = block.getDescendants(false).filter(isDeletable); + if (block.getNextBlock()) { + // Next blocks are not deleted. + const nextDescendants = block + .getNextBlock() + .getDescendants(false) + .filter(isDeletable); + descendants = descendants.filter((b) => !nextDescendants.includes(b)); + } + return descendants; +} + +function isDeletable(block) { + return block.isDeletable() && !block.isShadow(); +} + +/** + * Option to delete all blocks. + */ +export function registerDeleteAll() { + const deleteOption = { + displayText(scope) { + if (!scope.workspace) { + return ""; + } + const deletableBlocksLength = getDeletableBlocksInWorkspace(scope.workspace).length; + if (deletableBlocksLength === 1) { + return Blockly.Msg["DELETE_BLOCK"]; + } + return Blockly.Msg["DELETE_X_BLOCKS"].replace( + "%1", + `${deletableBlocksLength}` + ); + }, + preconditionFn(scope) { + if (!scope.workspace) { + return "disabled"; + } + const deletableBlocksLength = getDeletableBlocksInWorkspace(scope.workspace).length; + return deletableBlocksLength > 0 ? "enabled" : "disabled"; + }, + callback(scope) { + if (!scope.workspace) { + return; + } + scope.workspace.cancelCurrentGesture(); + const deletableBlocks = getDeletableBlocksInWorkspace(scope.workspace); + if (deletableBlocks.length < 2) { + deleteNext(deletableBlocks); + } else { + Blockly.dialog.confirm( + Blockly.Msg["DELETE_ALL_BLOCKS"].replace( + "%1", + String(deletableBlocks.length) + ), + function (ok) { + if (ok) { + deleteNext(deletableBlocks); + } + } + ); + } + }, + scopeType: Blockly.ContextMenuRegistry.ScopeType.WORKSPACE, + id: "workspaceDelete", + weight: 6, + }; + Blockly.ContextMenuRegistry.registry.register(deleteOption); +} + +/* + * Constructs a list of blocks that can be deleted in the given workspace. + * + * @param workspace to delete all blocks from. + * @returns list of blocks to delete. + */ +function getDeletableBlocksInWorkspace(workspace) { + return workspace + .getTopBlocks(true) + .flatMap((b) => b.getDescendants(false).filter(isDeletable)); +} + +/** + * Deletes the given blocks. Used to delete all blocks in the workspace. + * + * @param deleteList List of blocks to delete. + * @param eventGroup Event group ID with which all delete events should be + * associated. If not specified, create a new group. + */ +function deleteNext(deleteList, eventGroup) { + const DELAY = 10; + if (eventGroup) { + Blockly.Events.setGroup(eventGroup); + } else { + Blockly.Events.setGroup(true); + eventGroup = Blockly.Events.getGroup(); + } + const block = deleteList.shift(); + if (block) { + if (!block.isDeadOrDying()) { + block.dispose(false, true); + setTimeout(deleteNext, DELAY, deleteList, eventGroup); + } else { + deleteNext(deleteList, eventGroup); + } + } + Blockly.Events.setGroup(false); +} diff --git a/src/index.js b/src/index.js index 4621666f12..7a6182431e 100644 --- a/src/index.js +++ b/src/index.js @@ -27,6 +27,7 @@ import * as ScratchVariables from "./variables.js"; import "../core/css.js"; import "../core/field_vertical_separator.js"; import "./renderer/renderer.js"; +import * as contextMenuItems from "./context_menu_items.js"; import { ContinuousToolbox, ContinuousFlyout, @@ -67,6 +68,7 @@ export { glowStack }; export { scratchBlocksUtils }; export { CheckableContinuousFlyout }; export { ScratchVariables }; +export { contextMenuItems }; export function inject(container, options) { Object.assign(options, { @@ -105,3 +107,7 @@ Blockly.FlyoutButton.TEXT_MARGIN_Y = 10; Blockly.ContextMenuRegistry.registry.unregister("blockDisable"); Blockly.ContextMenuRegistry.registry.unregister("blockInline"); Blockly.ContextMenuItems.registerCommentOptions(); +Blockly.ContextMenuRegistry.registry.unregister("blockDelete"); +contextMenuItems.registerDeleteBlock(); +Blockly.ContextMenuRegistry.registry.unregister("workspaceDelete"); +contextMenuItems.registerDeleteAll(); From ff4b1151d702be0be5dabf1f1032fd08b8d58e3e Mon Sep 17 00:00:00 2001 From: Beka Westberg Date: Wed, 21 Aug 2024 16:42:40 +0000 Subject: [PATCH 067/130] fix: remove canvas transition (#129) --- core/css.js | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/core/css.js b/core/css.js index 4b6b253161..17b00d56f7 100644 --- a/core/css.js +++ b/core/css.js @@ -55,6 +55,11 @@ const styles = ` -ms-user-select: none; } + .blocklyBlockCanvas.blocklyCanvasTransitioning, + .blocklyBubbleCanvas.blocklyCanvasTransitioning { + transition: none; + } + .blocklyWidgetDiv.fieldTextInput { overflow: hidden; border: 1px solid; @@ -83,13 +88,6 @@ const styles = ` cursor: pointer; } - .blocklyNonSelectable { - user-select: none; - -moz-user-select: none; - -webkit-user-select: none; - -ms-user-select: none; - } - .blocklyWsDragSurface { display: none; position: absolute; From eb839fcef9e8befad591cf35c00044adff9269f6 Mon Sep 17 00:00:00 2001 From: Aaron Dodson Date: Wed, 21 Aug 2024 14:02:57 -0700 Subject: [PATCH 068/130] fix: show the name of the list in the list getter block context menu (#132) --- blocks_vertical/data.js | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/blocks_vertical/data.js b/blocks_vertical/data.js index 7561156383..ea1e09edf1 100644 --- a/blocks_vertical/data.js +++ b/blocks_vertical/data.js @@ -596,7 +596,7 @@ const CUSTOM_CONTEXT_MENU_GET_LIST_MIXIN = { if (this.isCollapsed()) { return; } - var currentVarName = this.getField(fieldName).text_; + var currentVarName = this.getField(fieldName).getVariable().getName(); if (!this.isInFlyout) { var variablesList = this.workspace.getVariablesOfType( Constants.LIST_VARIABLE_TYPE @@ -683,8 +683,7 @@ const RENAME_OPTION_CALLBACK_FACTORY = function (block, fieldName) { */ const DELETE_OPTION_CALLBACK_FACTORY = function (block, fieldName) { return function () { - var workspace = block.workspace; - var variable = block.getField(fieldName).getVariable(); - workspace.deleteVariableById(variable.getId()); + const variable = block.getField(fieldName).getVariable(); + Blockly.Variables.deleteVariable(variable.getWorkspace(), variable, block); }; }; From cda58ccfa799a0d301d6ba842c6546c1eb9f5614 Mon Sep 17 00:00:00 2001 From: Aaron Dodson Date: Wed, 21 Aug 2024 14:03:11 -0700 Subject: [PATCH 069/130] fix: don't warn about procedure references when moving the definition on the workspace (#131) --- src/scratch_dragger.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/scratch_dragger.js b/src/scratch_dragger.js index 35a1fce299..ebd0878050 100644 --- a/src/scratch_dragger.js +++ b/src/scratch_dragger.js @@ -14,7 +14,8 @@ class ScratchDragger extends Blockly.dragging.Dragger { onDragEnd(event) { if ( this.draggable instanceof Blockly.BlockSvg && - this.draggable.type === "procedures_definition" + this.draggable.type === "procedures_definition" && + this.wouldDeleteDraggable(event, this.draggable.getRootBlock()) ) { const procCode = this.draggable .getInputTargetBlock("custom_block") From 3d8b998f3be7e76adf313a60b81f29b871266c94 Mon Sep 17 00:00:00 2001 From: Aaron Dodson Date: Wed, 21 Aug 2024 14:10:04 -0700 Subject: [PATCH 070/130] fix: reenable support for dragging blocks between sprites (#130) --- core/css.js | 6 +- src/events_block_drag_end.js | 33 ++++++++++ src/events_block_drag_outside.js | 30 ++++++++++ src/scratch_dragger.js | 100 +++++++++++++++++++++++++++++++ 4 files changed, 168 insertions(+), 1 deletion(-) create mode 100644 src/events_block_drag_end.js create mode 100644 src/events_block_drag_outside.js diff --git a/core/css.js b/core/css.js index 17b00d56f7..d5127c7c40 100644 --- a/core/css.js +++ b/core/css.js @@ -45,7 +45,11 @@ const styles = ` height: 100%; position: relative; overflow: hidden; /* So blocks in drag surface disappear at edges */ - touch-action: none + touch-action: none; + } + + .injectionDiv.boundless { + overflow: visible; } .blocklyNonSelectable { diff --git a/src/events_block_drag_end.js b/src/events_block_drag_end.js new file mode 100644 index 0000000000..25def88961 --- /dev/null +++ b/src/events_block_drag_end.js @@ -0,0 +1,33 @@ +/** + * @license + * Copyright 2024 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + +import * as Blockly from "blockly/core"; + +export class BlockDragEnd extends Blockly.Events.BlockBase { + constructor(block, isOutside) { + super(block); + this.type = "endDrag"; + this.isOutside = isOutside; + this.recordUndo = false; + this.xml = Blockly.Xml.blockToDom(block, true); + } + + toJson() { + return { + ...super.toJson(), + isOutside: this.isOutside, + xml: this.xml, + }; + } + + static fromJson(json, workspace, event) { + const newEvent = super.fromJson(json, workspace, event); + newEvent.isOutside = json["isOutside"]; + newEvent.xml = json["xml"]; + + return newEvent; + } +} diff --git a/src/events_block_drag_outside.js b/src/events_block_drag_outside.js new file mode 100644 index 0000000000..1acdfe5b35 --- /dev/null +++ b/src/events_block_drag_outside.js @@ -0,0 +1,30 @@ +/** + * @license + * Copyright 2024 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + +import * as Blockly from "blockly/core"; + +export class BlockDragOutside extends Blockly.Events.BlockBase { + constructor(block, isOutside) { + super(block); + this.type = "dragOutside"; + this.isOutside = isOutside; + this.recordUndo = false; + } + + toJson() { + return { + ...super.toJson(), + isOutside: this.isOutside, + }; + } + + static fromJson(json, workspace, event) { + const newEvent = super.fromJson(json, workspace, event); + newEvent.isOutside = json["isOutside"]; + + return newEvent; + } +} diff --git a/src/scratch_dragger.js b/src/scratch_dragger.js index ebd0878050..ce40b0edfd 100644 --- a/src/scratch_dragger.js +++ b/src/scratch_dragger.js @@ -5,12 +5,61 @@ */ import * as Blockly from "blockly/core"; +import { BlockDragOutside } from "./events_block_drag_outside.js"; +import { BlockDragEnd } from "./events_block_drag_end.js"; + +const BOUNDLESS_CLASS = "boundless"; class ScratchDragger extends Blockly.dragging.Dragger { + constructor(draggable, workspace) { + super(draggable, workspace); + this.draggedOutOfBounds = false; + this.originatedFromFlyout = false; + } + setDraggable(draggable) { this.draggable = draggable; } + onDragStart(event) { + super.onDragStart(event); + if (this.draggable instanceof Blockly.BlockSvg) { + this.workspace.addClass(BOUNDLESS_CLASS); + const absoluteMetrics = this.workspace + .getMetricsManager() + .getAbsoluteMetrics(); + const viewMetrics = this.workspace.getMetricsManager().getViewMetrics(); + if ( + this.workspace.RTL + ? event.clientX > + this.workspace.getParentSvg().getBoundingClientRect().left + + viewMetrics.width + : event.clientX < absoluteMetrics.left + ) { + this.originatedFromFlyout = true; + } + } + } + + onDrag(event, totalDelta) { + super.onDrag(event, totalDelta); + this.updateOutOfBoundsState(event); + } + + updateOutOfBoundsState(event) { + if (this.draggable instanceof Blockly.BlockSvg) { + const outOfBounds = !this.isInsideWorkspace(event); + if (outOfBounds !== this.draggedOutOfBounds) { + const event = new BlockDragOutside( + this.getDragRoot(this.draggable), + outOfBounds + ); + Blockly.Events.fire(event); + this.draggedOutOfBounds = outOfBounds; + } + } + } + onDragEnd(event) { if ( this.draggable instanceof Blockly.BlockSvg && @@ -30,7 +79,58 @@ class ScratchDragger extends Blockly.dragging.Dragger { return; } } + super.onDragEnd(event); + + this.updateOutOfBoundsState(event); + if (this.draggable instanceof Blockly.BlockSvg) { + const event = new BlockDragEnd( + this.getDragRoot(this.draggable), + this.draggedOutOfBounds + ); + Blockly.Events.fire(event); + // If this block was dragged out of the flyout and dropped outside of + // the workspace (e.g. on a different sprite), the block that was created + // on the workspace in order to depict the block mid-drag needs to be + // deleted. + if (this.originatedFromFlyout && this.draggedOutOfBounds) { + Blockly.renderManagement.finishQueuedRenders().then(() => { + this.getDragRoot(this.draggable).dispose(); + }); + } + } + this.workspace.removeClass(BOUNDLESS_CLASS); + } + + shouldReturnToStart(event, rootDraggable) { + // If a block is dragged out of the workspace to be e.g. dropped on another + // sprite, it should remain in the same place on the workspace where it was, + // rather than being moved to an invisible part of the workspace. + return ( + this.draggedOutOfBounds || super.shouldReturnToStart(event, rootDraggable) + ); + } + + getDragRoot(block) { + // We can't just use getRootBlock() here because, when blocks are detached + // from a stack via dragging, getRootBlock() still returns the root of that + // stack. + if (block.isShadow()) { + return block.getParent(); + } + + return block; + } + + isInsideWorkspace(event) { + const bounds = this.workspace.getParentSvg().getBoundingClientRect(); + const workspaceRect = new Blockly.utils.Rect( + bounds.top, + bounds.bottom, + bounds.left, + bounds.right + ); + return workspaceRect.contains(event.clientX, event.clientY); } } From 3faed99e7feb8908687db6cc05236c5b40a668c6 Mon Sep 17 00:00:00 2001 From: Aaron Dodson Date: Wed, 21 Aug 2024 15:17:37 -0700 Subject: [PATCH 071/130] chore: fix various build warnings (#133) * chore: format blocks_common/math.js * chore: fix build warnings in blocks_common/math.js * chore: fix build warnings in blocks_vertical/data.js * chore: fix build warnings in blocks_vertical/vertical_extensions.js * chore: fix build warnings in src/constants.js * chore: fix constant references in field_variable.js * chore: format blocks_vertical/sensing.js * chore: fix build warnings in blocks_vertical/sensing.js * chore: clean up build warnings in scratch_blocks_utils.js --- blocks_common/math.js | 157 +++---- blocks_vertical/data.js | 4 +- blocks_vertical/sensing.js | 560 ++++++++++++------------- blocks_vertical/vertical_extensions.js | 7 +- core/scratch_blocks_utils.js | 122 +----- src/constants.js | 10 +- src/field_variable.js | 2 +- 7 files changed, 385 insertions(+), 477 deletions(-) diff --git a/blocks_common/math.js b/blocks_common/math.js index 542026127f..4532738057 100644 --- a/blocks_common/math.js +++ b/blocks_common/math.js @@ -22,131 +22,132 @@ * @fileoverview Math blocks for Blockly. * @author q.neutron@gmail.com (Quynh Neutron) */ -import * as Blockly from 'blockly/core'; -import {Colours} from '../core/colours.js'; +import * as Blockly from "blockly/core"; +import { Colours } from "../core/colours.js"; +import * as Constants from "../src/constants.js"; -Blockly.Blocks['math_number'] = { +Blockly.Blocks["math_number"] = { /** * Block for generic numeric value. * @this Blockly.Block */ - init: function() { + init: function () { this.jsonInit({ - "message0": "%1", - "args0": [ + message0: "%1", + args0: [ { - "type": "field_number", - "name": "NUM", - "value": "0" - } + type: "field_number", + name: "NUM", + value: "0", + }, ], - "output": "Number", - // "outputShape": Blockly.OUTPUT_SHAPE_ROUND, - "colour": Colours.textField, - "colourSecondary": Colours.textField, - "colourTertiary": Colours.textField, - "colourQuaternary": Colours.textField + output: "Number", + outputShape: Constants.OUTPUT_SHAPE_ROUND, + colour: Colours.textField, + colourSecondary: Colours.textField, + colourTertiary: Colours.textField, + colourQuaternary: Colours.textField, }); - } + }, }; -Blockly.Blocks['math_integer'] = { +Blockly.Blocks["math_integer"] = { /** * Block for integer value (no decimal, + or -). * @this Blockly.Block */ - init: function() { + init: function () { this.jsonInit({ - "message0": "%1", - "args0": [ + message0: "%1", + args0: [ { - "type": "field_number", - "name": "NUM", - "precision": 1 - } + type: "field_number", + name: "NUM", + precision: 1, + }, ], - "output": "Number", - // "outputShape": Blockly.OUTPUT_SHAPE_ROUND, - "colour": Colours.textField, - "colourSecondary": Colours.textField, - "colourTertiary": Colours.textField, - "colourQuaternary": Colours.textField + output: "Number", + outputShape: Constants.OUTPUT_SHAPE_ROUND, + colour: Colours.textField, + colourSecondary: Colours.textField, + colourTertiary: Colours.textField, + colourQuaternary: Colours.textField, }); - } + }, }; -Blockly.Blocks['math_whole_number'] = { +Blockly.Blocks["math_whole_number"] = { /** * Block for whole number value, no negatives or decimals. * @this Blockly.Block */ - init: function() { + init: function () { this.jsonInit({ - "message0": "%1", - "args0": [ + message0: "%1", + args0: [ { - "type": "field_number", - "name": "NUM", - "min": 0, - "precision": 1 - } + type: "field_number", + name: "NUM", + min: 0, + precision: 1, + }, ], - "output": "Number", - // "outputShape": Blockly.OUTPUT_SHAPE_ROUND, - "colour": Colours.textField, - "colourSecondary": Colours.textField, - "colourTertiary": Colours.textField, - "colourQuaternary": Colours.textField + output: "Number", + outputShape: Constants.OUTPUT_SHAPE_ROUND, + colour: Colours.textField, + colourSecondary: Colours.textField, + colourTertiary: Colours.textField, + colourQuaternary: Colours.textField, }); - } + }, }; -Blockly.Blocks['math_positive_number'] = { +Blockly.Blocks["math_positive_number"] = { /** * Block for positive number value, with decimal. * @this Blockly.Block */ - init: function() { + init: function () { this.jsonInit({ - "message0": "%1", - "args0": [ + message0: "%1", + args0: [ { - "type": "field_number", - "name": "NUM", - "min": 0 - } + type: "field_number", + name: "NUM", + min: 0, + }, ], - "output": "Number", - // "outputShape": Blockly.OUTPUT_SHAPE_ROUND, - "colour": Colours.textField, - "colourSecondary": Colours.textField, - "colourTertiary": Colours.textField, - "colourQuaternary": Colours.textField + output: "Number", + outputShape: Constants.OUTPUT_SHAPE_ROUND, + colour: Colours.textField, + colourSecondary: Colours.textField, + colourTertiary: Colours.textField, + colourQuaternary: Colours.textField, }); - } + }, }; -Blockly.Blocks['math_angle'] = { +Blockly.Blocks["math_angle"] = { /** * Block for angle picker. * @this Blockly.Block */ - init: function() { + init: function () { this.jsonInit({ - "message0": "%1", - "args0": [ + message0: "%1", + args0: [ { - "type": "field_angle", - "name": "NUM", - "value": 90 - } + type: "field_angle", + name: "NUM", + value: 90, + }, ], - "output": "Number", - // "outputShape": Blockly.OUTPUT_SHAPE_ROUND, - "colour": Colours.textField, - "colourSecondary": Colours.textField, - "colourTertiary": Colours.textField, - "colourQuaternary": Colours.textField + output: "Number", + outputShape: Constants.OUTPUT_SHAPE_ROUND, + colour: Colours.textField, + colourSecondary: Colours.textField, + colourTertiary: Colours.textField, + colourQuaternary: Colours.textField, }); - } + }, }; diff --git a/blocks_vertical/data.js b/blocks_vertical/data.js index ea1e09edf1..55bedc702d 100644 --- a/blocks_vertical/data.js +++ b/blocks_vertical/data.js @@ -389,7 +389,7 @@ Blockly.Blocks["data_itemoflist"] = { output: null, category: Categories.dataLists, extensions: ["colours_data_lists"], - outputShape: Blockly.OUTPUT_SHAPE_ROUND, + outputShape: Constants.OUTPUT_SHAPE_ROUND, }); }, }; @@ -417,7 +417,7 @@ Blockly.Blocks["data_itemnumoflist"] = { output: null, category: Categories.dataLists, extensions: ["colours_data_lists"], - outputShape: Blockly.OUTPUT_SHAPE_ROUND, + outputShape: Constants.OUTPUT_SHAPE_ROUND, }); }, }; diff --git a/blocks_vertical/sensing.js b/blocks_vertical/sensing.js index dfd2ed103f..c25eae5159 100644 --- a/blocks_vertical/sensing.js +++ b/blocks_vertical/sensing.js @@ -18,515 +18,513 @@ * limitations under the License. */ -import * as Blockly from 'blockly/core'; -import {Categories} from '../src/categories.js'; +import * as Blockly from "blockly/core"; +import { Categories } from "../src/categories.js"; +import * as Constants from "../src/constants.js"; -Blockly.Blocks['sensing_touchingobject'] = { +Blockly.Blocks["sensing_touchingobject"] = { /** * Block to Report if its touching a Object. * @this Blockly.Block */ - init: function() { + init: function () { this.jsonInit({ - "message0": Blockly.Msg.SENSING_TOUCHINGOBJECT, - "args0": [ + message0: Blockly.Msg.SENSING_TOUCHINGOBJECT, + args0: [ { - "type": "input_value", - "name": "TOUCHINGOBJECTMENU" - } + type: "input_value", + name: "TOUCHINGOBJECTMENU", + }, ], - "category": Categories.sensing, - "extensions": ["colours_sensing", "output_boolean"] + category: Categories.sensing, + extensions: ["colours_sensing", "output_boolean"], }); - } + }, }; -Blockly.Blocks['sensing_touchingobjectmenu'] = { +Blockly.Blocks["sensing_touchingobjectmenu"] = { /** * "Touching [Object]" Block Menu. * @this Blockly.Block */ - init: function() { + init: function () { this.jsonInit({ - "message0": "%1", - "args0": [ + message0: "%1", + args0: [ { - "type": "field_dropdown", - "name": "TOUCHINGOBJECTMENU", - "options": [ - [Blockly.Msg.SENSING_TOUCHINGOBJECT_POINTER, '_mouse_'], - [Blockly.Msg.SENSING_TOUCHINGOBJECT_EDGE, '_edge_'] - ] - } + type: "field_dropdown", + name: "TOUCHINGOBJECTMENU", + options: [ + [Blockly.Msg.SENSING_TOUCHINGOBJECT_POINTER, "_mouse_"], + [Blockly.Msg.SENSING_TOUCHINGOBJECT_EDGE, "_edge_"], + ], + }, ], - "extensions": ["colours_sensing", "output_string"] + extensions: ["colours_sensing", "output_string"], }); - } + }, }; -Blockly.Blocks['sensing_touchingcolor'] = { +Blockly.Blocks["sensing_touchingcolor"] = { /** * Block to Report if its touching a certain Color. * @this Blockly.Block */ - init: function() { + init: function () { this.jsonInit({ - "message0": Blockly.Msg.SENSING_TOUCHINGCOLOR, - "args0": [ + message0: Blockly.Msg.SENSING_TOUCHINGCOLOR, + args0: [ { - "type": "input_value", - "name": "COLOR" - } + type: "input_value", + name: "COLOR", + }, ], - "category": Categories.sensing, - "extensions": ["colours_sensing", "output_boolean"] + category: Categories.sensing, + extensions: ["colours_sensing", "output_boolean"], }); - } + }, }; -Blockly.Blocks['sensing_coloristouchingcolor'] = { +Blockly.Blocks["sensing_coloristouchingcolor"] = { /** * Block to Report if a color is touching a certain Color. * @this Blockly.Block */ - init: function() { + init: function () { this.jsonInit({ - "message0": Blockly.Msg.SENSING_COLORISTOUCHINGCOLOR, - "args0": [ + message0: Blockly.Msg.SENSING_COLORISTOUCHINGCOLOR, + args0: [ { - "type": "input_value", - "name": "COLOR" + type: "input_value", + name: "COLOR", }, { - "type": "input_value", - "name": "COLOR2" - } + type: "input_value", + name: "COLOR2", + }, ], - "category": Categories.sensing, - "extensions": ["colours_sensing", "output_boolean"] + category: Categories.sensing, + extensions: ["colours_sensing", "output_boolean"], }); - } + }, }; -Blockly.Blocks['sensing_distanceto'] = { +Blockly.Blocks["sensing_distanceto"] = { /** * Block to Report distance to another Object. * @this Blockly.Block */ - init: function() { + init: function () { this.jsonInit({ - "message0": Blockly.Msg.SENSING_DISTANCETO, - "args0": [ + message0: Blockly.Msg.SENSING_DISTANCETO, + args0: [ { - "type": "input_value", - "name": "DISTANCETOMENU" - } + type: "input_value", + name: "DISTANCETOMENU", + }, ], - "category": Categories.sensing, - "extensions": ["colours_sensing", "output_number"] + category: Categories.sensing, + extensions: ["colours_sensing", "output_number"], }); - } + }, }; -Blockly.Blocks['sensing_distancetomenu'] = { +Blockly.Blocks["sensing_distancetomenu"] = { /** * "Distance to [Object]" Block Menu. * @this Blockly.Block */ - init: function() { + init: function () { this.jsonInit({ - "message0": "%1", - "args0": [ + message0: "%1", + args0: [ { - "type": "field_dropdown", - "name": "DISTANCETOMENU", - "options": [ - [Blockly.Msg.SENSING_DISTANCETO_POINTER, '_mouse_'] - ] - } + type: "field_dropdown", + name: "DISTANCETOMENU", + options: [[Blockly.Msg.SENSING_DISTANCETO_POINTER, "_mouse_"]], + }, ], - "extensions": ["colours_sensing", "output_string"] + extensions: ["colours_sensing", "output_string"], }); - } + }, }; -Blockly.Blocks['sensing_askandwait'] = { +Blockly.Blocks["sensing_askandwait"] = { /** * Block to ask a question and wait * @this Blockly.Block */ - init: function() { + init: function () { this.jsonInit({ - "message0": Blockly.Msg.SENSING_ASKANDWAIT, - "args0": [ + message0: Blockly.Msg.SENSING_ASKANDWAIT, + args0: [ { - "type": "input_value", - "name": "QUESTION" - } + type: "input_value", + name: "QUESTION", + }, ], - "category": Categories.sensing, - "extensions": ["colours_sensing", "shape_statement"] + category: Categories.sensing, + extensions: ["colours_sensing", "shape_statement"], }); - } + }, }; -Blockly.Blocks['sensing_answer'] = { +Blockly.Blocks["sensing_answer"] = { /** * Block to report answer * @this Blockly.Block */ - init: function() { + init: function () { this.jsonInit({ - "message0": Blockly.Msg.SENSING_ANSWER, - "category": Categories.sensing, - "extensions": ["colours_sensing", "output_number"] + message0: Blockly.Msg.SENSING_ANSWER, + category: Categories.sensing, + extensions: ["colours_sensing", "output_number"], }); this.checkboxInFlyout = true; - } + }, }; -Blockly.Blocks['sensing_keypressed'] = { +Blockly.Blocks["sensing_keypressed"] = { /** * Block to Report if a key is pressed. * @this Blockly.Block */ - init: function() { + init: function () { this.jsonInit({ - "message0": Blockly.Msg.SENSING_KEYPRESSED, - "args0": [ + message0: Blockly.Msg.SENSING_KEYPRESSED, + args0: [ { - "type": "input_value", - "name": "KEY_OPTION" - } + type: "input_value", + name: "KEY_OPTION", + }, ], - "category": Categories.sensing, - "extensions": ["colours_sensing", "output_boolean"] + category: Categories.sensing, + extensions: ["colours_sensing", "output_boolean"], }); - } + }, }; -Blockly.Blocks['sensing_keyoptions'] = { +Blockly.Blocks["sensing_keyoptions"] = { /** * Options for Keys * @this Blockly.Block */ - init: function() { + init: function () { this.jsonInit({ - "message0": "%1", - "args0": [ + message0: "%1", + args0: [ { - "type": "field_dropdown", - "name": "KEY_OPTION", - "options": [ - [Blockly.Msg.EVENT_WHENKEYPRESSED_SPACE, 'space'], - [Blockly.Msg.EVENT_WHENKEYPRESSED_UP, 'up arrow'], - [Blockly.Msg.EVENT_WHENKEYPRESSED_DOWN, 'down arrow'], - [Blockly.Msg.EVENT_WHENKEYPRESSED_RIGHT, 'right arrow'], - [Blockly.Msg.EVENT_WHENKEYPRESSED_LEFT, 'left arrow'], - [Blockly.Msg.EVENT_WHENKEYPRESSED_ANY, 'any'], - ['a', 'a'], - ['b', 'b'], - ['c', 'c'], - ['d', 'd'], - ['e', 'e'], - ['f', 'f'], - ['g', 'g'], - ['h', 'h'], - ['i', 'i'], - ['j', 'j'], - ['k', 'k'], - ['l', 'l'], - ['m', 'm'], - ['n', 'n'], - ['o', 'o'], - ['p', 'p'], - ['q', 'q'], - ['r', 'r'], - ['s', 's'], - ['t', 't'], - ['u', 'u'], - ['v', 'v'], - ['w', 'w'], - ['x', 'x'], - ['y', 'y'], - ['z', 'z'], - ['0', '0'], - ['1', '1'], - ['2', '2'], - ['3', '3'], - ['4', '4'], - ['5', '5'], - ['6', '6'], - ['7', '7'], - ['8', '8'], - ['9', '9'] - ] - } + type: "field_dropdown", + name: "KEY_OPTION", + options: [ + [Blockly.Msg.EVENT_WHENKEYPRESSED_SPACE, "space"], + [Blockly.Msg.EVENT_WHENKEYPRESSED_UP, "up arrow"], + [Blockly.Msg.EVENT_WHENKEYPRESSED_DOWN, "down arrow"], + [Blockly.Msg.EVENT_WHENKEYPRESSED_RIGHT, "right arrow"], + [Blockly.Msg.EVENT_WHENKEYPRESSED_LEFT, "left arrow"], + [Blockly.Msg.EVENT_WHENKEYPRESSED_ANY, "any"], + ["a", "a"], + ["b", "b"], + ["c", "c"], + ["d", "d"], + ["e", "e"], + ["f", "f"], + ["g", "g"], + ["h", "h"], + ["i", "i"], + ["j", "j"], + ["k", "k"], + ["l", "l"], + ["m", "m"], + ["n", "n"], + ["o", "o"], + ["p", "p"], + ["q", "q"], + ["r", "r"], + ["s", "s"], + ["t", "t"], + ["u", "u"], + ["v", "v"], + ["w", "w"], + ["x", "x"], + ["y", "y"], + ["z", "z"], + ["0", "0"], + ["1", "1"], + ["2", "2"], + ["3", "3"], + ["4", "4"], + ["5", "5"], + ["6", "6"], + ["7", "7"], + ["8", "8"], + ["9", "9"], + ], + }, ], - "extensions": ["colours_sensing", "output_string"] + extensions: ["colours_sensing", "output_string"], }); - } + }, }; -Blockly.Blocks['sensing_mousedown'] = { +Blockly.Blocks["sensing_mousedown"] = { /** * Block to Report if the mouse is down. * @this Blockly.Block */ - init: function() { + init: function () { this.jsonInit({ - "message0": Blockly.Msg.SENSING_MOUSEDOWN, - "category": Categories.sensing, - "extensions": ["colours_sensing", "output_boolean"] + message0: Blockly.Msg.SENSING_MOUSEDOWN, + category: Categories.sensing, + extensions: ["colours_sensing", "output_boolean"], }); - } + }, }; -Blockly.Blocks['sensing_mousex'] = { +Blockly.Blocks["sensing_mousex"] = { /** * Block to report mouse's x position * @this Blockly.Block */ - init: function() { + init: function () { this.jsonInit({ - "message0": Blockly.Msg.SENSING_MOUSEX, - "category": Categories.sensing, - "extensions": ["colours_sensing", "output_number"] + message0: Blockly.Msg.SENSING_MOUSEX, + category: Categories.sensing, + extensions: ["colours_sensing", "output_number"], }); - } + }, }; -Blockly.Blocks['sensing_mousey'] = { +Blockly.Blocks["sensing_mousey"] = { /** * Block to report mouse's y position * @this Blockly.Block */ - init: function() { + init: function () { this.jsonInit({ - "message0": Blockly.Msg.SENSING_MOUSEY, - "category": Categories.sensing, - "extensions": ["colours_sensing", "output_number"] + message0: Blockly.Msg.SENSING_MOUSEY, + category: Categories.sensing, + extensions: ["colours_sensing", "output_number"], }); - } + }, }; -Blockly.Blocks['sensing_setdragmode'] = { +Blockly.Blocks["sensing_setdragmode"] = { /** * Block to set drag mode. * @this Blockly.Block */ - init: function() { + init: function () { this.jsonInit({ - "message0": Blockly.Msg.SENSING_SETDRAGMODE, - "args0": [ + message0: Blockly.Msg.SENSING_SETDRAGMODE, + args0: [ { - "type": "field_dropdown", - "name": "DRAG_MODE", - "options": [ - [Blockly.Msg.SENSING_SETDRAGMODE_DRAGGABLE, 'draggable'], - [Blockly.Msg.SENSING_SETDRAGMODE_NOTDRAGGABLE, 'not draggable'] - ] - } + type: "field_dropdown", + name: "DRAG_MODE", + options: [ + [Blockly.Msg.SENSING_SETDRAGMODE_DRAGGABLE, "draggable"], + [Blockly.Msg.SENSING_SETDRAGMODE_NOTDRAGGABLE, "not draggable"], + ], + }, ], - "category": Categories.sensing, - "extensions": ["colours_sensing", "shape_statement"] + category: Categories.sensing, + extensions: ["colours_sensing", "shape_statement"], }); - } + }, }; -Blockly.Blocks['sensing_loudness'] = { +Blockly.Blocks["sensing_loudness"] = { /** * Block to report loudness * @this Blockly.Block */ - init: function() { + init: function () { this.jsonInit({ - "message0": Blockly.Msg.SENSING_LOUDNESS, - "category": Categories.sensing, - "extensions": ["colours_sensing", "output_number"] + message0: Blockly.Msg.SENSING_LOUDNESS, + category: Categories.sensing, + extensions: ["colours_sensing", "output_number"], }); this.checkboxInFlyout = true; - } + }, }; -Blockly.Blocks['sensing_loud'] = { +Blockly.Blocks["sensing_loud"] = { /** * Block to report if the loudness is "loud" (greater than 10). This is an * obsolete block that is implemented for compatibility with Scratch 2.0 and * 1.4 projects. * @this Blockly.Block */ - init: function() { + init: function () { this.jsonInit({ - "message0": Blockly.Msg.SENSING_LOUD, - "category": Categories.sensing, - "extensions": ["colours_sensing", "output_boolean"] + message0: Blockly.Msg.SENSING_LOUD, + category: Categories.sensing, + extensions: ["colours_sensing", "output_boolean"], }); - } + }, }; -Blockly.Blocks['sensing_timer'] = { +Blockly.Blocks["sensing_timer"] = { /** * Block to report timer * @this Blockly.Block */ - init: function() { + init: function () { this.jsonInit({ - "message0": Blockly.Msg.SENSING_TIMER, - "category": Categories.sensing, - "extensions": ["colours_sensing", "output_number"] + message0: Blockly.Msg.SENSING_TIMER, + category: Categories.sensing, + extensions: ["colours_sensing", "output_number"], }); this.checkboxInFlyout = true; - } + }, }; -Blockly.Blocks['sensing_resettimer'] = { +Blockly.Blocks["sensing_resettimer"] = { /** * Block to reset timer * @this Blockly.Block */ - init: function() { + init: function () { this.jsonInit({ - "message0": Blockly.Msg.SENSING_RESETTIMER, - "category": Categories.sensing, - "extensions": ["colours_sensing", "shape_statement"] + message0: Blockly.Msg.SENSING_RESETTIMER, + category: Categories.sensing, + extensions: ["colours_sensing", "shape_statement"], }); - } + }, }; -Blockly.Blocks['sensing_of_object_menu'] = { +Blockly.Blocks["sensing_of_object_menu"] = { /** * "* of _" object menu. * @this Blockly.Block */ - init: function() { + init: function () { this.jsonInit({ - "message0": "%1", - "args0": [ + message0: "%1", + args0: [ { - "type": "field_dropdown", - "name": "OBJECT", - "options": [ - ['Sprite1', 'Sprite1'], - ['Stage', '_stage_'] - ] - } + type: "field_dropdown", + name: "OBJECT", + options: [ + ["Sprite1", "Sprite1"], + ["Stage", "_stage_"], + ], + }, ], - "category": Categories.sensing, - "extensions": ["colours_sensing", "output_string"] + category: Categories.sensing, + extensions: ["colours_sensing", "output_string"], }); - } + }, }; - -Blockly.Blocks['sensing_of'] = { +Blockly.Blocks["sensing_of"] = { /** * Block to report properties of sprites. * @this Blockly.Block */ - init: function() { + init: function () { this.jsonInit({ - "message0": Blockly.Msg.SENSING_OF, - "args0": [ + message0: Blockly.Msg.SENSING_OF, + args0: [ { - "type": "field_dropdown", - "name": "PROPERTY", - "options": [ - [Blockly.Msg.SENSING_OF_XPOSITION, 'x position'], - [Blockly.Msg.SENSING_OF_YPOSITION, 'y position'], - [Blockly.Msg.SENSING_OF_DIRECTION, 'direction'], - [Blockly.Msg.SENSING_OF_COSTUMENUMBER, 'costume #'], - [Blockly.Msg.SENSING_OF_COSTUMENAME, 'costume name'], - [Blockly.Msg.SENSING_OF_SIZE, 'size'], - [Blockly.Msg.SENSING_OF_VOLUME, 'volume'], - [Blockly.Msg.SENSING_OF_BACKDROPNUMBER, 'backdrop #'], - [Blockly.Msg.SENSING_OF_BACKDROPNAME, 'backdrop name'] - ] + type: "field_dropdown", + name: "PROPERTY", + options: [ + [Blockly.Msg.SENSING_OF_XPOSITION, "x position"], + [Blockly.Msg.SENSING_OF_YPOSITION, "y position"], + [Blockly.Msg.SENSING_OF_DIRECTION, "direction"], + [Blockly.Msg.SENSING_OF_COSTUMENUMBER, "costume #"], + [Blockly.Msg.SENSING_OF_COSTUMENAME, "costume name"], + [Blockly.Msg.SENSING_OF_SIZE, "size"], + [Blockly.Msg.SENSING_OF_VOLUME, "volume"], + [Blockly.Msg.SENSING_OF_BACKDROPNUMBER, "backdrop #"], + [Blockly.Msg.SENSING_OF_BACKDROPNAME, "backdrop name"], + ], }, { - "type": "input_value", - "name": "OBJECT" - } + type: "input_value", + name: "OBJECT", + }, ], - "output": true, - "category": Categories.sensing, - "outputShape": Blockly.OUTPUT_SHAPE_ROUND, - "extensions": ["colours_sensing"] + output: true, + category: Categories.sensing, + outputShape: Constants.OUTPUT_SHAPE_ROUND, + extensions: ["colours_sensing"], }); - } + }, }; -Blockly.Blocks['sensing_current'] = { +Blockly.Blocks["sensing_current"] = { /** * Block to Report the current option. * @this Blockly.Block */ - init: function() { + init: function () { this.jsonInit({ - "message0": Blockly.Msg.SENSING_CURRENT, - "args0": [ + message0: Blockly.Msg.SENSING_CURRENT, + args0: [ { - "type": "field_dropdown", - "name": "CURRENTMENU", - "options": [ - [Blockly.Msg.SENSING_CURRENT_YEAR, 'YEAR'], - [Blockly.Msg.SENSING_CURRENT_MONTH, 'MONTH'], - [Blockly.Msg.SENSING_CURRENT_DATE, 'DATE'], - [Blockly.Msg.SENSING_CURRENT_DAYOFWEEK, 'DAYOFWEEK'], - [Blockly.Msg.SENSING_CURRENT_HOUR, 'HOUR'], - [Blockly.Msg.SENSING_CURRENT_MINUTE, 'MINUTE'], - [Blockly.Msg.SENSING_CURRENT_SECOND, 'SECOND'] - ] - } + type: "field_dropdown", + name: "CURRENTMENU", + options: [ + [Blockly.Msg.SENSING_CURRENT_YEAR, "YEAR"], + [Blockly.Msg.SENSING_CURRENT_MONTH, "MONTH"], + [Blockly.Msg.SENSING_CURRENT_DATE, "DATE"], + [Blockly.Msg.SENSING_CURRENT_DAYOFWEEK, "DAYOFWEEK"], + [Blockly.Msg.SENSING_CURRENT_HOUR, "HOUR"], + [Blockly.Msg.SENSING_CURRENT_MINUTE, "MINUTE"], + [Blockly.Msg.SENSING_CURRENT_SECOND, "SECOND"], + ], + }, ], - "category": Categories.sensing, - "extensions": ["colours_sensing", "output_number"] + category: Categories.sensing, + extensions: ["colours_sensing", "output_number"], }); this.checkboxInFlyout = true; - } + }, }; -Blockly.Blocks['sensing_dayssince2000'] = { +Blockly.Blocks["sensing_dayssince2000"] = { /** * Block to report days since 2000 * @this Blockly.Block */ - init: function() { + init: function () { this.jsonInit({ - "message0": Blockly.Msg.SENSING_DAYSSINCE2000, - "category": Categories.sensing, - "extensions": ["colours_sensing", "output_number"] + message0: Blockly.Msg.SENSING_DAYSSINCE2000, + category: Categories.sensing, + extensions: ["colours_sensing", "output_number"], }); - } + }, }; -Blockly.Blocks['sensing_username'] = { +Blockly.Blocks["sensing_username"] = { /** * Block to report user's username * @this Blockly.Block */ - init: function() { + init: function () { this.jsonInit({ - "message0": Blockly.Msg.SENSING_USERNAME, - "category": Categories.sensing, - "extensions": ["colours_sensing", "output_number"] + message0: Blockly.Msg.SENSING_USERNAME, + category: Categories.sensing, + extensions: ["colours_sensing", "output_number"], }); this.checkboxInFlyout = true; - } + }, }; -Blockly.Blocks['sensing_userid'] = { +Blockly.Blocks["sensing_userid"] = { /** * Block to report user's ID. Does not actually do anything. This is an * obsolete block that is implemented for compatibility with Scratch 2.0 * projects. * @this Blockly.Block */ - init: function() { + init: function () { this.jsonInit({ - "message0": Blockly.Msg.SENSING_USERID, - "category": Categories.sensing, - "extensions": ["colours_sensing", "output_number"] + message0: Blockly.Msg.SENSING_USERID, + category: Categories.sensing, + extensions: ["colours_sensing", "output_number"], }); - } + }, }; diff --git a/blocks_vertical/vertical_extensions.js b/blocks_vertical/vertical_extensions.js index 89a046b9d3..f234e68cb5 100644 --- a/blocks_vertical/vertical_extensions.js +++ b/blocks_vertical/vertical_extensions.js @@ -28,6 +28,7 @@ import * as Blockly from "blockly/core"; import { Colours } from "../core/colours.js"; import { ScratchProcedures } from "../src/procedures.js"; +import * as Constants from "../src/constants.js"; const VerticalExtensions = {}; /** @@ -132,7 +133,7 @@ VerticalExtensions.SHAPE_END = function () { */ VerticalExtensions.OUTPUT_NUMBER = function () { this.setInputsInline(true); - this.setOutputShape(Blockly.OUTPUT_SHAPE_ROUND); + this.setOutputShape(Constants.OUTPUT_SHAPE_ROUND); this.setOutput(true, "Number"); }; @@ -145,7 +146,7 @@ VerticalExtensions.OUTPUT_NUMBER = function () { */ VerticalExtensions.OUTPUT_STRING = function () { this.setInputsInline(true); - this.setOutputShape(Blockly.OUTPUT_SHAPE_ROUND); + this.setOutputShape(Constants.OUTPUT_SHAPE_ROUND); this.setOutput(true, "String"); }; @@ -158,7 +159,7 @@ VerticalExtensions.OUTPUT_STRING = function () { */ VerticalExtensions.OUTPUT_BOOLEAN = function () { this.setInputsInline(true); - this.setOutputShape(Blockly.OUTPUT_SHAPE_HEXAGONAL); + this.setOutputShape(Constants.OUTPUT_SHAPE_HEXAGONAL); this.setOutput(true, "Boolean"); }; diff --git a/core/scratch_blocks_utils.js b/core/scratch_blocks_utils.js index 4780bf2126..903c7b4583 100644 --- a/core/scratch_blocks_utils.js +++ b/core/scratch_blocks_utils.js @@ -22,40 +22,7 @@ * @fileoverview Utility methods for Scratch Blocks but not Blockly. * @author fenichel@google.com (Rachel Fenichel) */ -import * as Blockly from 'blockly/core'; - -/** - * Measure some text using a canvas in-memory. - * Does not exist in Blockly, but needed in scratch-blocks - * @param {string} fontSize E.g., '10pt' - * @param {string} fontFamily E.g., 'Arial' - * @param {string} fontWeight E.g., '600' - * @param {string} text The actual text to measure - * @return {number} Width of the text in px. - * @package - */ -export function measureText(fontSize, fontFamily, - fontWeight, text) { - var canvas = document.createElement('canvas'); - var context = canvas.getContext('2d'); - context.font = fontWeight + ' ' + fontSize + ' ' + fontFamily; - return context.measureText(text).width; -}; - -/** - * Encode a string's HTML entities. - * E.g., -> <a> - * Does not exist in Blockly, but needed in scratch-blocks - * @param {string} rawStr Unencoded raw string to encode. - * @return {string} String with HTML entities encoded. - * @package - */ -export function encodeEntities(rawStr) { - // CC-BY-SA https://stackoverflow.com/questions/18749591/encode-html-entities-in-javascript - return rawStr.replace(/[\u00A0-\u9999<>&]/gim, function(i) { - return '&#' + i.charCodeAt(0) + ';'; - }); -}; +import * as Blockly from "blockly/core"; /** * Re-assign obscured shadow blocks new IDs to prevent collisions @@ -72,28 +39,13 @@ export function changeObscuredShadowIds(block) { if (connection) { var shadowDom = connection.getShadowDom(); if (shadowDom) { - shadowDom.setAttribute('id', Blockly.utils.genUid()); + shadowDom.setAttribute("id", Blockly.utils.genUid()); connection.setShadowDom(shadowDom); } } } } -}; - -/** - * Whether a block is both a shadow block and an argument reporter. These - * blocks have special behaviour in scratch-blocks: they're duplicated when - * dragged, and they are rendered slightly differently from normal shadow - * blocks. - * @param {!Blockly.BlockSvg} block The block that should be used to make this - * decision. - * @return {boolean} True if the block should be duplicated on drag. - * @package - */ -export function isShadowArgumentReporter(block) { - return (block.isShadow() && (block.type == 'argument_reporter_boolean' || - block.type == 'argument_reporter_string_number')); -}; +} /** * Compare strings with natural number sorting. @@ -103,51 +55,10 @@ export function isShadowArgumentReporter(block) { */ export function compareStrings(str1, str2) { return str1.localeCompare(str2, [], { - sensitivity: 'base', - numeric: true + sensitivity: "base", + numeric: true, }); -}; - -/** - * Determine if this block can be recycled in the flyout. Blocks that have no - * variablees and are not dynamic shadows can be recycled. - * @param {Blockly.Block} block The block to check. - * @return {boolean} True if the block can be recycled. - * @package - */ -export function blockIsRecyclable(block) { - // If the block needs to parse mutations, never recycle. - if (block.mutationToDom && block.domToMutation) { - return false; - } - - for (var i = 0; i < block.inputList.length; i++) { - var input = block.inputList[i]; - for (var j = 0; j < input.fieldRow.length; j++) { - var field = input.fieldRow[j]; - // No variables. - if (field instanceof Blockly.FieldVariable || - field instanceof Blockly.FieldVariableGetter) { - return false; - } - if (field instanceof Blockly.FieldDropdown || - field instanceof Blockly.FieldNumberDropdown || - field instanceof Blockly.FieldTextDropdown) { - if (field.isOptionListDynamic()) { - return false; - } - } - } - // Check children. - if (input.connection) { - var child = input.connection.targetBlock(); - if (child && !blockIsRecyclable(child)) { - return false; - } - } - } - return true; -}; +} /** * Creates a callback function for a click on the "duplicate" context menu @@ -161,14 +72,15 @@ export function blockIsRecyclable(block) { * @package */ export function duplicateAndDragCallback(oldBlock, event) { - var isMouseEvent = Blockly.Touch.getTouchIdentifierFromEvent(event) === 'mouse'; - return function(e) { + var isMouseEvent = + Blockly.Touch.getTouchIdentifierFromEvent(event) === "mouse"; + return function (e) { // Give the context menu a chance to close. - setTimeout(function() { + setTimeout(function () { var ws = oldBlock.workspace; var svgRootOld = oldBlock.getSvgRoot(); if (!svgRootOld) { - throw new Error('oldBlock is not rendered.'); + throw new Error("oldBlock is not rendered."); } // Create the new block by cloning the block in the flyout (via XML). @@ -191,7 +103,7 @@ export function duplicateAndDragCallback(oldBlock, event) { var svgRootNew = newBlock.getSvgRoot(); if (!svgRootNew) { - throw new Error('newBlock is not rendered.'); + throw new Error("newBlock is not rendered."); } // The position of the old block in workspace coordinates. @@ -220,17 +132,17 @@ export function duplicateAndDragCallback(oldBlock, event) { var fakeEvent = { clientX: event.clientX, clientY: event.clientY, - type: 'mousedown', - preventDefault: function() { + type: "mousedown", + preventDefault: function () { e.preventDefault(); }, - stopPropagation: function() { + stopPropagation: function () { e.stopPropagation(); }, - target: e.target + target: e.target, }; ws.startDragWithFakeEvent(fakeEvent, newBlock); } }, 0); }; -}; +} diff --git a/src/constants.js b/src/constants.js index 89c4635063..ebee4147ab 100644 --- a/src/constants.js +++ b/src/constants.js @@ -46,6 +46,9 @@ export { PROCEDURES_PROTOTYPE_BLOCK_TYPE }; const PROCEDURES_CALL_BLOCK_TYPE = "procedures_call"; export { PROCEDURES_CALL_BLOCK_TYPE }; +const OUTPUT_SHAPE_HEXAGONAL = 1; +export { OUTPUT_SHAPE_HEXAGONAL }; + const OUTPUT_SHAPE_ROUND = 2; export { OUTPUT_SHAPE_ROUND }; @@ -58,10 +61,3 @@ export { OUTPUT_SHAPE_ROUND }; */ const NEW_BROADCAST_MESSAGE_ID = "NEW_BROADCAST_MESSAGE_ID"; export { NEW_BROADCAST_MESSAGE_ID }; - -/** - * String for use in the dropdown created in field_variable. - * This string indicates that this option in the dropdown is 'Rename - * variable...' and if selected, should trigger the prompt to rename a variable. - */ -export const RENAME_VARIABLE_ID = "RENAME_VARIABLE_ID"; diff --git a/src/field_variable.js b/src/field_variable.js index bd278c7a4f..6c3f16b973 100644 --- a/src/field_variable.js +++ b/src/field_variable.js @@ -128,7 +128,7 @@ class FieldVariable extends Blockly.FieldVariable { Constants.BROADCAST_MESSAGE_VARIABLE_TYPE ); return; - } else if (selectedItem === Constants.RENAME_VARIABLE_ID) { + } else if (selectedItem === Blockly.RENAME_VARIABLE_ID) { renameVariable(sourceBlock.workspace, this.variable); return; } From 7a8593775830bbf8d4e87cde69e30f9747301180 Mon Sep 17 00:00:00 2001 From: Aaron Dodson Date: Thu, 22 Aug 2024 12:06:33 -0700 Subject: [PATCH 072/130] chore: clean up and reorganize the repo (#134) * chore: move FieldVerticalSeparator into src * chore: move FieldColoudSlider into src * chore: move FieldMatrix into src * chore: move FieldNote into src * chore: move FieldNumber into src * chore: move FieldVariable into src/fields * chore: move FieldVariableGetter into src/fields * chore: import fields from their new paths * chore: fix imports in FieldVariable * chore: format FieldNumber * chore: fix imports in FieldNumber * chore: move event classes into events directory * chore: fix event imports * chore: fix importing events * chore: move css.js into src * chore: move colours.js into src * chore: format files referencing colours.js * chore: fix imports of colours.js * chore: move scratch_blocks_utils.js into src * chore: move field_textinput_removable.js into src * chore: only import core Blockly * chore: move block definitions into src/blocks * chore: delete unused block files * chore: fix block imports * chore: delete the unused horizontal block definitions * chore: delete old build/import tooling * chore: format files --- blocks_horizontal/control.js | 212 ------ blocks_horizontal/default_toolbox.js | 139 ---- blocks_horizontal/event.js | 190 ------ blocks_horizontal/wedo.js | 325 --------- blocks_vertical/control.js | 512 -------------- blocks_vertical/default_toolbox.js | 564 ---------------- blocks_vertical/event.js | 323 --------- blocks_vertical/extensions.js | 294 -------- blocks_vertical/looks.js | 576 ---------------- blocks_vertical/motion.js | 571 ---------------- blocks_vertical/operators.js | 463 ------------- blocks_vertical/sound.js | 210 ------ build.py | 636 ------------------ build/gen_blocks.js | 1 - build/test_expect.js | 1 - build/test_input.js | 1 - cleanup.sh | 101 --- core/colours.js | 173 ----- local_build.sh | 70 -- pull_from_blockly.sh | 151 ----- ...compressed_horizontal-blocks_compressed.js | 1 - shim/blockly_compressed_horizontal.Blockly.js | 1 - shim/blockly_compressed_horizontal.goog.js | 1 - shim/blockly_compressed_horizontal.js | 1 - ...y_compressed_vertical-blocks_compressed.js | 1 - shim/blockly_compressed_vertical.Blockly.js | 1 - shim/blockly_compressed_vertical.goog.js | 1 - shim/blockly_compressed_vertical.js | 1 - ...-blockly_compressed_horizontal-messages.js | 1 - shim/blocks_compressed_horizontal.js | 1 - ...al-blockly_compressed_vertical-messages.js | 1 - shim/blocks_compressed_vertical.js | 1 - shim/gh-pages.js | 1 - shim/horizontal.js | 1 - shim/index.js | 17 - shim/vertical.js | 1 - src/block_reporting.js | 19 +- {blocks_common => src/blocks}/colour.js | 28 +- src/blocks/control.js | 513 ++++++++++++++ {blocks_vertical => src/blocks}/data.js | 6 +- src/blocks/event.js | 320 +++++++++ src/blocks/looks.js | 574 ++++++++++++++++ {blocks_common => src/blocks}/math.js | 4 +- {blocks_common => src/blocks}/matrix.js | 26 +- src/blocks/motion.js | 570 ++++++++++++++++ {blocks_common => src/blocks}/note.js | 36 +- src/blocks/operators.js | 463 +++++++++++++ {blocks_vertical => src/blocks}/procedures.js | 4 +- {blocks_vertical => src/blocks}/sensing.js | 4 +- src/blocks/sound.js | 209 ++++++ {blocks_common => src/blocks}/text.js | 30 +- .../blocks}/vertical_extensions.js | 6 +- src/categories.js | 24 +- src/checkable_continuous_flyout.js | 2 +- src/colours.js | 179 +++++ src/context_menu_items.js | 8 +- {core => src}/css.js | 0 src/{ => events}/events_block_comment_base.js | 0 .../events_block_comment_change.js | 0 .../events_block_comment_collapse.js | 0 .../events_block_comment_create.js | 0 .../events_block_comment_delete.js | 0 src/{ => events}/events_block_comment_move.js | 0 .../events_block_comment_resize.js | 0 src/{ => events}/events_block_drag_end.js | 0 src/{ => events}/events_block_drag_outside.js | 0 .../events_scratch_variable_create.js | 0 {core => src/fields}/field_colour_slider.js | 172 +++-- {core => src/fields}/field_matrix.js | 308 +++++---- {core => src/fields}/field_note.js | 430 +++++++----- {core => src/fields}/field_number.js | 175 +++-- .../fields}/field_textinput_removable.js | 35 +- src/{ => fields}/field_variable.js | 6 +- src/{ => fields}/field_variable_getter.js | 0 .../fields}/field_vertical_separator.js | 48 +- src/glows.js | 128 ++-- src/index.js | 66 +- src/procedures.js | 2 +- {core => src}/scratch_blocks_utils.js | 0 src/scratch_continuous_category.js | 16 +- src/scratch_continuous_toolbox.js | 4 +- src/scratch_dragger.js | 4 +- src/shadows.js | 79 ++- 83 files changed, 3829 insertions(+), 6214 deletions(-) delete mode 100644 blocks_horizontal/control.js delete mode 100644 blocks_horizontal/default_toolbox.js delete mode 100644 blocks_horizontal/event.js delete mode 100644 blocks_horizontal/wedo.js delete mode 100644 blocks_vertical/control.js delete mode 100644 blocks_vertical/default_toolbox.js delete mode 100644 blocks_vertical/event.js delete mode 100644 blocks_vertical/extensions.js delete mode 100644 blocks_vertical/looks.js delete mode 100644 blocks_vertical/motion.js delete mode 100644 blocks_vertical/operators.js delete mode 100644 blocks_vertical/sound.js delete mode 100755 build.py delete mode 100644 build/gen_blocks.js delete mode 100644 build/test_expect.js delete mode 100644 build/test_input.js delete mode 100755 cleanup.sh delete mode 100644 core/colours.js delete mode 100755 local_build.sh delete mode 100755 pull_from_blockly.sh delete mode 100644 shim/blockly_compressed_horizontal-blocks_compressed.js delete mode 100644 shim/blockly_compressed_horizontal.Blockly.js delete mode 100644 shim/blockly_compressed_horizontal.goog.js delete mode 100644 shim/blockly_compressed_horizontal.js delete mode 100644 shim/blockly_compressed_vertical-blocks_compressed.js delete mode 100644 shim/blockly_compressed_vertical.Blockly.js delete mode 100644 shim/blockly_compressed_vertical.goog.js delete mode 100644 shim/blockly_compressed_vertical.js delete mode 100644 shim/blocks_compressed_horizontal-blockly_compressed_horizontal-messages.js delete mode 100644 shim/blocks_compressed_horizontal.js delete mode 100644 shim/blocks_compressed_vertical-blockly_compressed_vertical-messages.js delete mode 100644 shim/blocks_compressed_vertical.js delete mode 100644 shim/gh-pages.js delete mode 100644 shim/horizontal.js delete mode 100644 shim/index.js delete mode 100644 shim/vertical.js rename {blocks_common => src/blocks}/colour.js (70%) create mode 100644 src/blocks/control.js rename {blocks_vertical => src/blocks}/data.js (99%) create mode 100644 src/blocks/event.js create mode 100644 src/blocks/looks.js rename {blocks_common => src/blocks}/math.js (97%) rename {blocks_common => src/blocks}/matrix.js (70%) create mode 100644 src/blocks/motion.js rename {blocks_common => src/blocks}/note.js (61%) create mode 100644 src/blocks/operators.js rename {blocks_vertical => src/blocks}/procedures.js (99%) rename {blocks_vertical => src/blocks}/sensing.js (99%) create mode 100644 src/blocks/sound.js rename {blocks_common => src/blocks}/text.js (67%) rename {blocks_vertical => src/blocks}/vertical_extensions.js (98%) create mode 100644 src/colours.js rename {core => src}/css.js (100%) rename src/{ => events}/events_block_comment_base.js (100%) rename src/{ => events}/events_block_comment_change.js (100%) rename src/{ => events}/events_block_comment_collapse.js (100%) rename src/{ => events}/events_block_comment_create.js (100%) rename src/{ => events}/events_block_comment_delete.js (100%) rename src/{ => events}/events_block_comment_move.js (100%) rename src/{ => events}/events_block_comment_resize.js (100%) rename src/{ => events}/events_block_drag_end.js (100%) rename src/{ => events}/events_block_drag_outside.js (100%) rename src/{ => events}/events_scratch_variable_create.js (100%) rename {core => src/fields}/field_colour_slider.js (66%) rename {core => src/fields}/field_matrix.js (61%) rename {core => src/fields}/field_note.js (67%) rename {core => src/fields}/field_number.js (69%) rename {core => src/fields}/field_textinput_removable.js (79%) rename src/{ => fields}/field_variable.js (96%) rename src/{ => fields}/field_variable_getter.js (100%) rename {core => src/fields}/field_vertical_separator.js (78%) rename {core => src}/scratch_blocks_utils.js (100%) diff --git a/blocks_horizontal/control.js b/blocks_horizontal/control.js deleted file mode 100644 index 8fd7cf20a2..0000000000 --- a/blocks_horizontal/control.js +++ /dev/null @@ -1,212 +0,0 @@ -/** - * @license - * Visual Blocks Editor - * - * Copyright 2016 Massachusetts Institute of Technology - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @fileoverview Control blocks for Scratch (Horizontal) - * @author ascii@media.mit.edu - */ -'use strict'; - -goog.provide('Blockly.Blocks.control'); - -goog.require('Blockly.Blocks'); - -goog.require('Blockly.Colours'); - -Blockly.Blocks['control_repeat'] = { - /** - * Block for repeat n times (external number). - * https://blockly-demo.appspot.com/static/demos/blockfactory/index.html#so57n9 - * @this Blockly.Block - */ - init: function() { - this.jsonInit({ - "id": "control_repeat", - "message0": "%1 %2 %3", - "args0": [ - { - "type": "input_statement", - "name": "SUBSTACK" - }, - { - "type": "field_image", - "src": Blockly.mainWorkspace.options.pathToMedia + "icons/control_repeat.svg", - "width": 40, - "height": 40, - "alt": "*", - "flip_rtl": true - }, - { - "type": "input_value", - "name": "TIMES", - "check": "Number" - } - ], - "inputsInline": true, - "previousStatement": null, - "nextStatement": null, - "category": Blockly.Categories.control, - "colour": Blockly.Colours.control.primary, - "colourSecondary": Blockly.Colours.control.secondary, - "colourTertiary": Blockly.Colours.control.tertiary, - "colourQuaternary": Blockly.Colours.control.quaternary - }); - } -}; - -Blockly.Blocks['control_forever'] = { - /** - * Block for repeat n times (external number). - * https://blockly-demo.appspot.com/static/demos/blockfactory/index.html#5eke39 - * @this Blockly.Block - */ - init: function() { - this.jsonInit({ - "id": "control_forever", - "message0": "%1 %2", - "args0": [ - { - "type": "input_statement", - "name": "SUBSTACK" - }, - { - "type": "field_image", - "src": Blockly.mainWorkspace.options.pathToMedia + "icons/control_forever.svg", - "width": 40, - "height": 40, - "alt": "*", - "flip_rtl": true - } - ], - "inputsInline": true, - "previousStatement": null, - "category": Blockly.Categories.control, - "colour": Blockly.Colours.control.primary, - "colourSecondary": Blockly.Colours.control.secondary, - "colourTertiary": Blockly.Colours.control.tertiary, - "colourQuaternary": Blockly.Colours.control.quaternary - }); - } -}; - -Blockly.Blocks['control_repeat'] = { - /** - * Block for repeat n times (external number). - * https://blockly-demo.appspot.com/static/demos/blockfactory/index.html#so57n9 - * @this Blockly.Block - */ - init: function() { - this.jsonInit({ - "id": "control_repeat", - "message0": "%1 %2 %3", - "args0": [ - { - "type": "input_statement", - "name": "SUBSTACK" - }, - { - "type": "field_image", - "src": Blockly.mainWorkspace.options.pathToMedia + "icons/control_repeat.svg", - "width": 40, - "height": 40, - "alt": "*", - "flip_rtl": true - }, - { - "type": "input_value", - "name": "TIMES", - "check": "Number" - } - ], - "inputsInline": true, - "previousStatement": null, - "nextStatement": null, - "category": Blockly.Categories.control, - "colour": Blockly.Colours.control.primary, - "colourSecondary": Blockly.Colours.control.secondary, - "colourTertiary": Blockly.Colours.control.tertiary, - "colourQuaternary": Blockly.Colours.control.quaternary - }); - } -}; - -Blockly.Blocks['control_stop'] = { - /** - * Block for stop all scripts. - * @this Blockly.Block - */ - init: function() { - this.jsonInit({ - "id": "control_stop", - "message0": "%1", - "args0": [ - { - "type": "field_image", - "src": Blockly.mainWorkspace.options.pathToMedia + "icons/control_stop.svg", - "width": 40, - "height": 40, - "alt": "Stop" - } - ], - "inputsInline": true, - "previousStatement": null, - "category": Blockly.Categories.control, - "colour": Blockly.Colours.control.primary, - "colourSecondary": Blockly.Colours.control.secondary, - "colourTertiary": Blockly.Colours.control.tertiary, - "colourQuaternary": Blockly.Colours.control.quaternary - }); - } -}; - -Blockly.Blocks['control_wait'] = { - /** - * Block to wait (pause) stack. - * @this Blockly.Block - */ - init: function() { - this.jsonInit({ - "id": "control_wait", - "message0": "%1 %2", - "args0": [ - { - "type": "field_image", - "src": Blockly.mainWorkspace.options.pathToMedia + "icons/control_wait.svg", - "width": 40, - "height": 40, - "alt": "Wait" - }, - { - "type": "input_value", - "name": "DURATION", - "check": "Number" - } - ], - "inputsInline": true, - "previousStatement": null, - "nextStatement": null, - "category": Blockly.Categories.control, - "colour": Blockly.Colours.control.primary, - "colourSecondary": Blockly.Colours.control.secondary, - "colourTertiary": Blockly.Colours.control.tertiary, - "colourQuaternary": Blockly.Colours.control.quaternary - }); - } -}; diff --git a/blocks_horizontal/default_toolbox.js b/blocks_horizontal/default_toolbox.js deleted file mode 100644 index f5fd741c52..0000000000 --- a/blocks_horizontal/default_toolbox.js +++ /dev/null @@ -1,139 +0,0 @@ -/** - * @license - * Visual Blocks Editor - * - * Copyright 2016 Massachusetts Institute of Technology - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -'use strict'; - -goog.provide('Blockly.Blocks.defaultToolbox'); - -goog.require('Blockly.Blocks'); - -/** - * @fileoverview Provide a default toolbox XML. - */ - -Blockly.Blocks.defaultToolbox = ''; - -Blockly.Blocks.defaultToolboxSimple = ''; diff --git a/blocks_horizontal/event.js b/blocks_horizontal/event.js deleted file mode 100644 index faada4fbfd..0000000000 --- a/blocks_horizontal/event.js +++ /dev/null @@ -1,190 +0,0 @@ -/** - * @license - * Visual Blocks Editor - * - * Copyright 2016 Massachusetts Institute of Technology - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @fileoverview Control blocks for Scratch (Horizontal) - * @author ascii@media.mit.edu - */ -'use strict'; - -goog.provide('Blockly.Blocks.event'); - -goog.require('Blockly.Blocks'); - -goog.require('Blockly.Colours'); - -Blockly.Blocks['event_whenflagclicked'] = { - /** - * Block for when flag clicked. - * @this Blockly.Block - */ - init: function() { - this.jsonInit({ - "id": "event_whenflagclicked", - "message0": "%1", - "args0": [ - { - "type": "field_image", - "src": Blockly.mainWorkspace.options.pathToMedia + "icons/event_whenflagclicked.svg", - "width": 40, - "height": 40, - "alt": "When green flag clicked", - "flip_rtl": true - } - ], - "inputsInline": true, - "nextStatement": null, - "category": Blockly.Categories.event, - "colour": Blockly.Colours.event.primary, - "colourSecondary": Blockly.Colours.event.secondary, - "colourTertiary": Blockly.Colours.event.tertiary, - "colourQuaternary": Blockly.Colours.event.quaternary - }); - } -}; - -Blockly.Blocks['dropdown_whenbroadcast'] = { - /** - * Block for when broadcast dropdown (used for shadow). - * @this Blockly.Block - */ - init: function() { - this.appendDummyInput() - .appendField(new Blockly.FieldIconMenu( - [ - {src: Blockly.mainWorkspace.options.pathToMedia + 'icons/event_when-broadcast-received_blue.svg', - value: 'blue', width: 48, height: 48, alt: 'Blue'}, - {src: Blockly.mainWorkspace.options.pathToMedia + 'icons/event_when-broadcast-received_green.svg', - value: 'green', width: 48, height: 48, alt: 'Green'}, - {src: Blockly.mainWorkspace.options.pathToMedia + 'icons/event_when-broadcast-received_coral.svg', - value: 'coral', width: 48, height: 48, alt: 'Coral'}, - {src: Blockly.mainWorkspace.options.pathToMedia + 'icons/event_when-broadcast-received_magenta.svg', - value: 'magenta', width: 48, height: 48, alt: 'Magenta'}, - {src: Blockly.mainWorkspace.options.pathToMedia + 'icons/event_when-broadcast-received_orange.svg', - value: 'orange', width: 48, height: 48, alt: 'Orange'}, - {src: Blockly.mainWorkspace.options.pathToMedia + 'icons/event_when-broadcast-received_purple.svg', - value: 'purple', width: 48, height: 48, alt: 'Purple'} - ]), 'CHOICE'); - this.setOutput(true); - this.setColour(Blockly.Colours.event.primary, - Blockly.Colours.event.secondary, - Blockly.Colours.event.tertiary, - Blockly.Colours.event.quaternary - ); - } -}; - -Blockly.Blocks['event_whenbroadcastreceived'] = { - /** - * Block for when broadcast received. - * @this Blockly.Block - */ - init: function() { - this.jsonInit({ - "id": "event_whenbroadcastreceived", - "message0": "%1 %2", - "args0": [ - { - "type": "field_image", - "src": Blockly.mainWorkspace.options.pathToMedia + "icons/event_when-broadcast-received_blue.svg", - "width": 40, - "height": 40, - "alt": "Broadcast received" - }, - { - "type": "input_value", - "name": "CHOICE" - } - ], - "inputsInline": true, - "nextStatement": null, - "category": Blockly.Categories.event, - "colour": Blockly.Colours.event.primary, - "colourSecondary": Blockly.Colours.event.secondary, - "colourTertiary": Blockly.Colours.event.tertiary, - "colourQuaternary": Blockly.Colours.event.quaternary - }); - } -}; - -Blockly.Blocks['dropdown_broadcast'] = { - /** - * Block for broadcast dropdown (used for shadow). - * @this Blockly.Block - */ - init: function() { - this.appendDummyInput() - .appendField(new Blockly.FieldIconMenu( - [ - {src: Blockly.mainWorkspace.options.pathToMedia + 'icons/event_broadcast_blue.svg', - value: 'blue', width: 48, height: 48, alt: 'Blue'}, - {src: Blockly.mainWorkspace.options.pathToMedia + 'icons/event_broadcast_green.svg', - value: 'green', width: 48, height: 48, alt: 'Green'}, - {src: Blockly.mainWorkspace.options.pathToMedia + 'icons/event_broadcast_coral.svg', - value: 'coral', width: 48, height: 48, alt: 'Coral'}, - {src: Blockly.mainWorkspace.options.pathToMedia + 'icons/event_broadcast_magenta.svg', - value: 'magenta', width: 48, height: 48, alt: 'Magenta'}, - {src: Blockly.mainWorkspace.options.pathToMedia + 'icons/event_broadcast_orange.svg', - value: 'orange', width: 48, height: 48, alt: 'Orange'}, - {src: Blockly.mainWorkspace.options.pathToMedia + 'icons/event_broadcast_purple.svg', - value: 'purple', width: 48, height: 48, alt: 'Purple'} - ]), 'CHOICE'); - this.setOutput(true); - this.setColour(Blockly.Colours.event.primary, - Blockly.Colours.event.secondary, - Blockly.Colours.event.tertiary, - Blockly.Colours.event.quaternary - ); - } -}; - -Blockly.Blocks['event_broadcast'] = { - /** - * Block to send a broadcast. - * @this Blockly.Block - */ - init: function() { - this.jsonInit({ - "id": "event_broadcast", - "message0": "%1 %2", - "args0": [ - { - "type": "field_image", - "src": Blockly.mainWorkspace.options.pathToMedia + "icons/event_broadcast_blue.svg", - "width": 40, - "height": 40, - "alt": "Broadcast" - }, - { - "type": "input_value", - "name": "CHOICE" - } - ], - "inputsInline": true, - "previousStatement": null, - "nextStatement": null, - "category": Blockly.Categories.event, - "colour": Blockly.Colours.event.primary, - "colourSecondary": Blockly.Colours.event.secondary, - "colourTertiary": Blockly.Colours.event.tertiary, - "colourQuaternary": Blockly.Colours.event.quaternary - }); - } -}; diff --git a/blocks_horizontal/wedo.js b/blocks_horizontal/wedo.js deleted file mode 100644 index 723fa9db65..0000000000 --- a/blocks_horizontal/wedo.js +++ /dev/null @@ -1,325 +0,0 @@ -/** - * @license - * Visual Blocks Editor - * - * Copyright 2016 Massachusetts Institute of Technology - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @fileoverview Wedo blocks for Scratch (Horizontal) - * @author ascii@media.mit.edu - */ -'use strict'; - -goog.provide('Blockly.Blocks.wedo'); - -goog.require('Blockly.Blocks'); - -goog.require('Blockly.Colours'); - -Blockly.Blocks['dropdown_wedo_setcolor'] = { - /** - * Block for set color drop-down (used for shadow). - * @this Blockly.Block - */ - init: function() { - this.appendDummyInput() - .appendField(new Blockly.FieldIconMenu( - [ - {src: Blockly.mainWorkspace.options.pathToMedia + 'icons/set-led_mystery.svg', - value: 'mystery', width: 48, height: 48, alt: 'Mystery'}, - {src: Blockly.mainWorkspace.options.pathToMedia + 'icons/set-led_yellow.svg', - value: 'yellow', width: 48, height: 48, alt: 'Yellow'}, - {src: Blockly.mainWorkspace.options.pathToMedia + 'icons/set-led_orange.svg', - value: 'orange', width: 48, height: 48, alt: 'Orange'}, - {src: Blockly.mainWorkspace.options.pathToMedia + 'icons/set-led_coral.svg', - value: 'coral', width: 48, height: 48, alt: 'Coral'}, - {src: Blockly.mainWorkspace.options.pathToMedia + 'icons/set-led_magenta.svg', - value: 'magenta', width: 48, height: 48, alt: 'Magenta'}, - {src: Blockly.mainWorkspace.options.pathToMedia + 'icons/set-led_purple.svg', - value: 'purple', width: 48, height: 48, alt: 'Purple'}, - {src: Blockly.mainWorkspace.options.pathToMedia + 'icons/set-led_blue.svg', - value: 'blue', width: 48, height: 48, alt: 'Blue'}, - {src: Blockly.mainWorkspace.options.pathToMedia + 'icons/set-led_green.svg', - value: 'green', width: 48, height: 48, alt: 'Green'}, - {src: Blockly.mainWorkspace.options.pathToMedia + 'icons/set-led_white.svg', - value: 'white', width: 48, height: 48, alt: 'White'} - ]), 'CHOICE'); - this.setOutput(true); - this.setColour(Blockly.Colours.looks.primary, - Blockly.Colours.looks.secondary, - Blockly.Colours.looks.tertiary, - Blockly.Colours.looks.quaternary - ); - } -}; - -Blockly.Blocks['wedo_setcolor'] = { - /** - * Block to set color of LED - * @this Blockly.Block - */ - init: function() { - this.jsonInit({ - "id": "wedo_setcolor", - "message0": "%1 %2", - "args0": [ - { - "type": "field_image", - "src": Blockly.mainWorkspace.options.pathToMedia + "icons/set-led_blue.svg", - "width": 40, - "height": 40, - "alt": "Set LED Color" - }, - { - "type": "input_value", - "name": "CHOICE" - } - ], - "inputsInline": true, - "previousStatement": null, - "nextStatement": null, - "category": Blockly.Categories.looks, - "colour": Blockly.Colours.looks.primary, - "colourSecondary": Blockly.Colours.looks.secondary, - "colourTertiary": Blockly.Colours.looks.tertiary, - "colourQuaternary": Blockly.Colours.looks.quaternary - }); - } -}; - -Blockly.Blocks['wedo_motorclockwise'] = { - /** - * Block to spin motor clockwise. - * @this Blockly.Block - */ - init: function() { - this.jsonInit({ - "id": "wedo_motorclockwise", - "message0": "%1 %2", - "args0": [ - { - "type": "field_image", - "src": Blockly.mainWorkspace.options.pathToMedia + "icons/wedo_motor-clockwise.svg", - "width": 40, - "height": 40, - "alt": "Turn motor clockwise" - }, - { - "type": "input_value", - "name": "DURATION", - "check": "Number" - } - ], - "inputsInline": true, - "previousStatement": null, - "nextStatement": null, - "category": Blockly.Categories.motion, - "colour": Blockly.Colours.motion.primary, - "colourSecondary": Blockly.Colours.motion.secondary, - "colourTertiary": Blockly.Colours.motion.tertiary, - "colourQuaternary": Blockly.Colours.motion.quaternary - }); - } -}; - -Blockly.Blocks['wedo_motorcounterclockwise'] = { - /** - * Block to spin motor counter-clockwise. - * @this Blockly.Block - */ - init: function() { - this.jsonInit({ - "id": "wedo_motorcounterclockwise", - "message0": "%1 %2", - "args0": [ - { - "type": "field_image", - "src": Blockly.mainWorkspace.options.pathToMedia + "icons/wedo_motor-counterclockwise.svg", - "width": 40, - "height": 40, - "alt": "Turn motor counter-clockwise" - }, - { - "type": "input_value", - "name": "DURATION", - "check": "Number" - } - ], - "inputsInline": true, - "previousStatement": null, - "nextStatement": null, - "category": Blockly.Categories.motion, - "colour": Blockly.Colours.motion.primary, - "colourSecondary": Blockly.Colours.motion.secondary, - "colourTertiary": Blockly.Colours.motion.tertiary, - "colourQuaternary": Blockly.Colours.motion.quaternary - }); - } -}; - -Blockly.Blocks['dropdown_wedo_motorspeed'] = { - /** - * Block for motor speed drop-down (used for shadow). - * @this Blockly.Block - */ - init: function() { - this.appendDummyInput() - .appendField(new Blockly.FieldIconMenu( - [ - {src: Blockly.mainWorkspace.options.pathToMedia + 'icons/wedo_motor-speed_slow.svg', - value: 'slow', width: 48, height: 48, alt: 'Slow'}, - {src: Blockly.mainWorkspace.options.pathToMedia + 'icons/wedo_motor-speed_med.svg', - value: 'medium', width: 48, height: 48, alt: 'Medium'}, - {src: Blockly.mainWorkspace.options.pathToMedia + 'icons/wedo_motor-speed_fast.svg', - value: 'fast', width: 48, height: 48, alt: 'Fast'} - ]), 'CHOICE'); - this.setOutput(true); - this.setColour(Blockly.Colours.motion.primary, - Blockly.Colours.motion.secondary, - Blockly.Colours.motion.tertiary, - Blockly.Colours.motion.quaternary - ); - } -}; - -Blockly.Blocks['wedo_motorspeed'] = { - /** - * Block to set motor speed. - * @this Blockly.Block - */ - init: function() { - this.jsonInit({ - "id": "wedo_motorspeed", - "message0": "%1 %2", - "args0": [ - { - "type": "field_image", - "src": Blockly.mainWorkspace.options.pathToMedia + "icons/wedo_motor-speed_fast.svg", - "width": 40, - "height": 40, - "alt": "Motor Speed" - }, - { - "type": "input_value", - "name": "CHOICE" - } - ], - "inputsInline": true, - "previousStatement": null, - "nextStatement": null, - "category": Blockly.Categories.motion, - "colour": Blockly.Colours.motion.primary, - "colourSecondary": Blockly.Colours.motion.secondary, - "colourTertiary": Blockly.Colours.motion.tertiary, - "colourQuaternary": Blockly.Colours.motion.quaternary - }); - } -}; - -Blockly.Blocks['dropdown_wedo_whentilt'] = { - /** - * Block for when tilt drop-down (used for shadow). - * @this Blockly.Block - */ - init: function() { - this.appendDummyInput() - .appendField(new Blockly.FieldIconMenu( - [ - {type: 'placeholder', width: 48, height: 48}, - {src: Blockly.mainWorkspace.options.pathToMedia + 'icons/wedo_when-tilt-forward.svg', - value: 'forward', width: 48, height: 48, alt: 'Tilt forward'}, - {type: 'placeholder', width: 48, height: 48}, - {src: Blockly.mainWorkspace.options.pathToMedia + 'icons/wedo_when-tilt-left.svg', - value: 'left', width: 48, height: 48, alt: 'Tilt left'}, - {src: Blockly.mainWorkspace.options.pathToMedia + 'icons/wedo_when-tilt.svg', - value: 'any', width: 48, height: 48, alt: 'Tilt any'}, - {src: Blockly.mainWorkspace.options.pathToMedia + 'icons/wedo_when-tilt-right.svg', - value: 'right', width: 48, height: 48, alt: 'Tilt right'}, - {type: 'placeholder', width: 48, height: 48}, - {src: Blockly.mainWorkspace.options.pathToMedia + 'icons/wedo_when-tilt-backward.svg', - value: 'backward', width: 48, height: 48, alt: 'Tilt backward'} - ]), 'CHOICE'); - this.setOutput(true); - this.setColour(Blockly.Colours.event.primary, - Blockly.Colours.event.secondary, - Blockly.Colours.event.tertiary, - Blockly.Colours.event.quaternary - ); - } -}; - -Blockly.Blocks['wedo_whentilt'] = { - /** - * Block for when tilted. - * @this Blockly.Block - */ - init: function() { - this.jsonInit({ - "id": "wedo_whentilt", - "message0": "%1 %2", - "args0": [ - { - "type": "field_image", - "src": Blockly.mainWorkspace.options.pathToMedia + "icons/wedo_when-tilt.svg", - "width": 40, - "height": 40, - "alt": "When tilted" - }, - { - "type": "input_value", - "name": "CHOICE" - } - ], - "inputsInline": true, - "nextStatement": null, - "category": Blockly.Categories.event, - "colour": Blockly.Colours.event.primary, - "colourSecondary": Blockly.Colours.event.secondary, - "colourTertiary": Blockly.Colours.event.tertiary, - "colourQuaternary": Blockly.Colours.event.quaternary - }); - } -}; - -Blockly.Blocks['wedo_whendistanceclose'] = { - /** - * Block for when distance sensor is close. - * @this Blockly.Block - */ - init: function() { - this.jsonInit({ - "id": "wedo_whendistanceclose", - "message0": "%1", - "args0": [ - { - "type": "field_image", - "src": Blockly.mainWorkspace.options.pathToMedia + "icons/wedo_when-distance_close.svg", - "width": 40, - "height": 40, - "alt": "When distance close" - } - ], - "inputsInline": true, - "nextStatement": null, - "category": Blockly.Categories.event, - "colour": Blockly.Colours.event.primary, - "colourSecondary": Blockly.Colours.event.secondary, - "colourTertiary": Blockly.Colours.event.tertiary, - "colourQuaternary": Blockly.Colours.event.quaternary - }); - } -}; diff --git a/blocks_vertical/control.js b/blocks_vertical/control.js deleted file mode 100644 index c555a6544b..0000000000 --- a/blocks_vertical/control.js +++ /dev/null @@ -1,512 +0,0 @@ -/** - * @license - * Visual Blocks Editor - * - * Copyright 2016 Massachusetts Institute of Technology - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import * as Blockly from 'blockly/core'; -import {Categories} from '../src/categories.js'; -import {Colours} from '../core/colours.js'; - -Blockly.Blocks['control_forever'] = { - /** - * Block for repeat n times (external number). - * https://blockly-demo.appspot.com/static/demos/blockfactory/index.html#5eke39 - * @this Blockly.Block - */ - init: function() { - const ws = this.workspace.options.parentWorkspace || this.workspace; - this.jsonInit({ - "id": "control_forever", - "message0": Blockly.Msg.CONTROL_FOREVER, - "message1": "%1", // Statement - "message2": "%1", // Icon - "lastDummyAlign2": "RIGHT", - "args1": [ - { - "type": "input_statement", - "name": "SUBSTACK" - } - ], - "args2": [ - { - "type": "field_image", - "src": ws.options.pathToMedia + "repeat.svg", - "width": 24, - "height": 24, - "alt": "*", - "flip_rtl": true - } - ], - "category": Categories.control, - "extensions": ["colours_control", "shape_end"] - }); - } -}; - -Blockly.Blocks['control_repeat'] = { - /** - * Block for repeat n times (external number). - * https://blockly-demo.appspot.com/static/demos/blockfactory/index.html#so57n9 - * @this Blockly.Block - */ - init: function() { - const ws = this.workspace.options.parentWorkspace || this.workspace; - this.jsonInit({ - "id": "control_repeat", - "message0": Blockly.Msg.CONTROL_REPEAT, - "message1": "%1", // Statement - "message2": "%1", // Icon - "lastDummyAlign2": "RIGHT", - "args0": [ - { - "type": "input_value", - "name": "TIMES" - } - ], - "args1": [ - { - "type": "input_statement", - "name": "SUBSTACK" - } - ], - "args2": [ - { - "type": "field_image", - "src": ws.options.pathToMedia + "repeat.svg", - "width": 24, - "height": 24, - "alt": "*", - "flip_rtl": true - } - ], - "category": Categories.control, - "extensions": ["colours_control", "shape_statement"] - }); - } -}; - -Blockly.Blocks['control_if'] = { - /** - * Block for if-then. - * @this Blockly.Block - */ - init: function() { - this.jsonInit({ - "type": "control_if", - "message0": Blockly.Msg.CONTROL_IF, - "message1": "%1", // Statement - "args0": [ - { - "type": "input_value", - "name": "CONDITION", - "check": "Boolean" - } - ], - "args1": [ - { - "type": "input_statement", - "name": "SUBSTACK" - } - ], - "category": Categories.control, - "extensions": ["colours_control", "shape_statement"] - }); - } -}; - -Blockly.Blocks['control_if_else'] = { - /** - * Block for if-else. - * @this Blockly.Block - */ - init: function() { - this.jsonInit({ - "type": "control_if_else", - "message0": Blockly.Msg.CONTROL_IF, - "message1": "%1", - "message2": Blockly.Msg.CONTROL_ELSE, - "message3": "%1", - "args0": [ - { - "type": "input_value", - "name": "CONDITION", - "check": "Boolean" - } - ], - "args1": [ - { - "type": "input_statement", - "name": "SUBSTACK" - } - ], - "args3": [ - { - "type": "input_statement", - "name": "SUBSTACK2" - } - ], - "category": Categories.control, - "extensions": ["colours_control", "shape_statement"] - }); - } -}; - -Blockly.Blocks['control_stop'] = { - /** - * Block for stop all scripts. - * @this Blockly.Block - */ - init: function() { - var ALL_SCRIPTS = 'all'; - var THIS_SCRIPT = 'this script'; - var OTHER_SCRIPTS = 'other scripts in sprite'; - var stopDropdown = new Blockly.FieldDropdown(function() { - if (this.sourceBlock_ && - this.sourceBlock_.nextConnection && - this.sourceBlock_.nextConnection.isConnected()) { - return [ - [Blockly.Msg.CONTROL_STOP_OTHER, OTHER_SCRIPTS] - ]; - } - return [[Blockly.Msg.CONTROL_STOP_ALL, ALL_SCRIPTS], - [Blockly.Msg.CONTROL_STOP_THIS, THIS_SCRIPT], - [Blockly.Msg.CONTROL_STOP_OTHER, OTHER_SCRIPTS] - ]; - }, function(option) { - this.getSourceBlock().setNextStatement(option === OTHER_SCRIPTS); - return option; - }); - this.appendDummyInput() - .appendField(Blockly.Msg.CONTROL_STOP) - .appendField(stopDropdown, 'STOP_OPTION'); - this.setColour(Colours.control.primary, - Colours.control.secondary, - Colours.control.tertiary, - Colours.control.quaternary - ); - this.setPreviousStatement(true); - } -}; - -Blockly.Blocks['control_wait'] = { - /** - * Block to wait (pause) stack. - * @this Blockly.Block - */ - init: function() { - this.jsonInit({ - "id": "control_wait", - "message0": Blockly.Msg.CONTROL_WAIT, - "args0": [ - { - "type": "input_value", - "name": "DURATION" - } - ], - "category": Categories.control, - "extensions": ["colours_control", "shape_statement"] - }); - } -}; - -Blockly.Blocks['control_wait_until'] = { - /** - * Block to wait until a condition becomes true. - * @this Blockly.Block - */ - init: function() { - this.jsonInit({ - "message0": Blockly.Msg.CONTROL_WAITUNTIL, - "args0": [ - { - "type": "input_value", - "name": "CONDITION", - "check": "Boolean" - } - ], - "category": Categories.control, - "extensions": ["colours_control", "shape_statement"] - }); - } -}; - -Blockly.Blocks['control_repeat_until'] = { - /** - * Block to repeat until a condition becomes true. - * @this Blockly.Block - */ - init: function() { - const ws = this.workspace.options.parentWorkspace || this.workspace; - this.jsonInit({ - "message0": Blockly.Msg.CONTROL_REPEATUNTIL, - "message1": "%1", - "message2": "%1", - "lastDummyAlign2": "RIGHT", - "args0": [ - { - "type": "input_value", - "name": "CONDITION", - "check": "Boolean" - } - ], - "args1": [ - { - "type": "input_statement", - "name": "SUBSTACK" - } - ], - "args2": [ - { - "type": "field_image", - "src": ws.options.pathToMedia + "repeat.svg", - "width": 24, - "height": 24, - "alt": "*", - "flip_rtl": true - } - ], - "category": Categories.control, - "extensions": ["colours_control", "shape_statement"] - }); - } -}; - -Blockly.Blocks['control_while'] = { - /** - * Block to repeat until a condition becomes false. - * (This is an obsolete "hacked" block, for compatibility with 2.0.) - */ - init: function() { - const ws = this.workspace.options.parentWorkspace || this.workspace; - this.jsonInit({ - "message0": Blockly.Msg.CONTROL_WHILE, - "message1": "%1", - "message2": "%1", - "lastDummyAlign2": "RIGHT", - "args0": [ - { - "type": "input_value", - "name": "CONDITION", - "check": "Boolean" - } - ], - "args1": [ - { - "type": "input_statement", - "name": "SUBSTACK" - } - ], - "args2": [ - { - "type": "field_image", - "src": ws.options.pathToMedia + "repeat.svg", - "width": 24, - "height": 24, - "alt": "*", - "flip_rtl": true - } - ], - "category": Categories.control, - "extensions": ["colours_control", "shape_statement"] - }); - } -}; - -Blockly.Blocks['control_for_each'] = { - /** - * Block for for-each. This is an obsolete block that is implemented for - * compatibility with Scratch 2.0 projects. - * @this Blockly.Block - */ - init: function() { - this.jsonInit({ - "type": "control_for_each", - "message0": Blockly.Msg.CONTROL_FOREACH, - "message1": "%1", - "args0": [ - { - "type": "field_variable", - "name": "VARIABLE" - }, - { - "type": "input_value", - "name": "VALUE" - } - ], - "args1": [ - { - "type": "input_statement", - "name": "SUBSTACK" - } - ], - "category": Categories.control, - "extensions": ["colours_control", "shape_statement"] - }); - } -}; - -Blockly.Blocks['control_start_as_clone'] = { - /** - * Block for "when I start as a clone" hat. - * @this Blockly.Block - */ - init: function() { - this.jsonInit({ - "id": "control_start_as_clone", - "message0": Blockly.Msg.CONTROL_STARTASCLONE, - "args0": [ - ], - "category": Categories.control, - "extensions": ["colours_control", "shape_hat"] - }); - } -}; - -Blockly.Blocks['control_create_clone_of_menu'] = { - /** - * Create-clone drop-down menu. - * @this Blockly.Block - */ - init: function() { - this.jsonInit({ - "message0": "%1", - "args0": [ - { - "type": "field_dropdown", - "name": "CLONE_OPTION", - "options": [ - [Blockly.Msg.CONTROL_CREATECLONEOF_MYSELF, '_myself_'] - ] - } - ], - "extensions": ["colours_control", "output_string"] - }); - } -}; - -Blockly.Blocks['control_create_clone_of'] = { - /** - * Block for "create clone of..." - * @this Blockly.Block - */ - init: function() { - this.jsonInit({ - "id": "control_start_as_clone", - "message0": Blockly.Msg.CONTROL_CREATECLONEOF, - "args0": [ - { - "type": "input_value", - "name": "CLONE_OPTION" - } - ], - "category": Categories.control, - "extensions": ["colours_control", "shape_statement"] - }); - } -}; - -Blockly.Blocks['control_delete_this_clone'] = { - /** - * Block for "delete this clone." - * @this Blockly.Block - */ - init: function() { - this.jsonInit({ - "message0": Blockly.Msg.CONTROL_DELETETHISCLONE, - "args0": [ - ], - "category": Categories.control, - "extensions": ["colours_control", "shape_end"] - }); - } -}; - -Blockly.Blocks['control_get_counter'] = { - /** - * Block to get the counter value. This is an obsolete block that is - * implemented for compatibility with Scratch 2.0 projects. - * @this Blockly.Block - */ - init: function() { - this.jsonInit({ - "message0": Blockly.Msg.CONTROL_COUNTER, - "category": Categories.control, - "extensions": ["colours_control", "output_number"] - }); - } -}; - -Blockly.Blocks['control_incr_counter'] = { - /** - * Block to add one to the counter value. This is an obsolete block that is - * implemented for compatibility with Scratch 2.0 projects. - * @this Blockly.Block - */ - init: function() { - this.jsonInit({ - "message0": Blockly.Msg.CONTROL_INCRCOUNTER, - "category": Categories.control, - "extensions": ["colours_control", "shape_statement"] - }); - } -}; - -Blockly.Blocks['control_clear_counter'] = { - /** - * Block to clear the counter value. This is an obsolete block that is - * implemented for compatibility with Scratch 2.0 projects. - * @this Blockly.Block - */ - init: function() { - this.jsonInit({ - "message0": Blockly.Msg.CONTROL_CLEARCOUNTER, - "category": Categories.control, - "extensions": ["colours_control", "shape_statement"] - }); - } -}; - -Blockly.Blocks['control_all_at_once'] = { - /** - * Block to run the contained script. This is an obsolete block that is - * implemented for compatibility with Scratch 2.0 projects. Note that - * this was originally designed to run all of the contained blocks - * (sequentially, like normal) within a single frame, but this feature - * was removed in place of custom blocks marked "run without screen - * refresh". The "all at once" block was changed to run the contained - * blocks ordinarily, functioning the same way as an "if" block with a - * reporter that is always true (e.g. "if 1 = 1"). Also note that the - * Scratch 2.0 spec for this block is "warpSpeed", but the label shows - * "all at once". - * @this Blockly.Block - */ - init: function() { - this.jsonInit({ - "message0": Blockly.Msg.CONTROL_ALLATONCE, - "message1": "%1", // Statement - "args1": [ - { - "type": "input_statement", - "name": "SUBSTACK" - } - ], - "category": Categories.control, - "extensions": ["colours_control", "shape_statement"] - }); - } -}; diff --git a/blocks_vertical/default_toolbox.js b/blocks_vertical/default_toolbox.js deleted file mode 100644 index 8c5624fad4..0000000000 --- a/blocks_vertical/default_toolbox.js +++ /dev/null @@ -1,564 +0,0 @@ -/** - * @license - * Visual Blocks Editor - * - * Copyright 2016 Massachusetts Institute of Technology - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -'use strict'; - -goog.provide('Blockly.Blocks.defaultToolbox'); - -goog.require('Blockly.Blocks'); - -/** - * @fileoverview Provide a default toolbox XML. - */ - -Blockly.Blocks.defaultToolbox = ''; diff --git a/blocks_vertical/event.js b/blocks_vertical/event.js deleted file mode 100644 index 2bbc788ff3..0000000000 --- a/blocks_vertical/event.js +++ /dev/null @@ -1,323 +0,0 @@ -/** - * @license - * Visual Blocks Editor - * - * Copyright 2016 Massachusetts Institute of Technology - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import * as Blockly from 'blockly/core'; -import {Categories} from '../src/categories.js'; -import * as Constants from '../src/constants.js'; - -Blockly.Blocks['event_whentouchingobject'] = { - /** - * Block for when a sprite is touching an object. - * @this Blockly.Block - */ - init: function() { - this.jsonInit({ - "message0": Blockly.Msg.EVENT_WHENTOUCHINGOBJECT, - "args0": [ - { - "type": "input_value", - "name": "TOUCHINGOBJECTMENU" - } - ], - "category": Categories.event, - "extensions": ["colours_event", "shape_hat"] - }); - } -}; - -Blockly.Blocks['event_touchingobjectmenu'] = { - /** - * "Touching [Object]" Block Menu. - * @this Blockly.Block - */ - init: function() { - this.jsonInit({ - "message0": "%1", - "args0": [ - { - "type": "field_dropdown", - "name": "TOUCHINGOBJECTMENU", - "options": [ - [Blockly.Msg.SENSING_TOUCHINGOBJECT_POINTER, '_mouse_'], - [Blockly.Msg.SENSING_TOUCHINGOBJECT_EDGE, '_edge_'] - ] - } - ], - "extensions": ["colours_event", "output_string"] - }); - } -}; - -Blockly.Blocks['event_whenflagclicked'] = { - /** - * Block for when flag clicked. - * @this Blockly.Block - */ - init: function() { - const ws = this.workspace.options.parentWorkspace || this.workspace; - this.jsonInit({ - "id": "event_whenflagclicked", - "message0": Blockly.Msg.EVENT_WHENFLAGCLICKED, - "args0": [ - { - "type": "field_image", - "src": ws.options.pathToMedia + "green-flag.svg", - "width": 24, - "height": 24, - "alt": "flag" - } - ], - "category": Categories.event, - "extensions": ["colours_event", "shape_hat"] - }); - } -}; - -Blockly.Blocks['event_whenthisspriteclicked'] = { - /** - * Block for when this sprite clicked. - * @this Blockly.Block - */ - init: function() { - this.jsonInit({ - "message0": Blockly.Msg.EVENT_WHENTHISSPRITECLICKED, - "category": Categories.event, - "extensions": ["colours_event", "shape_hat"] - }); - } - -}; - -Blockly.Blocks['event_whenstageclicked'] = { - /** - * Block for when the stage is clicked. - * @this Blockly.Block - */ - init: function() { - this.jsonInit({ - "message0": Blockly.Msg.EVENT_WHENSTAGECLICKED, - "category": Categories.event, - "extensions": ["colours_event", "shape_hat"] - }); - } -}; - -Blockly.Blocks['event_whenbroadcastreceived'] = { - /** - * Block for when broadcast received. - * @this Blockly.Block - */ - init: function() { - this.jsonInit({ - "id": "event_whenbroadcastreceived", - "message0": Blockly.Msg.EVENT_WHENBROADCASTRECEIVED, - "args0": [ - { - "type": "field_variable", - "name": "BROADCAST_OPTION", - "variableTypes": [Constants.BROADCAST_MESSAGE_VARIABLE_TYPE], - "defaultType": Constants.BROADCAST_MESSAGE_VARIABLE_TYPE, - "variable": Blockly.Msg.DEFAULT_BROADCAST_MESSAGE_NAME - } - ], - "category": Categories.event, - "extensions": ["colours_event", "shape_hat"] - }); - } -}; - -Blockly.Blocks['event_whenbackdropswitchesto'] = { - /** - * Block for when the current backdrop switched to a selected backdrop. - * @this Blockly.Block - */ - init: function() { - this.jsonInit({ - "message0": Blockly.Msg.EVENT_WHENBACKDROPSWITCHESTO, - "args0": [ - { - "type": "field_dropdown", - "name": "BACKDROP", - "options": [ - ['backdrop1', 'BACKDROP1'] - ] - } - ], - "category": Categories.event, - "extensions": ["colours_event", "shape_hat"] - }); - } -}; - -Blockly.Blocks['event_whengreaterthan'] = { - /** - * Block for when loudness/timer/video motion is greater than the value. - * @this Blockly.Block - */ - init: function() { - this.jsonInit({ - "message0": Blockly.Msg.EVENT_WHENGREATERTHAN, - "args0": [ - { - "type": "field_dropdown", - "name": "WHENGREATERTHANMENU", - "options": [ - [Blockly.Msg.EVENT_WHENGREATERTHAN_LOUDNESS, 'LOUDNESS'], - [Blockly.Msg.EVENT_WHENGREATERTHAN_TIMER, 'TIMER'] - ] - }, - { - "type": "input_value", - "name": "VALUE" - } - ], - "category": Categories.event, - "extensions": ["colours_event", "shape_hat"] - }); - } -}; - -Blockly.Blocks['event_broadcast_menu'] = { - /** - * Broadcast drop-down menu. - * @this Blockly.Block - */ - init: function() { - this.jsonInit({ - "message0": "%1", - "args0": [ - { - "type": "field_variable", - "name": "BROADCAST_OPTION", - "variableTypes": [Constants.BROADCAST_MESSAGE_VARIABLE_TYPE], - "defaultType": Constants.BROADCAST_MESSAGE_VARIABLE_TYPE, - "variable": Blockly.Msg.DEFAULT_BROADCAST_MESSAGE_NAME - } - ], - "extensions": ["colours_event", "output_string"] - }); - } -}; - -Blockly.Blocks['event_broadcast'] = { - /** - * Block to send a broadcast. - * @this Blockly.Block - */ - init: function() { - this.jsonInit({ - "id": "event_broadcast", - "message0": Blockly.Msg.EVENT_BROADCAST, - "args0": [ - { - "type": "input_value", - "name": "BROADCAST_INPUT" - } - ], - "category": Categories.event, - "extensions": ["colours_event", "shape_statement"] - }); - } -}; - -Blockly.Blocks['event_broadcastandwait'] = { - /** - * Block to send a broadcast. - * @this Blockly.Block - */ - init: function() { - this.jsonInit({ - "message0": Blockly.Msg.EVENT_BROADCASTANDWAIT, - "args0": [ - { - "type":"input_value", - "name":"BROADCAST_INPUT" - } - ], - "category": Categories.event, - "extensions": ["colours_event", "shape_statement"] - }); - } -}; - -Blockly.Blocks['event_whenkeypressed'] = { - /** - * Block to send a broadcast. - * @this Blockly.Block - */ - init: function() { - this.jsonInit({ - "id": "event_whenkeypressed", - "message0": Blockly.Msg.EVENT_WHENKEYPRESSED, - "args0": [ - { - "type": "field_dropdown", - "name": "KEY_OPTION", - "options": [ - [Blockly.Msg.EVENT_WHENKEYPRESSED_SPACE, 'space'], - [Blockly.Msg.EVENT_WHENKEYPRESSED_UP, 'up arrow'], - [Blockly.Msg.EVENT_WHENKEYPRESSED_DOWN, 'down arrow'], - [Blockly.Msg.EVENT_WHENKEYPRESSED_RIGHT, 'right arrow'], - [Blockly.Msg.EVENT_WHENKEYPRESSED_LEFT, 'left arrow'], - [Blockly.Msg.EVENT_WHENKEYPRESSED_ANY, 'any'], - ['a', 'a'], - ['b', 'b'], - ['c', 'c'], - ['d', 'd'], - ['e', 'e'], - ['f', 'f'], - ['g', 'g'], - ['h', 'h'], - ['i', 'i'], - ['j', 'j'], - ['k', 'k'], - ['l', 'l'], - ['m', 'm'], - ['n', 'n'], - ['o', 'o'], - ['p', 'p'], - ['q', 'q'], - ['r', 'r'], - ['s', 's'], - ['t', 't'], - ['u', 'u'], - ['v', 'v'], - ['w', 'w'], - ['x', 'x'], - ['y', 'y'], - ['z', 'z'], - ['0', '0'], - ['1', '1'], - ['2', '2'], - ['3', '3'], - ['4', '4'], - ['5', '5'], - ['6', '6'], - ['7', '7'], - ['8', '8'], - ['9', '9'] - ] - } - ], - "category": Categories.event, - "extensions": ["colours_event", "shape_hat"] - }); - } -}; diff --git a/blocks_vertical/extensions.js b/blocks_vertical/extensions.js deleted file mode 100644 index 499a3961d0..0000000000 --- a/blocks_vertical/extensions.js +++ /dev/null @@ -1,294 +0,0 @@ -/** - * @license - * Visual Blocks Editor - * - * Copyright 2016 Massachusetts Institute of Technology - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -'use strict'; - -goog.provide('Blockly.Blocks.extensions'); - -goog.require('Blockly.Blocks'); -goog.require('Blockly.Colours'); -goog.require('Blockly.constants'); -goog.require('Blockly.ScratchBlocks.VerticalExtensions'); - -Blockly.Blocks['extension_pen_down'] = { - /** - * @this Blockly.Block - */ - init: function() { - this.jsonInit({ - "message0": "%1 %2 pen down", - "args0": [ - { - "type": "field_image", - "src": Blockly.mainWorkspace.options.pathToMedia + "extensions/pen-block-icon.svg", - "width": 40, - "height": 40 - }, - { - "type": "field_vertical_separator" - } - ], - "category": Blockly.Categories.more, - "extensions": ["colours_more", "shape_statement", "scratch_extension"] - }); - } -}; - -Blockly.Blocks['extension_music_drum'] = { - /** - * @this Blockly.Block - */ - init: function() { - this.jsonInit({ - "message0": "%1 %2 play drum %3", - "args0": [ - { - "type": "field_image", - "src": Blockly.mainWorkspace.options.pathToMedia + "extensions/music-block-icon.svg", - "width": 40, - "height": 40 - }, - { - "type": "field_vertical_separator" - }, - { - "type": "input_value", - "name": "NUMBER" - } - ], - "category": Blockly.Categories.more, - "extensions": ["colours_more", "shape_statement", "scratch_extension"] - }); - } -}; - -Blockly.Blocks['extension_wedo_motor'] = { - /** - * @this Blockly.Block - */ - init: function() { - this.jsonInit({ - "message0": "%1 %2 turn a motor %3", - "args0": [ - { - "type": "field_image", - "src": Blockly.mainWorkspace.options.pathToMedia + "extensions/wedo2-block-icon.svg", - "width": 40, - "height": 40 - }, - { - "type": "field_vertical_separator" - }, - { - "type": "field_image", - "src": Blockly.mainWorkspace.options.pathToMedia + "rotate-right.svg", - "width": 24, - "height": 24 - } - ], - "category": Blockly.Categories.more, - "extensions": ["colours_more", "shape_statement", "scratch_extension"] - }); - } -}; - -Blockly.Blocks['extension_wedo_hat'] = { - /** - * @this Blockly.Block - */ - init: function() { - this.jsonInit({ - "message0": "%1 %2 when I am wearing a hat", - "args0": [ - { - "type": "field_image", - "src": Blockly.mainWorkspace.options.pathToMedia + "extensions/wedo2-block-icon.svg", - "width": 40, - "height": 40 - }, - { - "type": "field_vertical_separator" - } - ], - "category": Blockly.Categories.more, - "extensions": ["colours_more", "shape_hat", "scratch_extension"] - }); - } -}; - -Blockly.Blocks['extension_wedo_boolean'] = { - /** - * @this Blockly.Block - */ - init: function() { - this.jsonInit({ - "message0": "%1 %2 O RLY?", - "args0": [ - { - "type": "field_image", - "src": Blockly.mainWorkspace.options.pathToMedia + "extensions/wedo2-block-icon.svg", - "width": 40, - "height": 40 - }, - { - "type": "field_vertical_separator" - } - ], - "category": Blockly.Categories.more, - "extensions": ["colours_more", "output_boolean", "scratch_extension"] - }); - } -}; - -Blockly.Blocks['extension_wedo_tilt_reporter'] = { - /** - * @this Blockly.Block - */ - init: function() { - this.jsonInit({ - "message0": "%1 %2 tilt angle %3", - "args0": [ - { - "type": "field_image", - "src": Blockly.mainWorkspace.options.pathToMedia + "extensions/wedo2-block-icon.svg", - "width": 40, - "height": 40 - }, - { - "type": "field_vertical_separator" - }, - { - "type": "input_value", - "name": "TILT" - } - ], - "category": Blockly.Categories.more, - "extensions": ["colours_more", "output_number", "scratch_extension"] - }); - } -}; - -Blockly.Blocks['extension_wedo_tilt_menu'] = { - /** - * @this Blockly.Block - */ - init: function() { - this.jsonInit({ - "message0": "%1", - "args0": [ - { - "type": "field_dropdown", - "name": "TILT", - "options": [ - ['Any', 'Any'], - ['Whirl', 'Whirl'], - ['South', 'South'], - ['Back in time', 'Back in time'] - ] - } - ], - "extensions": ["colours_more", "output_string"] - }); - } -}; - -Blockly.Blocks['extension_music_reporter'] = { - /** - * @this Blockly.Block - */ - init: function() { - this.jsonInit({ - "message0": "%1 %2 hey now, you're an all-star", - "args0": [ - { - "type": "field_image", - "src": Blockly.mainWorkspace.options.pathToMedia + "extensions/music-block-icon.svg", - "width": 40, - "height": 40 - }, - { - "type": "field_vertical_separator" - } - ], - "category": Blockly.Categories.more, - "extensions": ["colours_more", "output_number", "scratch_extension"] - }); - } -}; - -Blockly.Blocks['extension_microbit_display'] = { - /** - * @this Blockly.Block - */ - init: function() { - this.jsonInit({ - "message0": "%1 %2 display %3", - "args0": [ - { - "type": "field_image", - "src": Blockly.mainWorkspace.options.pathToMedia + "extensions/microbit-block-icon.svg", - "width": 40, - "height": 40 - }, - { - "type": "field_vertical_separator" - }, - { - "type": "input_value", - "name": "MATRIX" - }, - ], - "category": Blockly.Categories.pen, - "extensions": ["colours_pen", "shape_statement", "scratch_extension"] - }); - } -}; - -Blockly.Blocks['extension_music_play_note'] = { - /** - * @this Blockly.Block - */ - init: function() { - this.jsonInit({ - "message0": "%1 %2 play note %3 for %4 beats", - "args0": [ - { - "type": "field_image", - "src": Blockly.mainWorkspace.options.pathToMedia + "extensions/music-block-icon.svg", - "width": 40, - "height": 40 - }, - { - "type": "field_vertical_separator" - }, - { - "type": "input_value", - "name": "NOTE" - }, - { - "type": "input_value", - "name": "BEATS" - } - ], - "category": Blockly.Categories.pen, - "extensions": ["colours_pen", "shape_statement", "scratch_extension"] - }); - } -}; diff --git a/blocks_vertical/looks.js b/blocks_vertical/looks.js deleted file mode 100644 index c2c276ff17..0000000000 --- a/blocks_vertical/looks.js +++ /dev/null @@ -1,576 +0,0 @@ -/** - * @license - * Visual Blocks Editor - * - * Copyright 2016 Massachusetts Institute of Technology - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import * as Blockly from 'blockly/core'; -import {Categories} from '../src/categories.js'; - -Blockly.Blocks['looks_sayforsecs'] = { - /** - * Block to say for some time. - * @this Blockly.Block - */ - init: function() { - this.jsonInit({ - "message0": Blockly.Msg.LOOKS_SAYFORSECS, - "args0": [ - { - "type": "input_value", - "name": "MESSAGE" - }, - { - "type": "input_value", - "name": "SECS" - } - ], - "category": Categories.looks, - "extensions": ["colours_looks", "shape_statement"] - }); - } -}; - -Blockly.Blocks['looks_say'] = { - /** - * Block to say. - * @this Blockly.Block - */ - init: function() { - this.jsonInit({ - "message0": Blockly.Msg.LOOKS_SAY, - "args0": [ - { - "type": "input_value", - "name": "MESSAGE" - } - ], - "category": Categories.looks, - "extensions": ["colours_looks", "shape_statement"] - }); - } -}; - -Blockly.Blocks['looks_thinkforsecs'] = { - /** - * Block to think for some time. - * @this Blockly.Block - */ - init: function() { - this.jsonInit({ - "message0": Blockly.Msg.LOOKS_THINKFORSECS, - "args0": [ - { - "type": "input_value", - "name": "MESSAGE" - }, - { - "type": "input_value", - "name": "SECS" - } - ], - "category": Categories.looks, - "extensions": ["colours_looks", "shape_statement"] - }); - } -}; - -Blockly.Blocks['looks_think'] = { - /** - * Block to think. - * @this Blockly.Block - */ - init: function() { - this.jsonInit({ - "message0": Blockly.Msg.LOOKS_THINK, - "args0": [ - { - "type": "input_value", - "name": "MESSAGE" - } - ], - "category": Categories.looks, - "extensions": ["colours_looks", "shape_statement"] - }); - } -}; - -Blockly.Blocks['looks_show'] = { - /** - * Show block. - * @this Blockly.Block - */ - init: function() { - this.jsonInit({ - "message0": Blockly.Msg.LOOKS_SHOW, - "category": Categories.looks, - "extensions": ["colours_looks", "shape_statement"] - }); - } -}; - -Blockly.Blocks['looks_hide'] = { - /** - * Hide block. - * @this Blockly.Block - */ - init: function() { - this.jsonInit({ - "message0": Blockly.Msg.LOOKS_HIDE, - "category": Categories.looks, - "extensions": ["colours_looks", "shape_statement"] - }); - } -}; - -Blockly.Blocks['looks_hideallsprites'] = { - /** - * Hide-all-sprites block. Does not actually do anything. This is an - * obsolete block that is implemented for compatibility with Scratch 2.0 - * projects. - * @this Blockly.Block - */ - init: function() { - this.jsonInit({ - "message0": Blockly.Msg.LOOKS_HIDEALLSPRITES, - "category": Categories.looks, - "extensions": ["colours_looks", "shape_statement"] - }); - } -}; - -Blockly.Blocks['looks_changeeffectby'] = { - /** - * Block to change graphic effect. - * @this Blockly.Block - */ - init: function() { - this.jsonInit({ - "message0": Blockly.Msg.LOOKS_CHANGEEFFECTBY, - "args0": [ - { - "type": "field_dropdown", - "name": "EFFECT", - "options": [ - [Blockly.Msg.LOOKS_EFFECT_COLOR, 'COLOR'], - [Blockly.Msg.LOOKS_EFFECT_FISHEYE, 'FISHEYE'], - [Blockly.Msg.LOOKS_EFFECT_WHIRL, 'WHIRL'], - [Blockly.Msg.LOOKS_EFFECT_PIXELATE, 'PIXELATE'], - [Blockly.Msg.LOOKS_EFFECT_MOSAIC, 'MOSAIC'], - [Blockly.Msg.LOOKS_EFFECT_BRIGHTNESS, 'BRIGHTNESS'], - [Blockly.Msg.LOOKS_EFFECT_GHOST, 'GHOST'] - ] - }, - { - "type": "input_value", - "name": "CHANGE" - } - ], - "category": Categories.looks, - "extensions": ["colours_looks", "shape_statement"] - }); - } -}; - -Blockly.Blocks['looks_seteffectto'] = { - /** - * Block to set graphic effect. - * @this Blockly.Block - */ - init: function() { - this.jsonInit({ - "message0": Blockly.Msg.LOOKS_SETEFFECTTO, - "args0": [ - { - "type": "field_dropdown", - "name": "EFFECT", - "options": [ - [Blockly.Msg.LOOKS_EFFECT_COLOR, 'COLOR'], - [Blockly.Msg.LOOKS_EFFECT_FISHEYE, 'FISHEYE'], - [Blockly.Msg.LOOKS_EFFECT_WHIRL, 'WHIRL'], - [Blockly.Msg.LOOKS_EFFECT_PIXELATE, 'PIXELATE'], - [Blockly.Msg.LOOKS_EFFECT_MOSAIC, 'MOSAIC'], - [Blockly.Msg.LOOKS_EFFECT_BRIGHTNESS, 'BRIGHTNESS'], - [Blockly.Msg.LOOKS_EFFECT_GHOST, 'GHOST'] - ] - }, - { - "type": "input_value", - "name": "VALUE" - } - ], - "category": Categories.looks, - "extensions": ["colours_looks", "shape_statement"] - }); - } -}; - -Blockly.Blocks['looks_cleargraphiceffects'] = { - /** - * Block to clear graphic effects. - * @this Blockly.Block - */ - init: function() { - this.jsonInit({ - "message0": Blockly.Msg.LOOKS_CLEARGRAPHICEFFECTS, - "category": Categories.looks, - "extensions": ["colours_looks", "shape_statement"] - }); - } -}; - -Blockly.Blocks['looks_changesizeby'] = { - /** - * Block to change size - * @this Blockly.Block - */ - init: function() { - this.jsonInit({ - "message0": Blockly.Msg.LOOKS_CHANGESIZEBY, - "args0": [ - { - "type": "input_value", - "name": "CHANGE" - } - ], - "category": Categories.looks, - "extensions": ["colours_looks", "shape_statement"] - }); - } -}; - -Blockly.Blocks['looks_setsizeto'] = { - /** - * Block to set size - * @this Blockly.Block - */ - init: function() { - this.jsonInit({ - "message0": Blockly.Msg.LOOKS_SETSIZETO, - "args0": [ - { - "type": "input_value", - "name": "SIZE" - } - ], - "category": Categories.looks, - "extensions": ["colours_looks", "shape_statement"] - }); - } -}; - -Blockly.Blocks['looks_size'] = { - /** - * Block to report size - * @this Blockly.Block - */ - init: function() { - this.jsonInit({ - "message0": Blockly.Msg.LOOKS_SIZE, - "category": Categories.looks, - "extensions": ["colours_looks", "output_number"] - }); - this.checkboxInFlyout = true; - } -}; - -Blockly.Blocks['looks_changestretchby'] = { - /** - * Block to change stretch. Does not actually do anything. This is an - * obsolete block that is implemented for compatibility with Scratch 1.4 - * projects as well as 2.0 projects that still have the block. - * The "stretch" blocks were introduced in very early versions of Scratch, - * but their functionality was removed shortly later. They still appeared - * correctly up until (and including) Scratch 1.4 - as "change stretch by" - * and "set stretch to" - but were removed altogether in Scratch 2.0, and - * displayed as red "undefined" blocks. Some Scratch projects still contain - * these blocks, however, and they don't open in 3.0 unless the blocks - * actually exist (though they still don't funcitonally do anything). - * @this Blockly.Block - */ - init: function() { - this.jsonInit({ - "message0": Blockly.Msg.LOOKS_CHANGESTRETCHBY, - "args0": [ - { - "type": "input_value", - "name": "CHANGE" - } - ], - "category": Categories.looks, - "extensions": ["colours_looks", "shape_statement"] - }); - } -}; - -Blockly.Blocks['looks_setstretchto'] = { - /** - * Block to set stretch. Does not actually do anything. This is an obsolete - * block that is implemented for compatibility with Scratch 1.4 projects - * (see looks_changestretchby). - * @this Blockly.Block - */ - init: function() { - this.jsonInit({ - "message0": Blockly.Msg.LOOKS_SETSTRETCHTO, - "args0": [ - { - "type": "input_value", - "name": "STRETCH" - } - ], - "category": Categories.looks, - "extensions": ["colours_looks", "shape_statement"] - }); - } -}; - -Blockly.Blocks['looks_costume'] = { - /** - * Costumes drop-down menu. - * @this Blockly.Block - */ - init: function() { - this.jsonInit({ - "message0": "%1", - "args0": [ - { - "type": "field_dropdown", - "name": "COSTUME", - "options": [ - ['costume1', 'COSTUME1'], - ['costume2', 'COSTUME2'] - ] - } - ], - "extensions": ["colours_looks", "output_string"] - }); - } -}; - -Blockly.Blocks['looks_switchcostumeto'] = { - /** - * Block to switch the sprite's costume to the selected one. - * @this Blockly.Block - */ - init: function() { - this.jsonInit({ - "message0": Blockly.Msg.LOOKS_SWITCHCOSTUMETO, - "args0": [ - { - "type": "input_value", - "name": "COSTUME" - } - ], - "category": Categories.looks, - "extensions": ["colours_looks", "shape_statement"] - }); - } -}; - -Blockly.Blocks['looks_nextcostume'] = { - /** - * Block to switch the sprite's costume to the next one. - * @this Blockly.Block - */ - init: function() { - this.jsonInit({ - "message0": Blockly.Msg.LOOKS_NEXTCOSTUME, - "category": Categories.looks, - "extensions": ["colours_looks", "shape_statement"] - }); - } -}; - -Blockly.Blocks['looks_switchbackdropto'] = { - /** - * Block to switch the backdrop to the selected one. - * @this Blockly.Block - */ - init: function() { - this.jsonInit({ - "message0": Blockly.Msg.LOOKS_SWITCHBACKDROPTO, - "args0": [ - { - "type": "input_value", - "name": "BACKDROP" - } - ], - "category": Categories.looks, - "extensions": ["colours_looks", "shape_statement"] - }); - } -}; - -Blockly.Blocks['looks_backdrops'] = { - /** - * Backdrop list - * @this Blockly.Block - */ - init: function() { - this.jsonInit({ - "id": "looks_backdrops", - "message0": "%1", - "args0": [ - { - "type": "field_dropdown", - "name": "BACKDROP", - "options": [ - ['backdrop1', 'BACKDROP1'] - ] - } - ], - "extensions": ["colours_looks", "output_string"] - }); - } -}; - -Blockly.Blocks['looks_gotofrontback'] = { - /** - * "Go to front/back" Block. - * @this Blockly.Block - */ - init: function() { - this.jsonInit({ - "message0": Blockly.Msg.LOOKS_GOTOFRONTBACK, - "args0": [ - { - "type": "field_dropdown", - "name": "FRONT_BACK", - "options": [ - [Blockly.Msg.LOOKS_GOTOFRONTBACK_FRONT, 'front'], - [Blockly.Msg.LOOKS_GOTOFRONTBACK_BACK, 'back'] - ] - } - ], - "category": Categories.looks, - "extensions": ["colours_looks", "shape_statement"] - }); - } -}; - -Blockly.Blocks['looks_goforwardbackwardlayers'] = { - /** - * "Go forward/backward [Number] Layers" Block. - * @this Blockly.Block - */ - init: function() { - this.jsonInit({ - "message0": Blockly.Msg.LOOKS_GOFORWARDBACKWARDLAYERS, - "args0": [ - { - "type": "field_dropdown", - "name": "FORWARD_BACKWARD", - "options": [ - [Blockly.Msg.LOOKS_GOFORWARDBACKWARDLAYERS_FORWARD, 'forward'], - [Blockly.Msg.LOOKS_GOFORWARDBACKWARDLAYERS_BACKWARD, 'backward'] - ] - }, - { - "type": "input_value", - "name": "NUM" - } - ], - "category": Categories.looks, - "extensions": ["colours_looks", "shape_statement"] - }); - } -}; - -Blockly.Blocks['looks_backdropnumbername'] = { - /** - * Block to report backdrop's number or name - * @this Blockly.Block - */ - init: function() { - this.jsonInit({ - "message0": Blockly.Msg.LOOKS_BACKDROPNUMBERNAME, - "args0": [ - { - "type": "field_dropdown", - "name": "NUMBER_NAME", - "options": [ - [Blockly.Msg.LOOKS_NUMBERNAME_NUMBER, 'number'], - [Blockly.Msg.LOOKS_NUMBERNAME_NAME, 'name'] - ] - } - ], - "category": Categories.looks, - "extensions": ["colours_looks", "output_number"] - }); - this.checkboxInFlyout = true; - } -}; - -Blockly.Blocks['looks_costumenumbername'] = { - /** - * Block to report costume's number or name - * @this Blockly.Block - */ - init: function() { - this.jsonInit({ - "message0": Blockly.Msg.LOOKS_COSTUMENUMBERNAME, - "args0": [ - { - "type": "field_dropdown", - "name": "NUMBER_NAME", - "options": [ - [Blockly.Msg.LOOKS_NUMBERNAME_NUMBER, 'number'], - [Blockly.Msg.LOOKS_NUMBERNAME_NAME, 'name'] - ] - } - ], - "category": Categories.looks, - "extensions": ["colours_looks", "output_number"] - }); - this.checkboxInFlyout = true; - } -}; - -Blockly.Blocks['looks_switchbackdroptoandwait'] = { - /** - * Block to switch the backdrop to the selected one and wait. - * @this Blockly.Block - */ - init: function() { - this.jsonInit({ - "message0": Blockly.Msg.LOOKS_SWITCHBACKDROPTOANDWAIT, - "args0": [ - { - "type": "input_value", - "name": "BACKDROP" - } - ], - "category": Categories.looks, - "extensions": ["colours_looks", "shape_statement"] - }); - } -}; - -Blockly.Blocks['looks_nextbackdrop'] = { - /** - * Block to switch the backdrop to the next one. - * @this Blockly.Block - */ - init: function() { - this.jsonInit({ - "message0": Blockly.Msg.LOOKS_NEXTBACKDROP_BLOCK, - "category": Categories.looks, - "extensions": ["colours_looks", "shape_statement"] - }); - } -}; diff --git a/blocks_vertical/motion.js b/blocks_vertical/motion.js deleted file mode 100644 index a64a715e7b..0000000000 --- a/blocks_vertical/motion.js +++ /dev/null @@ -1,571 +0,0 @@ -/** - * @license - * Visual Blocks Editor - * - * Copyright 2016 Massachusetts Institute of Technology - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import * as Blockly from 'blockly/core'; -import {Categories} from '../src/categories.js'; - - -Blockly.Blocks['motion_movesteps'] = { - /** - * Block to move steps. - * @this Blockly.Block - */ - init: function() { - this.jsonInit({ - "message0": Blockly.Msg.MOTION_MOVESTEPS, - "args0": [ - { - "type": "input_value", - "name": "STEPS" - } - ], - "category": Categories.motion, - "extensions": ["colours_motion", "shape_statement"] - }); - } -}; - -Blockly.Blocks['motion_turnright'] = { - /** - * Block to turn right. - * @this Blockly.Block - */ - init: function() { - const ws = this.workspace.options.parentWorkspace || this.workspace; - this.jsonInit({ - "message0": Blockly.Msg.MOTION_TURNRIGHT, - "args0": [ - { - "type": "field_image", - "src": ws.options.pathToMedia + "rotate-right.svg", - "width": 24, - "height": 24 - }, - { - "type": "input_value", - "name": "DEGREES" - } - ], - "category": Categories.motion, - "extensions": ["colours_motion", "shape_statement"] - }); - } -}; - -Blockly.Blocks['motion_turnleft'] = { - /** - * Block to turn left. - * @this Blockly.Block - */ - init: function() { - const ws = this.workspace.options.parentWorkspace || this.workspace; - this.jsonInit({ - "message0": Blockly.Msg.MOTION_TURNLEFT, - "args0": [ - { - "type": "field_image", - "src": ws.options.pathToMedia + "rotate-left.svg", - "width": 24, - "height": 24 - }, - { - "type": "input_value", - "name": "DEGREES" - } - ], - "category": Categories.motion, - "extensions": ["colours_motion", "shape_statement"] - }); - } -}; - -Blockly.Blocks['motion_pointindirection'] = { - /** - * Block to point in direction. - * @this Blockly.Block - */ - init: function() { - this.jsonInit({ - "message0": Blockly.Msg.MOTION_POINTINDIRECTION, - "args0": [ - { - "type": "input_value", - "name": "DIRECTION" - } - ], - "category": Categories.motion, - "extensions": ["colours_motion", "shape_statement"] - }); - } -}; - -Blockly.Blocks['motion_pointtowards_menu'] = { - /** - * Point towards drop-down menu. - * @this Blockly.Block - */ - init: function() { - this.jsonInit({ - "message0": "%1", - "args0": [ - { - "type": "field_dropdown", - "name": "TOWARDS", - "options": [ - [Blockly.Msg.MOTION_POINTTOWARDS_POINTER, '_mouse_'], - [Blockly.Msg.MOTION_POINTTOWARDS_RANDOM, '_random_'] - ] - } - ], - "extensions": ["colours_motion", "output_string"] - }); - } -}; - -Blockly.Blocks['motion_pointtowards'] = { - /** - * Block to point in direction. - * @this Blockly.Block - */ - init: function() { - this.jsonInit({ - "message0": Blockly.Msg.MOTION_POINTTOWARDS, - "args0": [ - { - "type": "input_value", - "name": "TOWARDS" - } - ], - "category": Categories.motion, - "extensions": ["colours_motion", "shape_statement"] - }); - } -}; - -Blockly.Blocks['motion_goto_menu'] = { - /** - * Go to drop-down menu. - * @this Blockly.Block - */ - init: function() { - this.jsonInit({ - "message0": "%1", - "args0": [ - { - "type": "field_dropdown", - "name": "TO", - "options": [ - [Blockly.Msg.MOTION_GOTO_POINTER, '_mouse_'], - [Blockly.Msg.MOTION_GOTO_RANDOM, '_random_'] - ] - } - ], - "extensions": ["colours_motion", "output_string"] - }); - } -}; - -Blockly.Blocks['motion_gotoxy'] = { - /** - * Block to go to X, Y. - * @this Blockly.Block - */ - init: function() { - this.jsonInit({ - "message0": Blockly.Msg.MOTION_GOTOXY, - "args0": [ - { - "type": "input_value", - "name": "X" - }, - { - "type": "input_value", - "name": "Y" - } - ], - "category": Categories.motion, - "extensions": ["colours_motion", "shape_statement"] - }); - } -}; - -Blockly.Blocks['motion_goto'] = { - /** - * Block to go to a menu item. - * @this Blockly.Block - */ - init: function() { - this.jsonInit({ - "message0": Blockly.Msg.MOTION_GOTO, - "args0": [ - { - "type": "input_value", - "name": "TO" - } - ], - "category": Categories.motion, - "extensions": ["colours_motion", "shape_statement"] - }); - } -}; - -Blockly.Blocks['motion_glidesecstoxy'] = { - /** - * Block to glide for a specified time. - * @this Blockly.Block - */ - init: function() { - this.jsonInit({ - "message0": Blockly.Msg.MOTION_GLIDESECSTOXY, - "args0": [ - { - "type": "input_value", - "name": "SECS" - }, - { - "type": "input_value", - "name": "X" - }, - { - "type": "input_value", - "name": "Y" - } - ], - "category": Categories.motion, - "extensions": ["colours_motion", "shape_statement"] - }); - } -}; - -Blockly.Blocks['motion_glideto_menu'] = { - /** - * Glide to drop-down menu - * @this Blockly.Block - */ - init: function() { - this.jsonInit({ - "message0": "%1", - "args0": [ - { - "type": "field_dropdown", - "name": "TO", - "options": [ - [Blockly.Msg.MOTION_GLIDETO_POINTER, '_mouse_'], - [Blockly.Msg.MOTION_GLIDETO_RANDOM, '_random_'] - ] - } - ], - "extensions": ["colours_motion", "output_string"] - }); - } -}; - -Blockly.Blocks['motion_glideto'] = { - /** - * Block to glide to a menu item - * @this Blockly.Block - */ - init: function() { - this.jsonInit({ - "message0": Blockly.Msg.MOTION_GLIDETO, - "args0": [ - { - "type": "input_value", - "name": "SECS" - }, - { - "type": "input_value", - "name": "TO" - } - ], - "category": Categories.motion, - "extensions": ["colours_motion", "shape_statement"] - }); - } -}; - -Blockly.Blocks['motion_changexby'] = { - /** - * Block to change X. - * @this Blockly.Block - */ - init: function() { - this.jsonInit({ - "message0": Blockly.Msg.MOTION_CHANGEXBY, - "args0": [ - { - "type": "input_value", - "name": "DX" - } - ], - "category": Categories.motion, - "extensions": ["colours_motion", "shape_statement"] - }); - } -}; - -Blockly.Blocks['motion_setx'] = { - /** - * Block to set X. - * @this Blockly.Block - */ - init: function() { - this.jsonInit({ - "message0": Blockly.Msg.MOTION_SETX, - "args0": [ - { - "type": "input_value", - "name": "X" - } - ], - "category": Categories.motion, - "extensions": ["colours_motion", "shape_statement"] - }); - } -}; - -Blockly.Blocks['motion_changeyby'] = { - /** - * Block to change Y. - * @this Blockly.Block - */ - init: function() { - this.jsonInit({ - "message0": Blockly.Msg.MOTION_CHANGEYBY, - "args0": [ - { - "type": "input_value", - "name": "DY" - } - ], - "category": Categories.motion, - "extensions": ["colours_motion", "shape_statement"] - }); - } -}; - -Blockly.Blocks['motion_sety'] = { - /** - * Block to set Y. - * @this Blockly.Block - */ - init: function() { - this.jsonInit({ - "message0": Blockly.Msg.MOTION_SETY, - "args0": [ - { - "type": "input_value", - "name": "Y" - } - ], - "category": Categories.motion, - "extensions": ["colours_motion", "shape_statement"] - }); - } -}; - -Blockly.Blocks['motion_ifonedgebounce'] = { - /** - * Block to bounce on edge. - * @this Blockly.Block - */ - init: function() { - this.jsonInit({ - "message0": Blockly.Msg.MOTION_IFONEDGEBOUNCE, - "category": Categories.motion, - "extensions": ["colours_motion", "shape_statement"] - }); - } -}; - -Blockly.Blocks['motion_setrotationstyle'] = { - /** - * Block to set rotation style. - * @this Blockly.Block - */ - init: function() { - this.jsonInit({ - "message0": Blockly.Msg.MOTION_SETROTATIONSTYLE, - "args0": [ - { - "type": "field_dropdown", - "name": "STYLE", - "options": [ - [Blockly.Msg.MOTION_SETROTATIONSTYLE_LEFTRIGHT, 'left-right'], - [Blockly.Msg.MOTION_SETROTATIONSTYLE_DONTROTATE, 'don\'t rotate'], - [Blockly.Msg.MOTION_SETROTATIONSTYLE_ALLAROUND, 'all around'] - ] - } - ], - "category": Categories.motion, - "extensions": ["colours_motion", "shape_statement"] - }); - } -}; - -Blockly.Blocks['motion_xposition'] = { - /** - * Block to report X. - * @this Blockly.Block - */ - init: function() { - this.jsonInit({ - "message0": Blockly.Msg.MOTION_XPOSITION, - "category": Categories.motion, - "extensions": ["colours_motion", "output_number"] - }); - this.checkboxInFlyout = true; - } -}; - -Blockly.Blocks['motion_yposition'] = { - /** - * Block to report Y. - * @this Blockly.Block - */ - init: function() { - this.jsonInit({ - "message0": Blockly.Msg.MOTION_YPOSITION, - "category": Categories.motion, - "extensions": ["colours_motion", "output_number"] - }); - this.checkboxInFlyout = true; - } -}; - -Blockly.Blocks['motion_direction'] = { - /** - * Block to report direction. - * @this Blockly.Block - */ - init: function() { - this.jsonInit({ - "message0": Blockly.Msg.MOTION_DIRECTION, - "category": Categories.motion, - "extensions": ["colours_motion", "output_number"] - }); - this.checkboxInFlyout = true; - } -}; - -Blockly.Blocks['motion_scroll_right'] = { - /** - * Block to scroll the stage right. Does not actually do anything. This is - * an obsolete block that is implemented for compatibility with Scratch 2.0 - * projects. - * @this Blockly.Block - */ - init: function() { - this.jsonInit({ - "message0": Blockly.Msg.MOTION_SCROLLRIGHT, - "args0": [ - { - "type": "input_value", - "name": "DISTANCE" - } - ], - "category": Categories.motion, - "extensions": ["colours_motion", "shape_statement"] - }); - } -}; - -Blockly.Blocks['motion_scroll_up'] = { - /** - * Block to scroll the stage up. Does not actually do anything. This is an - * obsolete block that is implemented for compatibility with Scratch 2.0 - * projects. - * @this Blockly.Block - */ - init: function() { - this.jsonInit({ - "message0": Blockly.Msg.MOTION_SCROLLUP, - "args0": [ - { - "type": "input_value", - "name": "DISTANCE" - } - ], - "category": Categories.motion, - "extensions": ["colours_motion", "shape_statement"] - }); - } -}; - -Blockly.Blocks['motion_align_scene'] = { - /** - * Block to change the stage's scrolling alignment. Does not actually do - * anything. This is an obsolete block that is implemented for compatibility - * with Scratch 2.0 projects. - * @this Blockly.Block - */ - init: function() { - this.jsonInit({ - "message0": Blockly.Msg.MOTION_ALIGNSCENE, - "args0": [ - { - "type": "field_dropdown", - "name": "ALIGNMENT", - "options": [ - [Blockly.Msg.MOTION_ALIGNSCENE_BOTTOMLEFT, 'bottom-left'], - [Blockly.Msg.MOTION_ALIGNSCENE_BOTTOMRIGHT, 'bottom-right'], - [Blockly.Msg.MOTION_ALIGNSCENE_MIDDLE, 'middle'], - [Blockly.Msg.MOTION_ALIGNSCENE_TOPLEFT, 'top-left'], - [Blockly.Msg.MOTION_ALIGNSCENE_TOPRIGHT, 'top-right'] - ] - } - ], - "category": Categories.motion, - "extensions": ["colours_motion", "shape_statement"] - }); - } -}; - -Blockly.Blocks['motion_xscroll'] = { - /** - * Block to report the stage's scroll position's X value. Does not actually - * do anything. This is an obsolete block that is implemented for - * compatibility with Scratch 2.0 projects. - * @this Blockly.Block - */ - init: function() { - this.jsonInit({ - "message0": Blockly.Msg.MOTION_XSCROLL, - "category": Categories.motion, - "extensions": ["colours_motion", "output_number"] - }); - } -}; - -Blockly.Blocks['motion_yscroll'] = { - /** - * Block to report the stage's scroll position's Y value. Does not actually - * do anything. This is an obsolete block that is implemented for - * compatibility with Scratch 2.0 projects. - * @this Blockly.Block - */ - init: function() { - this.jsonInit({ - "message0": Blockly.Msg.MOTION_YSCROLL, - "category": Categories.motion, - "extensions": ["colours_motion", "output_number"] - }); - } -}; diff --git a/blocks_vertical/operators.js b/blocks_vertical/operators.js deleted file mode 100644 index f47c8743bf..0000000000 --- a/blocks_vertical/operators.js +++ /dev/null @@ -1,463 +0,0 @@ -/** - * @license - * Visual Blocks Editor - * - * Copyright 2012 Google Inc. - * https://developers.google.com/blockly/ - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import * as Blockly from 'blockly'; -import {Categories} from '../src/categories.js'; - -Blockly.Blocks['operator_add'] = { - /** - * Block for adding two numbers. - * @this Blockly.Block - */ - init: function() { - this.jsonInit({ - "message0": Blockly.Msg.OPERATORS_ADD, - "args0": [ - { - "type": "input_value", - "name": "NUM1" - }, - { - "type": "input_value", - "name": "NUM2" - } - ], - "category": Categories.operators, - "extensions": ["colours_operators", "output_number"] - }); - } -}; - -Blockly.Blocks['operator_subtract'] = { - /** - * Block for subtracting two numbers. - * @this Blockly.Block - */ - init: function() { - this.jsonInit({ - "message0": Blockly.Msg.OPERATORS_SUBTRACT, - "args0": [ - { - "type": "input_value", - "name": "NUM1" - }, - { - "type": "input_value", - "name": "NUM2" - } - ], - "category": Categories.operators, - "extensions": ["colours_operators", "output_number"] - }); - } -}; - -Blockly.Blocks['operator_multiply'] = { - /** - * Block for multiplying two numbers. - * @this Blockly.Block - */ - init: function() { - this.jsonInit({ - "message0": Blockly.Msg.OPERATORS_MULTIPLY, - "args0": [ - { - "type": "input_value", - "name": "NUM1" - }, - { - "type": "input_value", - "name": "NUM2" - } - ], - "category": Categories.operators, - "extensions": ["colours_operators", "output_number"] - }); - } -}; - -Blockly.Blocks['operator_divide'] = { - /** - * Block for dividing two numbers. - * @this Blockly.Block - */ - init: function() { - this.jsonInit({ - "message0": Blockly.Msg.OPERATORS_DIVIDE, - "args0": [ - { - "type": "input_value", - "name": "NUM1" - }, - { - "type": "input_value", - "name": "NUM2" - } - ], - "category": Categories.operators, - "extensions": ["colours_operators", "output_number"] - }); - } -}; - -Blockly.Blocks['operator_random'] = { - /** - * Block for picking a random number. - * @this Blockly.Block - */ - init: function() { - this.jsonInit({ - "message0": Blockly.Msg.OPERATORS_RANDOM, - "args0": [ - { - "type": "input_value", - "name": "FROM" - }, - { - "type": "input_value", - "name": "TO" - } - ], - "category": Categories.operators, - "extensions": ["colours_operators", "output_number"] - }); - } -}; - -Blockly.Blocks['operator_lt'] = { - /** - * Block for less than comparator. - * @this Blockly.Block - */ - init: function() { - this.jsonInit({ - "message0": Blockly.Msg.OPERATORS_LT, - "args0": [ - { - "type": "input_value", - "name": "OPERAND1" - }, - { - "type": "input_value", - "name": "OPERAND2" - } - ], - "category": Categories.operators, - "extensions": ["colours_operators", "output_boolean"] - }); - } -}; - -Blockly.Blocks['operator_equals'] = { - /** - * Block for equals comparator. - * @this Blockly.Block - */ - init: function() { - this.jsonInit({ - "message0": Blockly.Msg.OPERATORS_EQUALS, - "args0": [ - { - "type": "input_value", - "name": "OPERAND1" - }, - { - "type": "input_value", - "name": "OPERAND2" - } - ], - "category": Categories.operators, - "extensions": ["colours_operators", "output_boolean"] - }); - } -}; - -Blockly.Blocks['operator_gt'] = { - /** - * Block for greater than comparator. - * @this Blockly.Block - */ - init: function() { - this.jsonInit({ - "message0": Blockly.Msg.OPERATORS_GT, - "args0": [ - { - "type": "input_value", - "name": "OPERAND1" - }, - { - "type": "input_value", - "name": "OPERAND2" - } - ], - "category": Categories.operators, - "extensions": ["colours_operators", "output_boolean"] - }); - } -}; - -Blockly.Blocks['operator_and'] = { - /** - * Block for "and" boolean comparator. - * @this Blockly.Block - */ - init: function() { - this.jsonInit({ - "message0": Blockly.Msg.OPERATORS_AND, - "args0": [ - { - "type": "input_value", - "name": "OPERAND1", - "check": "Boolean" - }, - { - "type": "input_value", - "name": "OPERAND2", - "check": "Boolean" - } - ], - "category": Categories.operators, - "extensions": ["colours_operators", "output_boolean"] - }); - } -}; - -Blockly.Blocks['operator_or'] = { - /** - * Block for "or" boolean comparator. - * @this Blockly.Block - */ - init: function() { - this.jsonInit({ - "message0": Blockly.Msg.OPERATORS_OR, - "args0": [ - { - "type": "input_value", - "name": "OPERAND1", - "check": "Boolean" - }, - { - "type": "input_value", - "name": "OPERAND2", - "check": "Boolean" - } - ], - "category": Categories.operators, - "extensions": ["colours_operators", "output_boolean"] - }); - } -}; - -Blockly.Blocks['operator_not'] = { - /** - * Block for "not" unary boolean operator. - * @this Blockly.Block - */ - init: function() { - this.jsonInit({ - "message0": Blockly.Msg.OPERATORS_NOT, - "args0": [ - { - "type": "input_value", - "name": "OPERAND", - "check": "Boolean" - } - ], - "category": Categories.operators, - "extensions": ["colours_operators", "output_boolean"] - }); - } -}; - -Blockly.Blocks['operator_join'] = { - /** - * Block for string join operator. - * @this Blockly.Block - */ - init: function() { - this.jsonInit({ - "message0": Blockly.Msg.OPERATORS_JOIN, - "args0": [ - { - "type": "input_value", - "name": "STRING1" - }, - { - "type": "input_value", - "name": "STRING2" - } - ], - "category": Categories.operators, - "extensions": ["colours_operators", "output_string"] - }); - } -}; - -Blockly.Blocks['operator_letter_of'] = { - /** - * Block for "letter _ of _" operator. - * @this Blockly.Block - */ - init: function() { - this.jsonInit({ - "message0": Blockly.Msg.OPERATORS_LETTEROF, - "args0": [ - { - "type": "input_value", - "name": "LETTER" - }, - { - "type": "input_value", - "name": "STRING" - } - ], - "category": Categories.operators, - "extensions": ["colours_operators", "output_string"] - }); - } -}; - -Blockly.Blocks['operator_length'] = { - /** - * Block for string length operator. - * @this Blockly.Block - */ - init: function() { - this.jsonInit({ - "message0": Blockly.Msg.OPERATORS_LENGTH, - "args0": [ - { - "type": "input_value", - "name": "STRING" - } - ], - "category": Categories.operators, - "extensions": ["colours_operators", "output_string"] - }); - } -}; - -Blockly.Blocks['operator_contains'] = { - /** - * Block for _ contains _ operator - * @this Blockly.Block - */ - init: function() { - this.jsonInit({ - "message0": Blockly.Msg.OPERATORS_CONTAINS, - "args0": [ - { - "type": "input_value", - "name": "STRING1" - }, - { - "type": "input_value", - "name": "STRING2" - } - ], - "category": Categories.operators, - "extensions": ["colours_operators", "output_boolean"] - }); - } -}; - -Blockly.Blocks['operator_mod'] = { - /** - * Block for mod two numbers. - * @this Blockly.Block - */ - init: function() { - this.jsonInit({ - "message0": Blockly.Msg.OPERATORS_MOD, - "args0": [ - { - "type": "input_value", - "name": "NUM1" - }, - { - "type": "input_value", - "name": "NUM2" - } - ], - "category": Categories.operators, - "extensions": ["colours_operators", "output_number"] - }); - } -}; - -Blockly.Blocks['operator_round'] = { - /** - * Block for rounding a numbers. - * @this Blockly.Block - */ - init: function() { - this.jsonInit({ - "message0": Blockly.Msg.OPERATORS_ROUND, - "args0": [ - { - "type": "input_value", - "name": "NUM" - } - ], - "category": Categories.operators, - "extensions": ["colours_operators", "output_number"] - }); - } -}; - -Blockly.Blocks['operator_mathop'] = { - /** - * Block for "advanced" math ops on a number. - * @this Blockly.Block - */ - init: function() { - this.jsonInit({ - "message0": Blockly.Msg.OPERATORS_MATHOP, - "args0": [ - { - "type": "field_dropdown", - "name": "OPERATOR", - "options": [ - [Blockly.Msg.OPERATORS_MATHOP_ABS, 'abs'], - [Blockly.Msg.OPERATORS_MATHOP_FLOOR, 'floor'], - [Blockly.Msg.OPERATORS_MATHOP_CEILING, 'ceiling'], - [Blockly.Msg.OPERATORS_MATHOP_SQRT, 'sqrt'], - [Blockly.Msg.OPERATORS_MATHOP_SIN, 'sin'], - [Blockly.Msg.OPERATORS_MATHOP_COS, 'cos'], - [Blockly.Msg.OPERATORS_MATHOP_TAN, 'tan'], - [Blockly.Msg.OPERATORS_MATHOP_ASIN, 'asin'], - [Blockly.Msg.OPERATORS_MATHOP_ACOS, 'acos'], - [Blockly.Msg.OPERATORS_MATHOP_ATAN, 'atan'], - [Blockly.Msg.OPERATORS_MATHOP_LN, 'ln'], - [Blockly.Msg.OPERATORS_MATHOP_LOG, 'log'], - [Blockly.Msg.OPERATORS_MATHOP_EEXP, 'e ^'], - [Blockly.Msg.OPERATORS_MATHOP_10EXP, '10 ^'] - ] - }, - { - "type": "input_value", - "name": "NUM" - } - ], - "category": Categories.operators, - "extensions": ["colours_operators", "output_number"] - }); - } -}; diff --git a/blocks_vertical/sound.js b/blocks_vertical/sound.js deleted file mode 100644 index bdb5697e75..0000000000 --- a/blocks_vertical/sound.js +++ /dev/null @@ -1,210 +0,0 @@ -/** - * @license - * Visual Blocks Editor - * - * Copyright 2016 Massachusetts Institute of Technology - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import * as Blockly from 'blockly/core'; -import {Categories} from '../src/categories.js'; - -Blockly.Blocks['sound_sounds_menu'] = { - /** - * Sound effects drop-down menu. Populated dynamically by scratch-gui. - * @this Blockly.Block - */ -}; - -Blockly.Blocks['sound_play'] = { - /** - * Block to play sound. - * @this Blockly.Block - */ - init: function() { - this.jsonInit({ - "message0": Blockly.Msg.SOUND_PLAY, - "args0": [ - { - "type": "input_value", - "name": "SOUND_MENU" - } - ], - "category": Categories.sound, - "extensions": ["colours_sounds", "shape_statement"] - }); - } -}; - -Blockly.Blocks['sound_playuntildone'] = { - /** - * Block to play sound until done. - * @this Blockly.Block - */ - init: function() { - this.jsonInit({ - "message0": Blockly.Msg.SOUND_PLAYUNTILDONE, - "args0": [ - { - "type": "input_value", - "name": "SOUND_MENU" - } - ], - "category": Categories.sound, - "extensions": ["colours_sounds", "shape_statement"] - }); - } -}; - -Blockly.Blocks['sound_stopallsounds'] = { - /** - * Block to stop all sounds - * @this Blockly.Block - */ - init: function() { - this.jsonInit({ - "message0": Blockly.Msg.SOUND_STOPALLSOUNDS, - "category": Categories.sound, - "extensions": ["colours_sounds", "shape_statement"] - }); - } -}; - -Blockly.Blocks['sound_seteffectto'] = { - /** - * Block to set the audio effect - * @this Blockly.Block - */ - init: function() { - this.jsonInit({ - "message0": Blockly.Msg.SOUND_SETEFFECTO, - "args0": [ - { - "type": "field_dropdown", - "name": "EFFECT", - "options": [ - [Blockly.Msg.SOUND_EFFECTS_PITCH, 'PITCH'], - [Blockly.Msg.SOUND_EFFECTS_PAN, 'PAN'] - ] - }, - { - "type": "input_value", - "name": "VALUE" - } - ], - "category": Categories.sound, - "extensions": ["colours_sounds", "shape_statement"] - }); - } -}; - - -Blockly.Blocks['sound_changeeffectby'] = { - /** - * Block to change the audio effect - * @this Blockly.Block - */ - init: function() { - this.jsonInit({ - "message0": Blockly.Msg.SOUND_CHANGEEFFECTBY, - "args0": [ - { - "type": "field_dropdown", - "name": "EFFECT", - "options": [ - [Blockly.Msg.SOUND_EFFECTS_PITCH, 'PITCH'], - [Blockly.Msg.SOUND_EFFECTS_PAN, 'PAN'] - ] - }, - { - "type": "input_value", - "name": "VALUE" - } - ], - "category": Categories.sound, - "extensions": ["colours_sounds", "shape_statement"] - }); - } -}; - -Blockly.Blocks['sound_cleareffects'] = { - /** - * Block to clear audio effects - * @this Blockly.Block - */ - init: function() { - this.jsonInit({ - "message0": Blockly.Msg.SOUND_CLEAREFFECTS, - "category": Categories.sound, - "extensions": ["colours_sounds", "shape_statement"] - }); - } -}; - -Blockly.Blocks['sound_changevolumeby'] = { - /** - * Block to change the sprite's volume by a certain value - * @this Blockly.Block - */ - init: function() { - this.jsonInit({ - "message0": Blockly.Msg.SOUND_CHANGEVOLUMEBY, - "args0": [ - { - "type": "input_value", - "name": "VOLUME" - } - ], - "category": Categories.sound, - "extensions": ["colours_sounds", "shape_statement"] - }); - } -}; - -Blockly.Blocks['sound_setvolumeto'] = { - /** - * Block to set the sprite's volume to a certain percent - * @this Blockly.Block - */ - init: function() { - this.jsonInit({ - "message0": Blockly.Msg.SOUND_SETVOLUMETO, - "args0": [ - { - "type": "input_value", - "name": "VOLUME" - } - ], - "category": Categories.sound, - "extensions": ["colours_sounds", "shape_statement"] - }); - } -}; - -Blockly.Blocks['sound_volume'] = { - /** - * Block to report volume - * @this Blockly.Block - */ - init: function() { - this.jsonInit({ - "message0": Blockly.Msg.SOUND_VOLUME, - "category": Categories.sound, - "checkboxInFlyout": true, - "extensions": ["colours_sounds", "output_number"] - }); - this.checkboxInFlyout = true; - } -}; diff --git a/build.py b/build.py deleted file mode 100755 index 3fc56e5fd3..0000000000 --- a/build.py +++ /dev/null @@ -1,636 +0,0 @@ -#!/usr/bin/python2.7 -# Compresses the core Blockly files into a single JavaScript file. -# -# Copyright 2012 Google Inc. -# https://developers.google.com/blockly/ -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# This script generates two versions of Blockly's core files: -# blockly_compressed.js -# blockly_uncompressed.js -# The compressed file is a concatenation of all of Blockly's core files which -# have been run through Google's Closure Compiler. This is done using the -# online API (which takes a few seconds and requires an Internet connection). -# The uncompressed file is a script that loads in each of Blockly's core files -# one by one. This takes much longer for a browser to load, but is useful -# when debugging code since line numbers are meaningful and variables haven't -# been renamed. The uncompressed file also allows for a faster developement -# cycle since there is no need to rebuild or recompile, just reload. -# -# This script also generates: -# blocks_compressed.js: The compressed common blocks. -# blocks_horizontal_compressed.js: The compressed Scratch horizontal blocks. -# blocks_vertical_compressed.js: The compressed Scratch vertical blocks. -# msg/js/.js for every language defined in msg/js/.json. - -import sys - -import errno, glob, json, os, re, subprocess, threading, codecs, functools - -if sys.version_info[0] == 2: - import httplib - from urllib import urlencode -else: - import http.client as httplib - from urllib.parse import urlencode - from importlib import reload - -REMOTE_COMPILER = "remote" - -CLOSURE_DIR = os.path.pardir -CLOSURE_ROOT = os.path.pardir -CLOSURE_LIBRARY = "closure-library" -CLOSURE_COMPILER = REMOTE_COMPILER - -CLOSURE_DIR_NPM = "node_modules" -CLOSURE_ROOT_NPM = os.path.join("node_modules") -CLOSURE_LIBRARY_NPM = "google-closure-library" -CLOSURE_COMPILER_NPM = ("google-closure-compiler.cmd" if os.name == "nt" else "google-closure-compiler") - -def import_path(fullpath): - """Import a file with full path specification. - Allows one to import from any directory, something __import__ does not do. - - Args: - fullpath: Path and filename of import. - - Returns: - An imported module. - """ - path, filename = os.path.split(fullpath) - filename, ext = os.path.splitext(filename) - sys.path.append(path) - module = __import__(filename) - reload(module) # Might be out of date. - del sys.path[-1] - return module - -def read(filename): - f = open(filename) - content = "".join(f.readlines()) - f.close() - return content - -HEADER = ("// Do not edit this file; automatically generated by build.py.\n" - "'use strict';\n") - - -class Gen_uncompressed(threading.Thread): - """Generate a JavaScript file that loads Blockly's raw files. - Runs in a separate thread. - """ - def __init__(self, search_paths, vertical, closure_env): - threading.Thread.__init__(self) - self.search_paths = search_paths - self.vertical = vertical - self.closure_env = closure_env - - def run(self): - if self.vertical: - target_filename = 'blockly_uncompressed_vertical.js' - else: - target_filename = 'blockly_uncompressed_horizontal.js' - f = open(target_filename, 'w') - f.write(HEADER) - f.write(self.format_js(""" -var isNodeJS = !!(typeof module !== 'undefined' && module.exports && - typeof window === 'undefined'); - -if (isNodeJS) { - var window = {}; - require('{closure_library}'); -} - -window.BLOCKLY_DIR = (function() { - if (!isNodeJS) { - // Find name of current directory. - var scripts = document.getElementsByTagName('script'); - var re = new RegExp('(.+)[\/]blockly_uncompressed(_vertical|_horizontal|)\.js$'); - for (var i = 0, script; script = scripts[i]; i++) { - var match = re.exec(script.src); - if (match) { - return match[1]; - } - } - alert('Could not detect Blockly\\'s directory name.'); - } - return ''; -})(); - -window.BLOCKLY_BOOT = function() { - var dir = ''; - if (isNodeJS) { - require('{closure_library}'); - dir = 'blockly'; - } else { - // Execute after Closure has loaded. - if (!window.goog) { - alert('Error: Closure not found. Read this:\\n' + - 'developers.google.com/blockly/guides/modify/web/closure'); - } - if (window.BLOCKLY_DIR.search(/node_modules/)) { - dir = '..'; - } else { - dir = window.BLOCKLY_DIR.match(/[^\\/]+$/)[0]; - } - } -""")) - add_dependency = [] - base_path = calcdeps.FindClosureBasePath(self.search_paths) - for dep in calcdeps.BuildDependenciesFromFiles(self.search_paths): - add_dependency.append(calcdeps.GetDepsLine(dep, base_path)) - add_dependency.sort() # Deterministic build. - add_dependency = '\n'.join(add_dependency) - # Find the Blockly directory name and replace it with a JS variable. - # This allows blockly_uncompressed.js to be compiled on one computer and be - # used on another, even if the directory name differs. - m = re.search('[\\/]([^\\/]+)[\\/]core[\\/]blockly.js', add_dependency) - add_dependency = re.sub('([\\/])' + re.escape(m.group(1)) + - '([\\/]core[\\/])', '\\1" + dir + "\\2', add_dependency) - f.write(add_dependency + '\n') - - provides = [] - for dep in calcdeps.BuildDependenciesFromFiles(self.search_paths): - # starts with '../' or 'node_modules/' - if not dep.filename.startswith(self.closure_env["closure_root"] + os.sep): - provides.extend(dep.provides) - provides.sort() # Deterministic build. - f.write('\n') - f.write('// Load Blockly.\n') - for provide in provides: - f.write("goog.require('%s');\n" % provide) - - f.write(self.format_js(""" -delete this.BLOCKLY_DIR; -delete this.BLOCKLY_BOOT; -}; - -if (isNodeJS) { - window.BLOCKLY_BOOT(); - module.exports = Blockly; -} else { - // Delete any existing Closure (e.g. Soy's nogoog_shim). - document.write(''); - // Load fresh Closure Library. - document.write(''); - document.write(''); -} -""")) - f.close() - print("SUCCESS: " + target_filename) - - def format_js(self, code): - """Format JS in a way that python's format method can work with to not - consider brace-wrapped sections to be format replacements while still - replacing known keys. - """ - - key_whitelist = self.closure_env.keys() - - keys_pipe_separated = functools.reduce(lambda accum, key: accum + "|" + key, key_whitelist) - begin_brace = re.compile(r"\{(?!%s)" % (keys_pipe_separated,)) - - end_brace = re.compile(r"\}") - def end_replacement(match): - try: - maybe_key = match.string[match.string[:match.start()].rindex("{") + 1:match.start()] - except ValueError: - return "}}" - - if maybe_key and maybe_key in key_whitelist: - return "}" - else: - return "}}" - - return begin_brace.sub("{{", end_brace.sub(end_replacement, code)).format(**self.closure_env) - -class Gen_compressed(threading.Thread): - """Generate a JavaScript file that contains all of Blockly's core and all - required parts of Closure, compiled together. - Uses the Closure Compiler's online API. - Runs in a separate thread. - """ - def __init__(self, search_paths_vertical, search_paths_horizontal, closure_env): - threading.Thread.__init__(self) - self.search_paths_vertical = search_paths_vertical - self.search_paths_horizontal = search_paths_horizontal - self.closure_env = closure_env - - def run(self): - self.gen_core(True) - self.gen_core(False) - self.gen_blocks("horizontal") - self.gen_blocks("vertical") - self.gen_blocks("common") - - def gen_core(self, vertical): - if vertical: - target_filename = 'blockly_compressed_vertical.js' - search_paths = self.search_paths_vertical - else: - target_filename = 'blockly_compressed_horizontal.js' - search_paths = self.search_paths_horizontal - # Define the parameters for the POST request. - params = [ - ("compilation_level", "SIMPLE"), - - # remote will filter this out - ("language_in", "ECMASCRIPT_2017"), - ("language_out", "ECMASCRIPT5"), - ("rewrite_polyfills", "false"), - ("define", "goog.DEBUG=false"), - - # local will filter this out - ("use_closure_library", "true"), - ] - - # Read in all the source files. - filenames = calcdeps.CalculateDependencies(search_paths, - [os.path.join("core", "blockly.js")]) - filenames.sort() # Deterministic build. - for filename in filenames: - # Append filenames as false arguments the step before compiling will - # either transform them into arguments for local or remote compilation - params.append(("js_file", filename)) - - self.do_compile(params, target_filename, filenames, "") - - def gen_blocks(self, block_type): - if block_type == "horizontal": - target_filename = "blocks_compressed_horizontal.js" - filenames = glob.glob(os.path.join("blocks_horizontal", "*.js")) - elif block_type == "vertical": - target_filename = "blocks_compressed_vertical.js" - filenames = glob.glob(os.path.join("blocks_vertical", "*.js")) - elif block_type == "common": - target_filename = "blocks_compressed.js" - filenames = glob.glob(os.path.join("blocks_common", "*.js")) - - # glob.glob ordering is platform-dependent and not necessary deterministic - filenames.sort() # Deterministic build. - - # Define the parameters for the POST request. - params = [ - ("compilation_level", "SIMPLE"), - ] - - # Read in all the source files. - # Add Blockly.Blocks to be compatible with the compiler. - params.append(("js_file", os.path.join("build", "gen_blocks.js"))) - # Add Blockly.Colours for use of centralized colour bank - filenames.append(os.path.join("core", "colours.js")) - filenames.append(os.path.join("core", "constants.js")) - - for filename in filenames: - # Append filenames as false arguments the step before compiling will - # either transform them into arguments for local or remote compilation - params.append(("js_file", filename)) - - # Remove Blockly.Blocks to be compatible with Blockly. - remove = "var Blockly={Blocks:{}};" - self.do_compile(params, target_filename, filenames, remove) - - def do_compile(self, params, target_filename, filenames, remove): - if self.closure_env["closure_compiler"] == REMOTE_COMPILER: - do_compile = self.do_compile_remote - else: - do_compile = self.do_compile_local - json_data = do_compile(params, target_filename) - - if self.report_errors(target_filename, filenames, json_data): - self.write_output(target_filename, remove, json_data) - self.report_stats(target_filename, json_data) - - def do_compile_local(self, params, target_filename): - filter_keys = ["use_closure_library"] - - # Drop arg if arg is js_file else add dashes - dash_params = [] - for (arg, value) in params: - dash_params.append((value,) if arg == "js_file" else ("--" + arg, value)) - - # Flatten dash_params into dash_args if their keys are not in filter_keys - dash_args = [] - for pair in dash_params: - if pair[0][2:] not in filter_keys: - dash_args.extend(pair) - - # Build the final args array by prepending CLOSURE_COMPILER_NPM to - # dash_args and dropping any falsy members - args = [] - for group in [[CLOSURE_COMPILER_NPM], dash_args]: - args.extend(filter(lambda item: item, group)) - - proc = subprocess.Popen(args, stdin=subprocess.PIPE, stdout=subprocess.PIPE) - (stdout, stderr) = proc.communicate() - - # Build the JSON response. - filesizes = [os.path.getsize(value) for (arg, value) in params if arg == "js_file"] - return dict( - compiledCode=stdout, - statistics=dict( - originalSize=functools.reduce(lambda v, size: v + size, filesizes, 0), - compressedSize=len(stdout), - ) - ) - - def do_compile_remote(self, params, target_filename): - filter_keys = [ - "language_in", - "language_out", - "rewrite_polyfills", - "define", - ] - - params.extend([ - ("output_format", "json"), - ("output_info", "compiled_code"), - ("output_info", "warnings"), - ("output_info", "errors"), - ("output_info", "statistics"), - ]) - - # Send the request to Google. - remoteParams = [] - for (arg, value) in params: - if not arg in filter_keys: - if arg == "js_file": - if not value.startswith(self.closure_env["closure_root"] + os.sep): - remoteParams.append(("js_code", read(value))) - # Change the normal compilation_level value SIMPLE to the remove - # service's SIMPLE_OPTIMIZATIONS - elif arg == "compilation_level" and value == "SIMPLE": - remoteParams.append((arg, "SIMPLE_OPTIMIZATIONS")) - else: - remoteParams.append((arg, value)) - - headers = {"Content-type": "application/x-www-form-urlencoded"} - conn = httplib.HTTPSConnection("closure-compiler.appspot.com") - conn.request("POST", "/compile", urlencode(remoteParams), headers) - response = conn.getresponse() - # Decode is necessary for Python 3.4 compatibility - json_str = response.read().decode("utf-8") - conn.close() - - # Parse the JSON response. - return json.loads(json_str) - - def report_errors(self, target_filename, filenames, json_data): - def file_lookup(name): - if not name.startswith("Input_"): - return "???" - n = int(name[6:]) - 1 - return filenames[n] - - if "serverErrors" in json_data: - errors = json_data["serverErrors"] - for error in errors: - print("SERVER ERROR: %s" % target_filename) - print(error["error"]) - elif "errors" in json_data: - errors = json_data["errors"] - for error in errors: - print("FATAL ERROR") - print(error["error"]) - if error["file"]: - print("%s at line %d:" % ( - file_lookup(error["file"]), error["lineno"])) - print(error["line"]) - print((" " * error["charno"]) + "^") - sys.exit(1) - else: - if "warnings" in json_data: - warnings = json_data["warnings"] - for warning in warnings: - print("WARNING") - print(warning["warning"]) - if warning["file"]: - print("%s at line %d:" % ( - file_lookup(warning["file"]), warning["lineno"])) - print(warning["line"]) - print((" " * warning["charno"]) + "^") - print() - - return True - - return False - - def write_output(self, target_filename, remove, json_data): - if "compiledCode" not in json_data: - print("FATAL ERROR: Compiler did not return compiledCode.") - sys.exit(1) - - code = HEADER + "\n" + json_data["compiledCode"].decode("utf-8") - code = code.replace(remove, "") - - # Trim down Google's (and only Google's) Apache licences. - # The Closure Compiler preserves these. - LICENSE = re.compile("""/\\* - - [\w ]+ - - Copyright \\d+ Google Inc. - https://developers.google.com/blockly/ - - Licensed under the Apache License, Version 2.0 \(the "License"\); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -\\*/""") - code = re.sub(LICENSE, "", code) - - stats = json_data["statistics"] - original_b = stats["originalSize"] - compressed_b = stats["compressedSize"] - if original_b > 0 and compressed_b > 0: - f = open(target_filename, "w") - f.write(code) - f.close() - - def report_stats(self, target_filename, json_data): - stats = json_data["statistics"] - original_b = stats["originalSize"] - compressed_b = stats["compressedSize"] - if original_b > 0 and compressed_b > 0: - original_kb = int(original_b / 1024 + 0.5) - compressed_kb = int(compressed_b / 1024 + 0.5) - ratio = int(float(compressed_b) / float(original_b) * 100 + 0.5) - print("SUCCESS: " + target_filename) - print("Size changed from %d KB to %d KB (%d%%)." % ( - original_kb, compressed_kb, ratio)) - else: - print("UNKNOWN ERROR") - - -class Gen_langfiles(threading.Thread): - """Generate JavaScript file for each natural language supported. - - Runs in a separate thread. - """ - - def __init__(self): - threading.Thread.__init__(self) - - def _rebuild(self, srcs, dests): - # Determine whether any of the files in srcs is newer than any in dests. - try: - return (max(os.path.getmtime(src) for src in srcs) > - min(os.path.getmtime(dest) for dest in dests)) - except OSError as e: - # Was a file not found? - if e.errno == errno.ENOENT: - # If it was a source file, we can't proceed. - if e.filename in srcs: - print("Source file missing: " + e.filename) - sys.exit(1) - else: - # If a destination file was missing, rebuild. - return True - else: - print("Error checking file creation times: " + str(e)) - - def run(self): - # The files msg/json/{en,qqq,synonyms}.json depend on msg/messages.js. - if self._rebuild([os.path.join("msg", "messages.js")], - [os.path.join("msg", "json", f) for f in - ["en.json", "qqq.json", "synonyms.json"]]): - try: - subprocess.check_call([ - "python", - os.path.join("i18n", "js_to_json.py"), - "--input_file", "msg/messages.js", - "--output_dir", "msg/json/", - "--quiet"]) - except (subprocess.CalledProcessError, OSError) as e: - # Documentation for subprocess.check_call says that CalledProcessError - # will be raised on failure, but I found that OSError is also possible. - print("Error running i18n/js_to_json.py: ", e) - sys.exit(1) - - # Checking whether it is necessary to rebuild the js files would be a lot of - # work since we would have to compare each .json file with each - # .js file. Rebuilding is easy and cheap, so just go ahead and do it. - try: - # Use create_messages.py to create .js files from .json files. - cmd = [ - "python", - os.path.join("i18n", "create_messages.py"), - "--source_lang_file", os.path.join("msg", "json", "en.json"), - "--source_synonym_file", os.path.join("msg", "json", "synonyms.json"), - "--source_constants_file", os.path.join("msg", "json", "constants.json"), - "--key_file", os.path.join("msg", "json", "keys.json"), - "--output_dir", os.path.join("msg", "js"), - "--quiet"] - json_files = glob.glob(os.path.join("msg", "json", "*.json")) - json_files = [file for file in json_files if not - (file.endswith(("keys.json", "synonyms.json", "qqq.json", "constants.json")))] - cmd.extend(json_files) - subprocess.check_call(cmd) - except (subprocess.CalledProcessError, OSError) as e: - print("Error running i18n/create_messages.py: ", e) - sys.exit(1) - - # Output list of .js files created. - for f in json_files: - # This assumes the path to the current directory does not contain "json". - f = f.replace("json", "js") - if os.path.isfile(f): - print("SUCCESS: " + f) - else: - print("FAILED to create " + f) - -def exclude_vertical(item): - return not item.endswith("block_render_svg_vertical.js") - -def exclude_horizontal(item): - return not item.endswith("block_render_svg_horizontal.js") - -if __name__ == "__main__": - try: - closure_dir = CLOSURE_DIR_NPM - closure_root = CLOSURE_ROOT_NPM - closure_library = CLOSURE_LIBRARY_NPM - closure_compiler = CLOSURE_COMPILER_NPM - - # Load calcdeps from the local library - calcdeps = import_path(os.path.join( - closure_root, closure_library, "closure", "bin", "calcdeps.py")) - - # Sanity check the local compiler - test_args = [closure_compiler, os.path.join("build", "test_input.js")] - test_proc = subprocess.Popen(test_args, stdin=subprocess.PIPE, stdout=subprocess.PIPE) - (stdout, _) = test_proc.communicate() - assert stdout.decode("utf-8") == read(os.path.join("build", "test_expect.js")) - - print("Using local compiler: %s ...\n" % CLOSURE_COMPILER_NPM) - except (ImportError, AssertionError): - print("Using remote compiler: closure-compiler.appspot.com ...\n") - - try: - closure_dir = CLOSURE_DIR - closure_root = CLOSURE_ROOT - closure_library = CLOSURE_LIBRARY - closure_compiler = CLOSURE_COMPILER - - calcdeps = import_path(os.path.join( - closure_root, closure_library, "closure", "bin", "calcdeps.py")) - except ImportError: - if os.path.isdir(os.path.join(os.path.pardir, "closure-library-read-only")): - # Dir got renamed when Closure moved from Google Code to GitHub in 2014. - print("Error: Closure directory needs to be renamed from" - "'closure-library-read-only' to 'closure-library'.\n" - "Please rename this directory.") - elif os.path.isdir(os.path.join(os.path.pardir, "google-closure-library")): - print("Error: Closure directory needs to be renamed from" - "'google-closure-library' to 'closure-library'.\n" - "Please rename this directory.") - else: - print("""Error: Closure not found. Read this: - developers.google.com/blockly/guides/modify/web/closure""") - sys.exit(1) - - search_paths = list(calcdeps.ExpandDirectories( - ["core", os.path.join(closure_root, closure_library)])) - - search_paths_horizontal = list(filter(exclude_vertical, search_paths)) - search_paths_vertical = list(filter(exclude_horizontal, search_paths)) - - closure_env = { - "closure_dir": closure_dir, - "closure_root": closure_root, - "closure_library": closure_library, - "closure_compiler": closure_compiler, - } - - # Run all tasks in parallel threads. - # Uncompressed is limited by processor speed. - # Compressed is limited by network and server speed. - # Vertical: - Gen_uncompressed(search_paths_vertical, True, closure_env).start() - # Horizontal: - Gen_uncompressed(search_paths_horizontal, False, closure_env).start() - - # Compressed forms of vertical and horizontal. - Gen_compressed(search_paths_vertical, search_paths_horizontal, closure_env).start() - - # This is run locally in a separate thread. - # Gen_langfiles().start() diff --git a/build/gen_blocks.js b/build/gen_blocks.js deleted file mode 100644 index 2ab6e688b5..0000000000 --- a/build/gen_blocks.js +++ /dev/null @@ -1 +0,0 @@ -goog.provide('Blockly.Blocks'); diff --git a/build/test_expect.js b/build/test_expect.js deleted file mode 100644 index 555c3f7c54..0000000000 --- a/build/test_expect.js +++ /dev/null @@ -1 +0,0 @@ -var Blockly={Blocks:{}}; diff --git a/build/test_input.js b/build/test_input.js deleted file mode 100644 index 2ab6e688b5..0000000000 --- a/build/test_input.js +++ /dev/null @@ -1 +0,0 @@ -goog.provide('Blockly.Blocks'); diff --git a/cleanup.sh b/cleanup.sh deleted file mode 100755 index 8af8cf6a70..0000000000 --- a/cleanup.sh +++ /dev/null @@ -1,101 +0,0 @@ -#!/bin/bash - -# Script for cleaning up blockly-specific files when merging blockly into scratch-blocks -# Removes files and directories that scratch-blocks doesn't want. -# Rachel Fenichel (fenichel@google.com) - -# Note: 'ours' is scratch-blocks, 'theirs' is blockly. - -# Formatting helpers. -indent() { sed 's/^/ /'; } -indent_more() { sed 's/^/\t/'; } -empty_lines() { printf '\n\n'; } - - -empty_lines -echo Cleaning up a merge from Blockly to Scratch-Blocks... - -# Get rid of Blockly's internationalization/messages. This is not usually worth -# scrolling up to look at. -empty_lines -echo Cleaning up Blockly message files... -# Turn on more powerful globbing -shopt -s extglob - -# Having trouble with directories. Let's just go there. -cd msg/json -git rm -f !(en.json|synonyms.json) | indent_more -cd ../.. - -# Having trouble with directories. Let's just go there. -cd msg/js -git rm -f !(en.js) | indent_more -cd ../.. - -# Turn powerful globbing off again -shopt -u extglob - -# Whole directories that we want to get rid of. -empty_lines -echo Removing blockly-specific directories... -dirslist="accessible demos tests/generators appengine blocks local_build" -for directory in $dirslist -do - echo 'Cleaning up' $directory | indent - git rm -rf $directory | indent_more -done - -# Scratch-blocks does not use generators -empty_lines -echo Removing generators... -generated_langs="dart javascript lua php python" -for lang in $generated_langs -do - echo 'Cleaning up' $lang | indent - # Directories containing block generators. - git rm -rf generators/${lang} | indent_more -done - -# Built stuff that we should get rid of. -empty_lines -echo Removing built files... -built_files="blockly_compressed.js \ -blockly_uncompressed.js \ -blockly_accessible_compressed.js \ -blockly_accessible_uncompressed.js \ -blocks_compressed.js \ -dart_compressed.js \ -php_compressed.js \ -python_compressed.js \ -javascript_compressed.js \ -lua_compressed.js" - -for filename in $built_files -do - git rm $filename | indent_more -done - -empty_lines -echo Miscellaneous cleanup... -# Use ours. -keep_ours=".github/ISSUE_TEMPLATE.md \ -.github/PULL_REQUEST_TEMPLATE.md \ -.gitignore \ -.circleci/config.yml \ -core/block_animations.js \ -msg/messages.js \ -msg/js/en.js \ -msg/json/en.json" - - -for filename in $keep_ours -do - git checkout --ours $filename && git add $filename | indent_more -done - -# Scratch-blocks has separate vertical and horizontal playgrounds and block -# rendering. -git rm -f tests/playground.html core/block_render_svg.js | indent_more - -empty_lines -echo Done with cleanup. diff --git a/core/colours.js b/core/colours.js deleted file mode 100644 index 12fd515b0a..0000000000 --- a/core/colours.js +++ /dev/null @@ -1,173 +0,0 @@ -/** - * @license - * Visual Blocks Editor - * - * Copyright 2016 Massachusetts Institute of Technology - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - import * as Blockly from 'blockly/core'; - - const cssColours = { - // SVG colours: these must be specificed in #RRGGBB style - // To add an opacity, this must be specified as a separate property (for SVG fill-opacity) - "motion": { - "primary": "#4C97FF", - "secondary": "#4280D7", - "tertiary": "#3373CC", - "quaternary": "#3373CC" - }, - "looks": { - "primary": "#9966FF", - "secondary": "#855CD6", - "tertiary": "#774DCB", - "quaternary": "#774DCB" - }, - "sounds": { - "primary": "#CF63CF", - "secondary": "#C94FC9", - "tertiary": "#BD42BD", - "quaternary": "#BD42BD" - }, - "control": { - "primary": "#FFAB19", - "secondary": "#EC9C13", - "tertiary": "#CF8B17", - "quaternary": "#CF8B17" - }, - "event": { - "primary": "#FFBF00", - "secondary": "#E6AC00", - "tertiary": "#CC9900", - "quaternary": "#CC9900" - }, - "sensing": { - "primary": "#5CB1D6", - "secondary": "#47A8D1", - "tertiary": "#2E8EB8", - "quaternary": "#2E8EB8" - }, - "pen": { - "primary": "#0fBD8C", - "secondary": "#0DA57A", - "tertiary": "#0B8E69", - "quaternary": "#0B8E69" - }, - "operators": { - "primary": "#59C059", - "secondary": "#46B946", - "tertiary": "#389438", - "quaternary": "#389438" - }, - "data": { - "primary": "#FF8C1A", - "secondary": "#FF8000", - "tertiary": "#DB6E00", - "quaternary": "#DB6E00" - }, - // This is not a new category, but rather for differentiation - // between lists and scalar variables. - "data_lists": { - "primary": "#FF661A", - "secondary": "#FF5500", - "tertiary": "#E64D00", - "quaternary": "#E64D00" - }, - "more": { - "primary": "#FF6680", - "secondary": "#FF4D6A", - "tertiary": "#FF3355", - "quaternary": "#FF3355" - }, - "text": "#FFFFFF", - "workspace": "#F9F9F9", - "toolboxHover": "#4C97FF", - "toolboxSelected": "#e9eef2", - "toolboxText": "#575E75", - "toolbox": "#FFFFFF", - "flyout": "#F9F9F9", - "scrollbar": "#CECDCE", - "scrollbarHover": '#CECDCE', - "textField": "#FFFFFF", - "textFieldText": "#575E75", - "insertionMarker": "#000000", - "insertionMarkerOpacity": 0.2, - "dragShadowOpacity": 0.6, - "stackGlow": "#FFF200", - "stackGlowSize": 4, - "stackGlowOpacity": 1, - "replacementGlow": "#FFFFFF", - "replacementGlowSize": 2, - "replacementGlowOpacity": 1, - "colourPickerStroke": "#FFFFFF", - // CSS colours: support RGBA - "fieldShadow": "rgba(0,0,0,0.1)", - "dropDownShadow": "rgba(0, 0, 0, .3)", - "numPadBackground": "#547AB2", - "numPadBorder": "#435F91", - "numPadActiveBackground": "#435F91", - "numPadText": "white", // Do not use hex here, it cannot be inlined with data-uri SVG - "valueReportBackground": "#FFFFFF", - "valueReportBorder": "#AAAAAA", - "menuHover": "rgba(0, 0, 0, 0.2)", - }; - -const Colours = { - ...cssColours, - overrideColours: function(colours) { - // Colour overrides provided by the injection - if (colours) { - for (var colourProperty in colours) { - if (colours.hasOwnProperty(colourProperty) && - this.hasOwnProperty(colourProperty)) { - // If a property is in both colours option and Blockly.Colours, - // set the Blockly.Colours value to the override. - // Override Blockly category color object properties with those - // provided. - var colourPropertyValue = colours[colourProperty]; - if (goog.isObject(colourPropertyValue)) { - for (var colourSequence in colourPropertyValue) { - if (colourPropertyValue.hasOwnProperty(colourSequence) && - this[colourProperty].hasOwnProperty(colourSequence)) { - this[colourProperty][colourSequence] = - colourPropertyValue[colourSequence]; - } - } - } else { - this[colourProperty] = colourPropertyValue; - } - } - } - } - } -}; - -function varify(coloursObj, prefix = '--colour') { - return Object.keys(coloursObj).map(key => { - const colour = coloursObj[key]; - if (typeof colour === 'string') { - return `${prefix}-${key}: ${colour};`; - } else { - return varify(colour, `${prefix}-${key}`); - } - }).join('\n'); -} - -const cssVariables = `:root { - ${varify(cssColours)} -}`; - -Blockly.Css.register(cssVariables); - -export {Colours}; diff --git a/local_build.sh b/local_build.sh deleted file mode 100755 index fc02445db2..0000000000 --- a/local_build.sh +++ /dev/null @@ -1,70 +0,0 @@ -#!/bin/bash - -# Locally build and compress the core Blockly files into a single JavaScript -# file. -# -# Copyright 2018 Google Inc. -# https://developers.google.com/blockly/ -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# Usage: local_build.sh. -# -# This script generates only local_blockly_compressed_vertical.js. You may -# modify it as needed to build other files. -# -# The compressed file is a concatenation of all of Scratch-Blocks's core files, -# run through a local copy of Google's Closure Compiler with simple -# optimizations turned on. - -# Future work: -# - Trim down Google's Apache licenses, to match the output of build.py. -# - Generate other compressed files generated by build.py normally. -# - Add a good error message if multiple versions of the closure compiler were -# found. -# - Add a flag for generating horizontal (still default to vertical). - -# Find the Closure Compiler. -if [ -f "$(npm root)/google-closure-compiler/compiler.jar" ]; then - COMPILER="$(npm root)/google-closure-compiler/compiler.jar" -elif [ -f closure-compiler*.jar ]; then - COMPILER="closure-compiler*.jar" - # TODO: Check whether multiple files were found. -else - echo "ERROR: Closure Compiler not found." - echo "Download from this URL, and place jar file in current directory." - echo "https://dl.google.com/closure-compiler/compiler-latest.zip" - exit 1 -fi - -echo Using $COMPILER as the compiler. -rm local_blockly_compressed_vertical.js 2> /dev/null -echo Compiling Scratch-Blocks.. -java -jar $COMPILER \ - --js='core/**.js' \ - --js='!core/block_render_svg_horizontal.js' \ - --js='../closure-library/closure/goog/**.js' \ - --js='../closure-library/third_party/closure/goog/**.js' \ - --generate_exports \ - --warning_level='DEFAULT' \ - --compilation_level SIMPLE_OPTIMIZATIONS \ - --dependency_mode=STRICT \ - --entry_point=Blockly \ - --js_output_file local_blockly_compressed_vertical.js - -if [ -s local_blockly_compressed_vertical.js ]; then - echo Compilation OK. -else - echo Compilation FAIL. - exit 1 -fi diff --git a/pull_from_blockly.sh b/pull_from_blockly.sh deleted file mode 100755 index fe3dcb8674..0000000000 --- a/pull_from_blockly.sh +++ /dev/null @@ -1,151 +0,0 @@ -#!/bin/bash - -# Pull from Blockly into Scratch Blocks and do basic cleanup. -# Rachel Fenichel (fenichel@google.com) - -BOLD='\e[1m' -NOBOLD='\e[21m' - -# Formatting helper. -empty_lines() { printf '\n\n'; } -bold_echo() { - echo -e "${BOLD}$1${NOBOLD}" -} - -stop_on_fail() { - # Fail if any command fails. - set -e - # Even if you're piping the output. - set -o pipefail -} - -# Undo the effects of start_failing. -continue_on_fail() { - set +e - set +o pipefail -} - -# Prompt for y/n and put the result in $prompt_result -# The first argument specifies the text to use in the prompt. -# The second argument specifies which value to use if we're skipping prompts. -prompt() { - if [ $with_prompts ] - then - if [ $2 = true ] - then - paren_text="(Y/n)" - else - paren_text="(y/N)" - fi - # Prompt the user and retry if they try any funny business. - while true; do - read -p "$1 $paren_text > " yn - case $yn in - [Yy]* ) prompt_result=true; break;; - [Nn]* ) prompt_result=false; break;; - * ) echo "Please answer yes or no.";; - esac - done - else - # Running without prompts. Use the default value. - prompt_result=$2; - fi -} - - -# Ask the user for confirmation, then pull from Blockly's develop branch. -# The default is to do the pull. -pull_from_develop_fn() { - empty_lines - prompt "Do you want to pull from develop?" true - if [ $prompt_result = false ] - then - bold_echo "You don't want to pull from develop. Why are you running this script?" - exit - fi - - bold_echo "Pulling from Blockly's develop branch" - sleep .5 - # This pull will likely fail with merge conflicts, but that's okay. - # However, this means that we won't fail on errors other than merge conflicts. - continue_on_fail - git pull https://github.com/google/blockly.git develop - stop_on_fail -} - -# Ask the user for confirmation, then run cleanup. -# The default is to run cleanup. -run_cleanup_fn() { - empty_lines - prompt "Ready to run cleanup.sh. Continue?" true - if [ $prompt_result = false ] - then - bold_echo "Skipping cleanup.sh" - prompt_for_merge_abort - empty_lines - bold_echo "Done" - exit - fi - - bold_echo "Running cleanup.sh" - sleep .5 - # Cleanup.sh resolves common conflicts. - ./cleanup.sh -} - -# Ask the user for confirmation, then possibly abort the merge. -# The default is to *not* abort the merge. -# Used to clean up the repo instead of leaving it in a bad state. -prompt_for_merge_abort() { - empty_lines - prompt "Do you want to abort this merge?" false - if [ $prompt_result = false ] - then - bold_echo "Continuing with merge..." - else - bold_echo "Running git merge --abort" - git merge --abort - display_status_fn - bold_echo "Done" - exit - fi -} - -# Ask the user for confirmation, then show the current repo status. -# The default to to show status. -display_status_fn() { - empty_lines - prompt "Do you want to display the current status?" true - if [ $prompt_result = true ] - then - # Tell the user the current state. - bold_echo "Current status" - sleep .5 - git status - else - bold_echo "Skipping status display." - fi -} - -# Give the user one more chance to abort the merge, then tell them what their -# next steps should be. -finish_fn() { - prompt_for_merge_abort - bold_echo "Done. You may need to manually resolve conflicts." - # Helpful tips about what to do next. - empty_lines - sleep .5 - echo "Fix conflicts and run 'git commit'." - echo "Use 'git add ' to mark resolution." - echo "Use 'git merge --abort' to abort this merge." -} - -# Check whether we're running with prompts. If unset, we'll skip all prompts. -with_prompts=$1 - -# Here we go! -stop_on_fail -pull_from_develop_fn -run_cleanup_fn -display_status_fn -finish_fn diff --git a/shim/blockly_compressed_horizontal-blocks_compressed.js b/shim/blockly_compressed_horizontal-blocks_compressed.js deleted file mode 100644 index 32675cc413..0000000000 --- a/shim/blockly_compressed_horizontal-blocks_compressed.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = require('imports-loader?Blockly=./shim/blockly_compressed_horizontal.Blockly!exports-loader?Blockly!../blocks_compressed'); diff --git a/shim/blockly_compressed_horizontal.Blockly.js b/shim/blockly_compressed_horizontal.Blockly.js deleted file mode 100644 index f481649d88..0000000000 --- a/shim/blockly_compressed_horizontal.Blockly.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = require('./blockly_compressed_horizontal').Blockly; diff --git a/shim/blockly_compressed_horizontal.goog.js b/shim/blockly_compressed_horizontal.goog.js deleted file mode 100644 index 1bc78ca5ae..0000000000 --- a/shim/blockly_compressed_horizontal.goog.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = require('./blockly_compressed_horizontal').goog; diff --git a/shim/blockly_compressed_horizontal.js b/shim/blockly_compressed_horizontal.js deleted file mode 100644 index ed83a67472..0000000000 --- a/shim/blockly_compressed_horizontal.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = require('imports-loader?this=>window!exports-loader?Blockly&goog!../blockly_compressed_horizontal'); diff --git a/shim/blockly_compressed_vertical-blocks_compressed.js b/shim/blockly_compressed_vertical-blocks_compressed.js deleted file mode 100644 index 8eec1f68a2..0000000000 --- a/shim/blockly_compressed_vertical-blocks_compressed.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = require('imports-loader?Blockly=./shim/blockly_compressed_vertical.Blockly!exports-loader?Blockly!../blocks_compressed'); diff --git a/shim/blockly_compressed_vertical.Blockly.js b/shim/blockly_compressed_vertical.Blockly.js deleted file mode 100644 index 041f4e1313..0000000000 --- a/shim/blockly_compressed_vertical.Blockly.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = require('./blockly_compressed_vertical').Blockly; diff --git a/shim/blockly_compressed_vertical.goog.js b/shim/blockly_compressed_vertical.goog.js deleted file mode 100644 index 22ccbfdd73..0000000000 --- a/shim/blockly_compressed_vertical.goog.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = require('./blockly_compressed_vertical').goog; diff --git a/shim/blockly_compressed_vertical.js b/shim/blockly_compressed_vertical.js deleted file mode 100644 index dce46a9de5..0000000000 --- a/shim/blockly_compressed_vertical.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = require('imports-loader?this=>window!exports-loader?Blockly&goog!../blockly_compressed_vertical'); diff --git a/shim/blocks_compressed_horizontal-blockly_compressed_horizontal-messages.js b/shim/blocks_compressed_horizontal-blockly_compressed_horizontal-messages.js deleted file mode 100644 index 609080e29f..0000000000 --- a/shim/blocks_compressed_horizontal-blockly_compressed_horizontal-messages.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = require('imports-loader?Blockly=../shim/blocks_compressed_horizontal,goog=../shim/blockly_compressed_horizontal.goog!exports-loader?Blockly!../msg/messages'); diff --git a/shim/blocks_compressed_horizontal.js b/shim/blocks_compressed_horizontal.js deleted file mode 100644 index 0c4272ae08..0000000000 --- a/shim/blocks_compressed_horizontal.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = require('imports-loader?Blockly=./shim/blockly_compressed_horizontal-blocks_compressed!exports-loader?Blockly!../blocks_compressed_horizontal'); diff --git a/shim/blocks_compressed_vertical-blockly_compressed_vertical-messages.js b/shim/blocks_compressed_vertical-blockly_compressed_vertical-messages.js deleted file mode 100644 index 65449c83b4..0000000000 --- a/shim/blocks_compressed_vertical-blockly_compressed_vertical-messages.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = require('imports-loader?Blockly=../shim/blocks_compressed_vertical,goog=../shim/blockly_compressed_vertical.goog!exports-loader?Blockly!../msg/messages'); diff --git a/shim/blocks_compressed_vertical.js b/shim/blocks_compressed_vertical.js deleted file mode 100644 index 3368c09d03..0000000000 --- a/shim/blocks_compressed_vertical.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = require('imports-loader?goog=./shim/blockly_compressed_vertical.goog,Blockly=./shim/blockly_compressed_vertical-blocks_compressed!exports-loader?Blockly!../blocks_compressed_vertical'); diff --git a/shim/gh-pages.js b/shim/gh-pages.js deleted file mode 100644 index 36db4933d9..0000000000 --- a/shim/gh-pages.js +++ /dev/null @@ -1 +0,0 @@ -// intentionally left empty diff --git a/shim/horizontal.js b/shim/horizontal.js deleted file mode 100644 index 9416cada6d..0000000000 --- a/shim/horizontal.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = require('imports-loader?Blockly=../shim/blocks_compressed_horizontal-blockly_compressed_horizontal-messages,goog=../shim/blockly_compressed_horizontal.goog!exports-loader?Blockly!../msg/scratch_msgs'); diff --git a/shim/index.js b/shim/index.js deleted file mode 100644 index cd27975deb..0000000000 --- a/shim/index.js +++ /dev/null @@ -1,17 +0,0 @@ -/** - * Webpack shim module - * - * Uses webpack imports-loader and exports-loader to provide the horizontal and - * vertical flavors of Blockly. All of the other files in this directory shim - * Blockly and goog between blockly_compressed_* and blocks_compressed*. - * - * Horizontal and Vertical export Blockly out of - * blockly_compressed_[horizontal, vertical] + - * blocks_compressed + - * blocks_compressed_[horizontal, vertical] + - * msg/messages -**/ -module.exports = { - Horizontal: require('./horizontal'), - Vertical: require('./vertical') -}; diff --git a/shim/vertical.js b/shim/vertical.js deleted file mode 100644 index 7990fe5b65..0000000000 --- a/shim/vertical.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = require('imports-loader?Blockly=../shim/blocks_compressed_vertical-blockly_compressed_vertical-messages,goog=../shim/blockly_compressed_vertical.goog!exports-loader?Blockly!../msg/scratch_msgs'); diff --git a/src/block_reporting.js b/src/block_reporting.js index 3cd2854cfd..4a4e0253d9 100644 --- a/src/block_reporting.js +++ b/src/block_reporting.js @@ -1,11 +1,12 @@ -import * as Blockly from 'blockly/core'; -import {Colours} from '../core/colours.js'; +import * as Blockly from "blockly/core"; +import { Colours } from "./colours.js"; export function reportValue(id, value) { - const block = Blockly.getMainWorkspace().getBlockById(id) || - Blockly.getMainWorkspace().getFlyout().getWorkspace().getBlockById(id); + const block = + Blockly.getMainWorkspace().getBlockById(id) || + Blockly.getMainWorkspace().getFlyout().getWorkspace().getBlockById(id); if (!block) { - throw 'Tried to report value on block that does not exist.'; + throw "Tried to report value on block that does not exist."; } let field; @@ -18,13 +19,13 @@ export function reportValue(id, value) { if (!field) return; const contentDiv = Blockly.DropDownDiv.getContentDiv(); - const valueReportBox = document.createElement('div'); - valueReportBox.setAttribute('class', 'valueReportBox'); + const valueReportBox = document.createElement("div"); + valueReportBox.setAttribute("class", "valueReportBox"); valueReportBox.innerText = value; contentDiv.appendChild(valueReportBox); Blockly.DropDownDiv.setColour( - Colours.valueReportBackground, - Colours.valueReportBorder + Colours.valueReportBackground, + Colours.valueReportBorder ); Blockly.DropDownDiv.showPositionedByBlock(field, block); } diff --git a/blocks_common/colour.js b/src/blocks/colour.js similarity index 70% rename from blocks_common/colour.js rename to src/blocks/colour.js index c947329ce3..8f1e9e2fb5 100644 --- a/blocks_common/colour.js +++ b/src/blocks/colour.js @@ -22,8 +22,8 @@ * @fileoverview Colour blocks for Blockly. * @author fraser@google.com (Neil Fraser) */ -import * as Blockly from 'blockly'; -import * as Constants from '../src/constants.js'; +import * as Blockly from "blockly/core"; +import * as Constants from "../constants.js"; /** * Pick a random colour. @@ -31,26 +31,26 @@ import * as Constants from '../src/constants.js'; */ function randomColour() { var num = Math.floor(Math.random() * Math.pow(2, 24)); - return '#' + ('00000' + num.toString(16)).substr(-6); + return "#" + ("00000" + num.toString(16)).substr(-6); } -Blockly.Blocks['colour_picker'] = { +Blockly.Blocks["colour_picker"] = { /** * Block for colour picker. * @this Blockly.Block */ - init: function() { + init: function () { this.jsonInit({ - "message0": "%1", - "args0": [ + message0: "%1", + args0: [ { - "type": "field_colour_slider", - "name": "COLOUR", - "colour": randomColour() - } + type: "field_colour_slider", + name: "COLOUR", + colour: randomColour(), + }, ], - "outputShape": Constants.OUTPUT_SHAPE_ROUND, - "output": "Colour" + outputShape: Constants.OUTPUT_SHAPE_ROUND, + output: "Colour", }); - } + }, }; diff --git a/src/blocks/control.js b/src/blocks/control.js new file mode 100644 index 0000000000..bad0d43203 --- /dev/null +++ b/src/blocks/control.js @@ -0,0 +1,513 @@ +/** + * @license + * Visual Blocks Editor + * + * Copyright 2016 Massachusetts Institute of Technology + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import * as Blockly from "blockly/core"; +import { Categories } from "../categories.js"; +import { Colours } from "../colours.js"; + +Blockly.Blocks["control_forever"] = { + /** + * Block for repeat n times (external number). + * https://blockly-demo.appspot.com/static/demos/blockfactory/index.html#5eke39 + * @this Blockly.Block + */ + init: function () { + const ws = this.workspace.options.parentWorkspace || this.workspace; + this.jsonInit({ + id: "control_forever", + message0: Blockly.Msg.CONTROL_FOREVER, + message1: "%1", // Statement + message2: "%1", // Icon + lastDummyAlign2: "RIGHT", + args1: [ + { + type: "input_statement", + name: "SUBSTACK", + }, + ], + args2: [ + { + type: "field_image", + src: ws.options.pathToMedia + "repeat.svg", + width: 24, + height: 24, + alt: "*", + flip_rtl: true, + }, + ], + category: Categories.control, + extensions: ["colours_control", "shape_end"], + }); + }, +}; + +Blockly.Blocks["control_repeat"] = { + /** + * Block for repeat n times (external number). + * https://blockly-demo.appspot.com/static/demos/blockfactory/index.html#so57n9 + * @this Blockly.Block + */ + init: function () { + const ws = this.workspace.options.parentWorkspace || this.workspace; + this.jsonInit({ + id: "control_repeat", + message0: Blockly.Msg.CONTROL_REPEAT, + message1: "%1", // Statement + message2: "%1", // Icon + lastDummyAlign2: "RIGHT", + args0: [ + { + type: "input_value", + name: "TIMES", + }, + ], + args1: [ + { + type: "input_statement", + name: "SUBSTACK", + }, + ], + args2: [ + { + type: "field_image", + src: ws.options.pathToMedia + "repeat.svg", + width: 24, + height: 24, + alt: "*", + flip_rtl: true, + }, + ], + category: Categories.control, + extensions: ["colours_control", "shape_statement"], + }); + }, +}; + +Blockly.Blocks["control_if"] = { + /** + * Block for if-then. + * @this Blockly.Block + */ + init: function () { + this.jsonInit({ + type: "control_if", + message0: Blockly.Msg.CONTROL_IF, + message1: "%1", // Statement + args0: [ + { + type: "input_value", + name: "CONDITION", + check: "Boolean", + }, + ], + args1: [ + { + type: "input_statement", + name: "SUBSTACK", + }, + ], + category: Categories.control, + extensions: ["colours_control", "shape_statement"], + }); + }, +}; + +Blockly.Blocks["control_if_else"] = { + /** + * Block for if-else. + * @this Blockly.Block + */ + init: function () { + this.jsonInit({ + type: "control_if_else", + message0: Blockly.Msg.CONTROL_IF, + message1: "%1", + message2: Blockly.Msg.CONTROL_ELSE, + message3: "%1", + args0: [ + { + type: "input_value", + name: "CONDITION", + check: "Boolean", + }, + ], + args1: [ + { + type: "input_statement", + name: "SUBSTACK", + }, + ], + args3: [ + { + type: "input_statement", + name: "SUBSTACK2", + }, + ], + category: Categories.control, + extensions: ["colours_control", "shape_statement"], + }); + }, +}; + +Blockly.Blocks["control_stop"] = { + /** + * Block for stop all scripts. + * @this Blockly.Block + */ + init: function () { + var ALL_SCRIPTS = "all"; + var THIS_SCRIPT = "this script"; + var OTHER_SCRIPTS = "other scripts in sprite"; + var stopDropdown = new Blockly.FieldDropdown( + function () { + if ( + this.sourceBlock_ && + this.sourceBlock_.nextConnection && + this.sourceBlock_.nextConnection.isConnected() + ) { + return [[Blockly.Msg.CONTROL_STOP_OTHER, OTHER_SCRIPTS]]; + } + return [ + [Blockly.Msg.CONTROL_STOP_ALL, ALL_SCRIPTS], + [Blockly.Msg.CONTROL_STOP_THIS, THIS_SCRIPT], + [Blockly.Msg.CONTROL_STOP_OTHER, OTHER_SCRIPTS], + ]; + }, + function (option) { + this.getSourceBlock().setNextStatement(option === OTHER_SCRIPTS); + return option; + } + ); + this.appendDummyInput() + .appendField(Blockly.Msg.CONTROL_STOP) + .appendField(stopDropdown, "STOP_OPTION"); + this.setColour( + Colours.control.primary, + Colours.control.secondary, + Colours.control.tertiary, + Colours.control.quaternary + ); + this.setPreviousStatement(true); + }, +}; + +Blockly.Blocks["control_wait"] = { + /** + * Block to wait (pause) stack. + * @this Blockly.Block + */ + init: function () { + this.jsonInit({ + id: "control_wait", + message0: Blockly.Msg.CONTROL_WAIT, + args0: [ + { + type: "input_value", + name: "DURATION", + }, + ], + category: Categories.control, + extensions: ["colours_control", "shape_statement"], + }); + }, +}; + +Blockly.Blocks["control_wait_until"] = { + /** + * Block to wait until a condition becomes true. + * @this Blockly.Block + */ + init: function () { + this.jsonInit({ + message0: Blockly.Msg.CONTROL_WAITUNTIL, + args0: [ + { + type: "input_value", + name: "CONDITION", + check: "Boolean", + }, + ], + category: Categories.control, + extensions: ["colours_control", "shape_statement"], + }); + }, +}; + +Blockly.Blocks["control_repeat_until"] = { + /** + * Block to repeat until a condition becomes true. + * @this Blockly.Block + */ + init: function () { + const ws = this.workspace.options.parentWorkspace || this.workspace; + this.jsonInit({ + message0: Blockly.Msg.CONTROL_REPEATUNTIL, + message1: "%1", + message2: "%1", + lastDummyAlign2: "RIGHT", + args0: [ + { + type: "input_value", + name: "CONDITION", + check: "Boolean", + }, + ], + args1: [ + { + type: "input_statement", + name: "SUBSTACK", + }, + ], + args2: [ + { + type: "field_image", + src: ws.options.pathToMedia + "repeat.svg", + width: 24, + height: 24, + alt: "*", + flip_rtl: true, + }, + ], + category: Categories.control, + extensions: ["colours_control", "shape_statement"], + }); + }, +}; + +Blockly.Blocks["control_while"] = { + /** + * Block to repeat until a condition becomes false. + * (This is an obsolete "hacked" block, for compatibility with 2.0.) + */ + init: function () { + const ws = this.workspace.options.parentWorkspace || this.workspace; + this.jsonInit({ + message0: Blockly.Msg.CONTROL_WHILE, + message1: "%1", + message2: "%1", + lastDummyAlign2: "RIGHT", + args0: [ + { + type: "input_value", + name: "CONDITION", + check: "Boolean", + }, + ], + args1: [ + { + type: "input_statement", + name: "SUBSTACK", + }, + ], + args2: [ + { + type: "field_image", + src: ws.options.pathToMedia + "repeat.svg", + width: 24, + height: 24, + alt: "*", + flip_rtl: true, + }, + ], + category: Categories.control, + extensions: ["colours_control", "shape_statement"], + }); + }, +}; + +Blockly.Blocks["control_for_each"] = { + /** + * Block for for-each. This is an obsolete block that is implemented for + * compatibility with Scratch 2.0 projects. + * @this Blockly.Block + */ + init: function () { + this.jsonInit({ + type: "control_for_each", + message0: Blockly.Msg.CONTROL_FOREACH, + message1: "%1", + args0: [ + { + type: "field_variable", + name: "VARIABLE", + }, + { + type: "input_value", + name: "VALUE", + }, + ], + args1: [ + { + type: "input_statement", + name: "SUBSTACK", + }, + ], + category: Categories.control, + extensions: ["colours_control", "shape_statement"], + }); + }, +}; + +Blockly.Blocks["control_start_as_clone"] = { + /** + * Block for "when I start as a clone" hat. + * @this Blockly.Block + */ + init: function () { + this.jsonInit({ + id: "control_start_as_clone", + message0: Blockly.Msg.CONTROL_STARTASCLONE, + args0: [], + category: Categories.control, + extensions: ["colours_control", "shape_hat"], + }); + }, +}; + +Blockly.Blocks["control_create_clone_of_menu"] = { + /** + * Create-clone drop-down menu. + * @this Blockly.Block + */ + init: function () { + this.jsonInit({ + message0: "%1", + args0: [ + { + type: "field_dropdown", + name: "CLONE_OPTION", + options: [[Blockly.Msg.CONTROL_CREATECLONEOF_MYSELF, "_myself_"]], + }, + ], + extensions: ["colours_control", "output_string"], + }); + }, +}; + +Blockly.Blocks["control_create_clone_of"] = { + /** + * Block for "create clone of..." + * @this Blockly.Block + */ + init: function () { + this.jsonInit({ + id: "control_start_as_clone", + message0: Blockly.Msg.CONTROL_CREATECLONEOF, + args0: [ + { + type: "input_value", + name: "CLONE_OPTION", + }, + ], + category: Categories.control, + extensions: ["colours_control", "shape_statement"], + }); + }, +}; + +Blockly.Blocks["control_delete_this_clone"] = { + /** + * Block for "delete this clone." + * @this Blockly.Block + */ + init: function () { + this.jsonInit({ + message0: Blockly.Msg.CONTROL_DELETETHISCLONE, + args0: [], + category: Categories.control, + extensions: ["colours_control", "shape_end"], + }); + }, +}; + +Blockly.Blocks["control_get_counter"] = { + /** + * Block to get the counter value. This is an obsolete block that is + * implemented for compatibility with Scratch 2.0 projects. + * @this Blockly.Block + */ + init: function () { + this.jsonInit({ + message0: Blockly.Msg.CONTROL_COUNTER, + category: Categories.control, + extensions: ["colours_control", "output_number"], + }); + }, +}; + +Blockly.Blocks["control_incr_counter"] = { + /** + * Block to add one to the counter value. This is an obsolete block that is + * implemented for compatibility with Scratch 2.0 projects. + * @this Blockly.Block + */ + init: function () { + this.jsonInit({ + message0: Blockly.Msg.CONTROL_INCRCOUNTER, + category: Categories.control, + extensions: ["colours_control", "shape_statement"], + }); + }, +}; + +Blockly.Blocks["control_clear_counter"] = { + /** + * Block to clear the counter value. This is an obsolete block that is + * implemented for compatibility with Scratch 2.0 projects. + * @this Blockly.Block + */ + init: function () { + this.jsonInit({ + message0: Blockly.Msg.CONTROL_CLEARCOUNTER, + category: Categories.control, + extensions: ["colours_control", "shape_statement"], + }); + }, +}; + +Blockly.Blocks["control_all_at_once"] = { + /** + * Block to run the contained script. This is an obsolete block that is + * implemented for compatibility with Scratch 2.0 projects. Note that + * this was originally designed to run all of the contained blocks + * (sequentially, like normal) within a single frame, but this feature + * was removed in place of custom blocks marked "run without screen + * refresh". The "all at once" block was changed to run the contained + * blocks ordinarily, functioning the same way as an "if" block with a + * reporter that is always true (e.g. "if 1 = 1"). Also note that the + * Scratch 2.0 spec for this block is "warpSpeed", but the label shows + * "all at once". + * @this Blockly.Block + */ + init: function () { + this.jsonInit({ + message0: Blockly.Msg.CONTROL_ALLATONCE, + message1: "%1", // Statement + args1: [ + { + type: "input_statement", + name: "SUBSTACK", + }, + ], + category: Categories.control, + extensions: ["colours_control", "shape_statement"], + }); + }, +}; diff --git a/blocks_vertical/data.js b/src/blocks/data.js similarity index 99% rename from blocks_vertical/data.js rename to src/blocks/data.js index 55bedc702d..45869707b2 100644 --- a/blocks_vertical/data.js +++ b/src/blocks/data.js @@ -19,9 +19,9 @@ */ import * as Blockly from "blockly/core"; -import { Categories } from "../src/categories.js"; -import * as Constants from "../src/constants.js"; -import * as scratchBlocksUtils from "../core/scratch_blocks_utils.js"; +import { Categories } from "../categories.js"; +import * as Constants from "../constants.js"; +import * as scratchBlocksUtils from "../scratch_blocks_utils.js"; Blockly.Blocks["data_variable"] = { /** diff --git a/src/blocks/event.js b/src/blocks/event.js new file mode 100644 index 0000000000..20ac9a0768 --- /dev/null +++ b/src/blocks/event.js @@ -0,0 +1,320 @@ +/** + * @license + * Visual Blocks Editor + * + * Copyright 2016 Massachusetts Institute of Technology + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import * as Blockly from "blockly/core"; +import { Categories } from "../categories.js"; +import * as Constants from "../constants.js"; + +Blockly.Blocks["event_whentouchingobject"] = { + /** + * Block for when a sprite is touching an object. + * @this Blockly.Block + */ + init: function () { + this.jsonInit({ + message0: Blockly.Msg.EVENT_WHENTOUCHINGOBJECT, + args0: [ + { + type: "input_value", + name: "TOUCHINGOBJECTMENU", + }, + ], + category: Categories.event, + extensions: ["colours_event", "shape_hat"], + }); + }, +}; + +Blockly.Blocks["event_touchingobjectmenu"] = { + /** + * "Touching [Object]" Block Menu. + * @this Blockly.Block + */ + init: function () { + this.jsonInit({ + message0: "%1", + args0: [ + { + type: "field_dropdown", + name: "TOUCHINGOBJECTMENU", + options: [ + [Blockly.Msg.SENSING_TOUCHINGOBJECT_POINTER, "_mouse_"], + [Blockly.Msg.SENSING_TOUCHINGOBJECT_EDGE, "_edge_"], + ], + }, + ], + extensions: ["colours_event", "output_string"], + }); + }, +}; + +Blockly.Blocks["event_whenflagclicked"] = { + /** + * Block for when flag clicked. + * @this Blockly.Block + */ + init: function () { + const ws = this.workspace.options.parentWorkspace || this.workspace; + this.jsonInit({ + id: "event_whenflagclicked", + message0: Blockly.Msg.EVENT_WHENFLAGCLICKED, + args0: [ + { + type: "field_image", + src: ws.options.pathToMedia + "green-flag.svg", + width: 24, + height: 24, + alt: "flag", + }, + ], + category: Categories.event, + extensions: ["colours_event", "shape_hat"], + }); + }, +}; + +Blockly.Blocks["event_whenthisspriteclicked"] = { + /** + * Block for when this sprite clicked. + * @this Blockly.Block + */ + init: function () { + this.jsonInit({ + message0: Blockly.Msg.EVENT_WHENTHISSPRITECLICKED, + category: Categories.event, + extensions: ["colours_event", "shape_hat"], + }); + }, +}; + +Blockly.Blocks["event_whenstageclicked"] = { + /** + * Block for when the stage is clicked. + * @this Blockly.Block + */ + init: function () { + this.jsonInit({ + message0: Blockly.Msg.EVENT_WHENSTAGECLICKED, + category: Categories.event, + extensions: ["colours_event", "shape_hat"], + }); + }, +}; + +Blockly.Blocks["event_whenbroadcastreceived"] = { + /** + * Block for when broadcast received. + * @this Blockly.Block + */ + init: function () { + this.jsonInit({ + id: "event_whenbroadcastreceived", + message0: Blockly.Msg.EVENT_WHENBROADCASTRECEIVED, + args0: [ + { + type: "field_variable", + name: "BROADCAST_OPTION", + variableTypes: [Constants.BROADCAST_MESSAGE_VARIABLE_TYPE], + defaultType: Constants.BROADCAST_MESSAGE_VARIABLE_TYPE, + variable: Blockly.Msg.DEFAULT_BROADCAST_MESSAGE_NAME, + }, + ], + category: Categories.event, + extensions: ["colours_event", "shape_hat"], + }); + }, +}; + +Blockly.Blocks["event_whenbackdropswitchesto"] = { + /** + * Block for when the current backdrop switched to a selected backdrop. + * @this Blockly.Block + */ + init: function () { + this.jsonInit({ + message0: Blockly.Msg.EVENT_WHENBACKDROPSWITCHESTO, + args0: [ + { + type: "field_dropdown", + name: "BACKDROP", + options: [["backdrop1", "BACKDROP1"]], + }, + ], + category: Categories.event, + extensions: ["colours_event", "shape_hat"], + }); + }, +}; + +Blockly.Blocks["event_whengreaterthan"] = { + /** + * Block for when loudness/timer/video motion is greater than the value. + * @this Blockly.Block + */ + init: function () { + this.jsonInit({ + message0: Blockly.Msg.EVENT_WHENGREATERTHAN, + args0: [ + { + type: "field_dropdown", + name: "WHENGREATERTHANMENU", + options: [ + [Blockly.Msg.EVENT_WHENGREATERTHAN_LOUDNESS, "LOUDNESS"], + [Blockly.Msg.EVENT_WHENGREATERTHAN_TIMER, "TIMER"], + ], + }, + { + type: "input_value", + name: "VALUE", + }, + ], + category: Categories.event, + extensions: ["colours_event", "shape_hat"], + }); + }, +}; + +Blockly.Blocks["event_broadcast_menu"] = { + /** + * Broadcast drop-down menu. + * @this Blockly.Block + */ + init: function () { + this.jsonInit({ + message0: "%1", + args0: [ + { + type: "field_variable", + name: "BROADCAST_OPTION", + variableTypes: [Constants.BROADCAST_MESSAGE_VARIABLE_TYPE], + defaultType: Constants.BROADCAST_MESSAGE_VARIABLE_TYPE, + variable: Blockly.Msg.DEFAULT_BROADCAST_MESSAGE_NAME, + }, + ], + extensions: ["colours_event", "output_string"], + }); + }, +}; + +Blockly.Blocks["event_broadcast"] = { + /** + * Block to send a broadcast. + * @this Blockly.Block + */ + init: function () { + this.jsonInit({ + id: "event_broadcast", + message0: Blockly.Msg.EVENT_BROADCAST, + args0: [ + { + type: "input_value", + name: "BROADCAST_INPUT", + }, + ], + category: Categories.event, + extensions: ["colours_event", "shape_statement"], + }); + }, +}; + +Blockly.Blocks["event_broadcastandwait"] = { + /** + * Block to send a broadcast. + * @this Blockly.Block + */ + init: function () { + this.jsonInit({ + message0: Blockly.Msg.EVENT_BROADCASTANDWAIT, + args0: [ + { + type: "input_value", + name: "BROADCAST_INPUT", + }, + ], + category: Categories.event, + extensions: ["colours_event", "shape_statement"], + }); + }, +}; + +Blockly.Blocks["event_whenkeypressed"] = { + /** + * Block to send a broadcast. + * @this Blockly.Block + */ + init: function () { + this.jsonInit({ + id: "event_whenkeypressed", + message0: Blockly.Msg.EVENT_WHENKEYPRESSED, + args0: [ + { + type: "field_dropdown", + name: "KEY_OPTION", + options: [ + [Blockly.Msg.EVENT_WHENKEYPRESSED_SPACE, "space"], + [Blockly.Msg.EVENT_WHENKEYPRESSED_UP, "up arrow"], + [Blockly.Msg.EVENT_WHENKEYPRESSED_DOWN, "down arrow"], + [Blockly.Msg.EVENT_WHENKEYPRESSED_RIGHT, "right arrow"], + [Blockly.Msg.EVENT_WHENKEYPRESSED_LEFT, "left arrow"], + [Blockly.Msg.EVENT_WHENKEYPRESSED_ANY, "any"], + ["a", "a"], + ["b", "b"], + ["c", "c"], + ["d", "d"], + ["e", "e"], + ["f", "f"], + ["g", "g"], + ["h", "h"], + ["i", "i"], + ["j", "j"], + ["k", "k"], + ["l", "l"], + ["m", "m"], + ["n", "n"], + ["o", "o"], + ["p", "p"], + ["q", "q"], + ["r", "r"], + ["s", "s"], + ["t", "t"], + ["u", "u"], + ["v", "v"], + ["w", "w"], + ["x", "x"], + ["y", "y"], + ["z", "z"], + ["0", "0"], + ["1", "1"], + ["2", "2"], + ["3", "3"], + ["4", "4"], + ["5", "5"], + ["6", "6"], + ["7", "7"], + ["8", "8"], + ["9", "9"], + ], + }, + ], + category: Categories.event, + extensions: ["colours_event", "shape_hat"], + }); + }, +}; diff --git a/src/blocks/looks.js b/src/blocks/looks.js new file mode 100644 index 0000000000..72a7443490 --- /dev/null +++ b/src/blocks/looks.js @@ -0,0 +1,574 @@ +/** + * @license + * Visual Blocks Editor + * + * Copyright 2016 Massachusetts Institute of Technology + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import * as Blockly from "blockly/core"; +import { Categories } from "../categories.js"; + +Blockly.Blocks["looks_sayforsecs"] = { + /** + * Block to say for some time. + * @this Blockly.Block + */ + init: function () { + this.jsonInit({ + message0: Blockly.Msg.LOOKS_SAYFORSECS, + args0: [ + { + type: "input_value", + name: "MESSAGE", + }, + { + type: "input_value", + name: "SECS", + }, + ], + category: Categories.looks, + extensions: ["colours_looks", "shape_statement"], + }); + }, +}; + +Blockly.Blocks["looks_say"] = { + /** + * Block to say. + * @this Blockly.Block + */ + init: function () { + this.jsonInit({ + message0: Blockly.Msg.LOOKS_SAY, + args0: [ + { + type: "input_value", + name: "MESSAGE", + }, + ], + category: Categories.looks, + extensions: ["colours_looks", "shape_statement"], + }); + }, +}; + +Blockly.Blocks["looks_thinkforsecs"] = { + /** + * Block to think for some time. + * @this Blockly.Block + */ + init: function () { + this.jsonInit({ + message0: Blockly.Msg.LOOKS_THINKFORSECS, + args0: [ + { + type: "input_value", + name: "MESSAGE", + }, + { + type: "input_value", + name: "SECS", + }, + ], + category: Categories.looks, + extensions: ["colours_looks", "shape_statement"], + }); + }, +}; + +Blockly.Blocks["looks_think"] = { + /** + * Block to think. + * @this Blockly.Block + */ + init: function () { + this.jsonInit({ + message0: Blockly.Msg.LOOKS_THINK, + args0: [ + { + type: "input_value", + name: "MESSAGE", + }, + ], + category: Categories.looks, + extensions: ["colours_looks", "shape_statement"], + }); + }, +}; + +Blockly.Blocks["looks_show"] = { + /** + * Show block. + * @this Blockly.Block + */ + init: function () { + this.jsonInit({ + message0: Blockly.Msg.LOOKS_SHOW, + category: Categories.looks, + extensions: ["colours_looks", "shape_statement"], + }); + }, +}; + +Blockly.Blocks["looks_hide"] = { + /** + * Hide block. + * @this Blockly.Block + */ + init: function () { + this.jsonInit({ + message0: Blockly.Msg.LOOKS_HIDE, + category: Categories.looks, + extensions: ["colours_looks", "shape_statement"], + }); + }, +}; + +Blockly.Blocks["looks_hideallsprites"] = { + /** + * Hide-all-sprites block. Does not actually do anything. This is an + * obsolete block that is implemented for compatibility with Scratch 2.0 + * projects. + * @this Blockly.Block + */ + init: function () { + this.jsonInit({ + message0: Blockly.Msg.LOOKS_HIDEALLSPRITES, + category: Categories.looks, + extensions: ["colours_looks", "shape_statement"], + }); + }, +}; + +Blockly.Blocks["looks_changeeffectby"] = { + /** + * Block to change graphic effect. + * @this Blockly.Block + */ + init: function () { + this.jsonInit({ + message0: Blockly.Msg.LOOKS_CHANGEEFFECTBY, + args0: [ + { + type: "field_dropdown", + name: "EFFECT", + options: [ + [Blockly.Msg.LOOKS_EFFECT_COLOR, "COLOR"], + [Blockly.Msg.LOOKS_EFFECT_FISHEYE, "FISHEYE"], + [Blockly.Msg.LOOKS_EFFECT_WHIRL, "WHIRL"], + [Blockly.Msg.LOOKS_EFFECT_PIXELATE, "PIXELATE"], + [Blockly.Msg.LOOKS_EFFECT_MOSAIC, "MOSAIC"], + [Blockly.Msg.LOOKS_EFFECT_BRIGHTNESS, "BRIGHTNESS"], + [Blockly.Msg.LOOKS_EFFECT_GHOST, "GHOST"], + ], + }, + { + type: "input_value", + name: "CHANGE", + }, + ], + category: Categories.looks, + extensions: ["colours_looks", "shape_statement"], + }); + }, +}; + +Blockly.Blocks["looks_seteffectto"] = { + /** + * Block to set graphic effect. + * @this Blockly.Block + */ + init: function () { + this.jsonInit({ + message0: Blockly.Msg.LOOKS_SETEFFECTTO, + args0: [ + { + type: "field_dropdown", + name: "EFFECT", + options: [ + [Blockly.Msg.LOOKS_EFFECT_COLOR, "COLOR"], + [Blockly.Msg.LOOKS_EFFECT_FISHEYE, "FISHEYE"], + [Blockly.Msg.LOOKS_EFFECT_WHIRL, "WHIRL"], + [Blockly.Msg.LOOKS_EFFECT_PIXELATE, "PIXELATE"], + [Blockly.Msg.LOOKS_EFFECT_MOSAIC, "MOSAIC"], + [Blockly.Msg.LOOKS_EFFECT_BRIGHTNESS, "BRIGHTNESS"], + [Blockly.Msg.LOOKS_EFFECT_GHOST, "GHOST"], + ], + }, + { + type: "input_value", + name: "VALUE", + }, + ], + category: Categories.looks, + extensions: ["colours_looks", "shape_statement"], + }); + }, +}; + +Blockly.Blocks["looks_cleargraphiceffects"] = { + /** + * Block to clear graphic effects. + * @this Blockly.Block + */ + init: function () { + this.jsonInit({ + message0: Blockly.Msg.LOOKS_CLEARGRAPHICEFFECTS, + category: Categories.looks, + extensions: ["colours_looks", "shape_statement"], + }); + }, +}; + +Blockly.Blocks["looks_changesizeby"] = { + /** + * Block to change size + * @this Blockly.Block + */ + init: function () { + this.jsonInit({ + message0: Blockly.Msg.LOOKS_CHANGESIZEBY, + args0: [ + { + type: "input_value", + name: "CHANGE", + }, + ], + category: Categories.looks, + extensions: ["colours_looks", "shape_statement"], + }); + }, +}; + +Blockly.Blocks["looks_setsizeto"] = { + /** + * Block to set size + * @this Blockly.Block + */ + init: function () { + this.jsonInit({ + message0: Blockly.Msg.LOOKS_SETSIZETO, + args0: [ + { + type: "input_value", + name: "SIZE", + }, + ], + category: Categories.looks, + extensions: ["colours_looks", "shape_statement"], + }); + }, +}; + +Blockly.Blocks["looks_size"] = { + /** + * Block to report size + * @this Blockly.Block + */ + init: function () { + this.jsonInit({ + message0: Blockly.Msg.LOOKS_SIZE, + category: Categories.looks, + extensions: ["colours_looks", "output_number"], + }); + this.checkboxInFlyout = true; + }, +}; + +Blockly.Blocks["looks_changestretchby"] = { + /** + * Block to change stretch. Does not actually do anything. This is an + * obsolete block that is implemented for compatibility with Scratch 1.4 + * projects as well as 2.0 projects that still have the block. + * The "stretch" blocks were introduced in very early versions of Scratch, + * but their functionality was removed shortly later. They still appeared + * correctly up until (and including) Scratch 1.4 - as "change stretch by" + * and "set stretch to" - but were removed altogether in Scratch 2.0, and + * displayed as red "undefined" blocks. Some Scratch projects still contain + * these blocks, however, and they don't open in 3.0 unless the blocks + * actually exist (though they still don't funcitonally do anything). + * @this Blockly.Block + */ + init: function () { + this.jsonInit({ + message0: Blockly.Msg.LOOKS_CHANGESTRETCHBY, + args0: [ + { + type: "input_value", + name: "CHANGE", + }, + ], + category: Categories.looks, + extensions: ["colours_looks", "shape_statement"], + }); + }, +}; + +Blockly.Blocks["looks_setstretchto"] = { + /** + * Block to set stretch. Does not actually do anything. This is an obsolete + * block that is implemented for compatibility with Scratch 1.4 projects + * (see looks_changestretchby). + * @this Blockly.Block + */ + init: function () { + this.jsonInit({ + message0: Blockly.Msg.LOOKS_SETSTRETCHTO, + args0: [ + { + type: "input_value", + name: "STRETCH", + }, + ], + category: Categories.looks, + extensions: ["colours_looks", "shape_statement"], + }); + }, +}; + +Blockly.Blocks["looks_costume"] = { + /** + * Costumes drop-down menu. + * @this Blockly.Block + */ + init: function () { + this.jsonInit({ + message0: "%1", + args0: [ + { + type: "field_dropdown", + name: "COSTUME", + options: [ + ["costume1", "COSTUME1"], + ["costume2", "COSTUME2"], + ], + }, + ], + extensions: ["colours_looks", "output_string"], + }); + }, +}; + +Blockly.Blocks["looks_switchcostumeto"] = { + /** + * Block to switch the sprite's costume to the selected one. + * @this Blockly.Block + */ + init: function () { + this.jsonInit({ + message0: Blockly.Msg.LOOKS_SWITCHCOSTUMETO, + args0: [ + { + type: "input_value", + name: "COSTUME", + }, + ], + category: Categories.looks, + extensions: ["colours_looks", "shape_statement"], + }); + }, +}; + +Blockly.Blocks["looks_nextcostume"] = { + /** + * Block to switch the sprite's costume to the next one. + * @this Blockly.Block + */ + init: function () { + this.jsonInit({ + message0: Blockly.Msg.LOOKS_NEXTCOSTUME, + category: Categories.looks, + extensions: ["colours_looks", "shape_statement"], + }); + }, +}; + +Blockly.Blocks["looks_switchbackdropto"] = { + /** + * Block to switch the backdrop to the selected one. + * @this Blockly.Block + */ + init: function () { + this.jsonInit({ + message0: Blockly.Msg.LOOKS_SWITCHBACKDROPTO, + args0: [ + { + type: "input_value", + name: "BACKDROP", + }, + ], + category: Categories.looks, + extensions: ["colours_looks", "shape_statement"], + }); + }, +}; + +Blockly.Blocks["looks_backdrops"] = { + /** + * Backdrop list + * @this Blockly.Block + */ + init: function () { + this.jsonInit({ + id: "looks_backdrops", + message0: "%1", + args0: [ + { + type: "field_dropdown", + name: "BACKDROP", + options: [["backdrop1", "BACKDROP1"]], + }, + ], + extensions: ["colours_looks", "output_string"], + }); + }, +}; + +Blockly.Blocks["looks_gotofrontback"] = { + /** + * "Go to front/back" Block. + * @this Blockly.Block + */ + init: function () { + this.jsonInit({ + message0: Blockly.Msg.LOOKS_GOTOFRONTBACK, + args0: [ + { + type: "field_dropdown", + name: "FRONT_BACK", + options: [ + [Blockly.Msg.LOOKS_GOTOFRONTBACK_FRONT, "front"], + [Blockly.Msg.LOOKS_GOTOFRONTBACK_BACK, "back"], + ], + }, + ], + category: Categories.looks, + extensions: ["colours_looks", "shape_statement"], + }); + }, +}; + +Blockly.Blocks["looks_goforwardbackwardlayers"] = { + /** + * "Go forward/backward [Number] Layers" Block. + * @this Blockly.Block + */ + init: function () { + this.jsonInit({ + message0: Blockly.Msg.LOOKS_GOFORWARDBACKWARDLAYERS, + args0: [ + { + type: "field_dropdown", + name: "FORWARD_BACKWARD", + options: [ + [Blockly.Msg.LOOKS_GOFORWARDBACKWARDLAYERS_FORWARD, "forward"], + [Blockly.Msg.LOOKS_GOFORWARDBACKWARDLAYERS_BACKWARD, "backward"], + ], + }, + { + type: "input_value", + name: "NUM", + }, + ], + category: Categories.looks, + extensions: ["colours_looks", "shape_statement"], + }); + }, +}; + +Blockly.Blocks["looks_backdropnumbername"] = { + /** + * Block to report backdrop's number or name + * @this Blockly.Block + */ + init: function () { + this.jsonInit({ + message0: Blockly.Msg.LOOKS_BACKDROPNUMBERNAME, + args0: [ + { + type: "field_dropdown", + name: "NUMBER_NAME", + options: [ + [Blockly.Msg.LOOKS_NUMBERNAME_NUMBER, "number"], + [Blockly.Msg.LOOKS_NUMBERNAME_NAME, "name"], + ], + }, + ], + category: Categories.looks, + extensions: ["colours_looks", "output_number"], + }); + this.checkboxInFlyout = true; + }, +}; + +Blockly.Blocks["looks_costumenumbername"] = { + /** + * Block to report costume's number or name + * @this Blockly.Block + */ + init: function () { + this.jsonInit({ + message0: Blockly.Msg.LOOKS_COSTUMENUMBERNAME, + args0: [ + { + type: "field_dropdown", + name: "NUMBER_NAME", + options: [ + [Blockly.Msg.LOOKS_NUMBERNAME_NUMBER, "number"], + [Blockly.Msg.LOOKS_NUMBERNAME_NAME, "name"], + ], + }, + ], + category: Categories.looks, + extensions: ["colours_looks", "output_number"], + }); + this.checkboxInFlyout = true; + }, +}; + +Blockly.Blocks["looks_switchbackdroptoandwait"] = { + /** + * Block to switch the backdrop to the selected one and wait. + * @this Blockly.Block + */ + init: function () { + this.jsonInit({ + message0: Blockly.Msg.LOOKS_SWITCHBACKDROPTOANDWAIT, + args0: [ + { + type: "input_value", + name: "BACKDROP", + }, + ], + category: Categories.looks, + extensions: ["colours_looks", "shape_statement"], + }); + }, +}; + +Blockly.Blocks["looks_nextbackdrop"] = { + /** + * Block to switch the backdrop to the next one. + * @this Blockly.Block + */ + init: function () { + this.jsonInit({ + message0: Blockly.Msg.LOOKS_NEXTBACKDROP_BLOCK, + category: Categories.looks, + extensions: ["colours_looks", "shape_statement"], + }); + }, +}; diff --git a/blocks_common/math.js b/src/blocks/math.js similarity index 97% rename from blocks_common/math.js rename to src/blocks/math.js index 4532738057..ec5075cb5e 100644 --- a/blocks_common/math.js +++ b/src/blocks/math.js @@ -23,8 +23,8 @@ * @author q.neutron@gmail.com (Quynh Neutron) */ import * as Blockly from "blockly/core"; -import { Colours } from "../core/colours.js"; -import * as Constants from "../src/constants.js"; +import { Colours } from "../colours.js"; +import * as Constants from "../constants.js"; Blockly.Blocks["math_number"] = { /** diff --git a/blocks_common/matrix.js b/src/blocks/matrix.js similarity index 70% rename from blocks_common/matrix.js rename to src/blocks/matrix.js index 839a778496..85893b17c0 100644 --- a/blocks_common/matrix.js +++ b/src/blocks/matrix.js @@ -22,26 +22,26 @@ * @fileoverview Matrix blocks for Blockly. * @author khanning@gmail.com (Kreg Hanning) */ -import * as Blockly from 'blockly/core'; -import * as Constants from '../src/constants.js'; +import * as Blockly from "blockly/core"; +import * as Constants from "../constants.js"; -Blockly.Blocks['matrix'] = { +Blockly.Blocks["matrix"] = { /** * Block for matrix value. * @this Blockly.Block */ - init: function() { + init: function () { this.jsonInit({ - "message0": "%1", - "args0": [ + message0: "%1", + args0: [ { - "type": "field_matrix", - "name": "MATRIX" - } + type: "field_matrix", + name: "MATRIX", + }, ], - "outputShape": Constants.OUTPUT_SHAPE_ROUND, - "output": "Number", - "extensions": ["colours_pen"] + outputShape: Constants.OUTPUT_SHAPE_ROUND, + output: "Number", + extensions: ["colours_pen"], }); - } + }, }; diff --git a/src/blocks/motion.js b/src/blocks/motion.js new file mode 100644 index 0000000000..920a033b35 --- /dev/null +++ b/src/blocks/motion.js @@ -0,0 +1,570 @@ +/** + * @license + * Visual Blocks Editor + * + * Copyright 2016 Massachusetts Institute of Technology + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import * as Blockly from "blockly/core"; +import { Categories } from "../categories.js"; + +Blockly.Blocks["motion_movesteps"] = { + /** + * Block to move steps. + * @this Blockly.Block + */ + init: function () { + this.jsonInit({ + message0: Blockly.Msg.MOTION_MOVESTEPS, + args0: [ + { + type: "input_value", + name: "STEPS", + }, + ], + category: Categories.motion, + extensions: ["colours_motion", "shape_statement"], + }); + }, +}; + +Blockly.Blocks["motion_turnright"] = { + /** + * Block to turn right. + * @this Blockly.Block + */ + init: function () { + const ws = this.workspace.options.parentWorkspace || this.workspace; + this.jsonInit({ + message0: Blockly.Msg.MOTION_TURNRIGHT, + args0: [ + { + type: "field_image", + src: ws.options.pathToMedia + "rotate-right.svg", + width: 24, + height: 24, + }, + { + type: "input_value", + name: "DEGREES", + }, + ], + category: Categories.motion, + extensions: ["colours_motion", "shape_statement"], + }); + }, +}; + +Blockly.Blocks["motion_turnleft"] = { + /** + * Block to turn left. + * @this Blockly.Block + */ + init: function () { + const ws = this.workspace.options.parentWorkspace || this.workspace; + this.jsonInit({ + message0: Blockly.Msg.MOTION_TURNLEFT, + args0: [ + { + type: "field_image", + src: ws.options.pathToMedia + "rotate-left.svg", + width: 24, + height: 24, + }, + { + type: "input_value", + name: "DEGREES", + }, + ], + category: Categories.motion, + extensions: ["colours_motion", "shape_statement"], + }); + }, +}; + +Blockly.Blocks["motion_pointindirection"] = { + /** + * Block to point in direction. + * @this Blockly.Block + */ + init: function () { + this.jsonInit({ + message0: Blockly.Msg.MOTION_POINTINDIRECTION, + args0: [ + { + type: "input_value", + name: "DIRECTION", + }, + ], + category: Categories.motion, + extensions: ["colours_motion", "shape_statement"], + }); + }, +}; + +Blockly.Blocks["motion_pointtowards_menu"] = { + /** + * Point towards drop-down menu. + * @this Blockly.Block + */ + init: function () { + this.jsonInit({ + message0: "%1", + args0: [ + { + type: "field_dropdown", + name: "TOWARDS", + options: [ + [Blockly.Msg.MOTION_POINTTOWARDS_POINTER, "_mouse_"], + [Blockly.Msg.MOTION_POINTTOWARDS_RANDOM, "_random_"], + ], + }, + ], + extensions: ["colours_motion", "output_string"], + }); + }, +}; + +Blockly.Blocks["motion_pointtowards"] = { + /** + * Block to point in direction. + * @this Blockly.Block + */ + init: function () { + this.jsonInit({ + message0: Blockly.Msg.MOTION_POINTTOWARDS, + args0: [ + { + type: "input_value", + name: "TOWARDS", + }, + ], + category: Categories.motion, + extensions: ["colours_motion", "shape_statement"], + }); + }, +}; + +Blockly.Blocks["motion_goto_menu"] = { + /** + * Go to drop-down menu. + * @this Blockly.Block + */ + init: function () { + this.jsonInit({ + message0: "%1", + args0: [ + { + type: "field_dropdown", + name: "TO", + options: [ + [Blockly.Msg.MOTION_GOTO_POINTER, "_mouse_"], + [Blockly.Msg.MOTION_GOTO_RANDOM, "_random_"], + ], + }, + ], + extensions: ["colours_motion", "output_string"], + }); + }, +}; + +Blockly.Blocks["motion_gotoxy"] = { + /** + * Block to go to X, Y. + * @this Blockly.Block + */ + init: function () { + this.jsonInit({ + message0: Blockly.Msg.MOTION_GOTOXY, + args0: [ + { + type: "input_value", + name: "X", + }, + { + type: "input_value", + name: "Y", + }, + ], + category: Categories.motion, + extensions: ["colours_motion", "shape_statement"], + }); + }, +}; + +Blockly.Blocks["motion_goto"] = { + /** + * Block to go to a menu item. + * @this Blockly.Block + */ + init: function () { + this.jsonInit({ + message0: Blockly.Msg.MOTION_GOTO, + args0: [ + { + type: "input_value", + name: "TO", + }, + ], + category: Categories.motion, + extensions: ["colours_motion", "shape_statement"], + }); + }, +}; + +Blockly.Blocks["motion_glidesecstoxy"] = { + /** + * Block to glide for a specified time. + * @this Blockly.Block + */ + init: function () { + this.jsonInit({ + message0: Blockly.Msg.MOTION_GLIDESECSTOXY, + args0: [ + { + type: "input_value", + name: "SECS", + }, + { + type: "input_value", + name: "X", + }, + { + type: "input_value", + name: "Y", + }, + ], + category: Categories.motion, + extensions: ["colours_motion", "shape_statement"], + }); + }, +}; + +Blockly.Blocks["motion_glideto_menu"] = { + /** + * Glide to drop-down menu + * @this Blockly.Block + */ + init: function () { + this.jsonInit({ + message0: "%1", + args0: [ + { + type: "field_dropdown", + name: "TO", + options: [ + [Blockly.Msg.MOTION_GLIDETO_POINTER, "_mouse_"], + [Blockly.Msg.MOTION_GLIDETO_RANDOM, "_random_"], + ], + }, + ], + extensions: ["colours_motion", "output_string"], + }); + }, +}; + +Blockly.Blocks["motion_glideto"] = { + /** + * Block to glide to a menu item + * @this Blockly.Block + */ + init: function () { + this.jsonInit({ + message0: Blockly.Msg.MOTION_GLIDETO, + args0: [ + { + type: "input_value", + name: "SECS", + }, + { + type: "input_value", + name: "TO", + }, + ], + category: Categories.motion, + extensions: ["colours_motion", "shape_statement"], + }); + }, +}; + +Blockly.Blocks["motion_changexby"] = { + /** + * Block to change X. + * @this Blockly.Block + */ + init: function () { + this.jsonInit({ + message0: Blockly.Msg.MOTION_CHANGEXBY, + args0: [ + { + type: "input_value", + name: "DX", + }, + ], + category: Categories.motion, + extensions: ["colours_motion", "shape_statement"], + }); + }, +}; + +Blockly.Blocks["motion_setx"] = { + /** + * Block to set X. + * @this Blockly.Block + */ + init: function () { + this.jsonInit({ + message0: Blockly.Msg.MOTION_SETX, + args0: [ + { + type: "input_value", + name: "X", + }, + ], + category: Categories.motion, + extensions: ["colours_motion", "shape_statement"], + }); + }, +}; + +Blockly.Blocks["motion_changeyby"] = { + /** + * Block to change Y. + * @this Blockly.Block + */ + init: function () { + this.jsonInit({ + message0: Blockly.Msg.MOTION_CHANGEYBY, + args0: [ + { + type: "input_value", + name: "DY", + }, + ], + category: Categories.motion, + extensions: ["colours_motion", "shape_statement"], + }); + }, +}; + +Blockly.Blocks["motion_sety"] = { + /** + * Block to set Y. + * @this Blockly.Block + */ + init: function () { + this.jsonInit({ + message0: Blockly.Msg.MOTION_SETY, + args0: [ + { + type: "input_value", + name: "Y", + }, + ], + category: Categories.motion, + extensions: ["colours_motion", "shape_statement"], + }); + }, +}; + +Blockly.Blocks["motion_ifonedgebounce"] = { + /** + * Block to bounce on edge. + * @this Blockly.Block + */ + init: function () { + this.jsonInit({ + message0: Blockly.Msg.MOTION_IFONEDGEBOUNCE, + category: Categories.motion, + extensions: ["colours_motion", "shape_statement"], + }); + }, +}; + +Blockly.Blocks["motion_setrotationstyle"] = { + /** + * Block to set rotation style. + * @this Blockly.Block + */ + init: function () { + this.jsonInit({ + message0: Blockly.Msg.MOTION_SETROTATIONSTYLE, + args0: [ + { + type: "field_dropdown", + name: "STYLE", + options: [ + [Blockly.Msg.MOTION_SETROTATIONSTYLE_LEFTRIGHT, "left-right"], + [Blockly.Msg.MOTION_SETROTATIONSTYLE_DONTROTATE, "don't rotate"], + [Blockly.Msg.MOTION_SETROTATIONSTYLE_ALLAROUND, "all around"], + ], + }, + ], + category: Categories.motion, + extensions: ["colours_motion", "shape_statement"], + }); + }, +}; + +Blockly.Blocks["motion_xposition"] = { + /** + * Block to report X. + * @this Blockly.Block + */ + init: function () { + this.jsonInit({ + message0: Blockly.Msg.MOTION_XPOSITION, + category: Categories.motion, + extensions: ["colours_motion", "output_number"], + }); + this.checkboxInFlyout = true; + }, +}; + +Blockly.Blocks["motion_yposition"] = { + /** + * Block to report Y. + * @this Blockly.Block + */ + init: function () { + this.jsonInit({ + message0: Blockly.Msg.MOTION_YPOSITION, + category: Categories.motion, + extensions: ["colours_motion", "output_number"], + }); + this.checkboxInFlyout = true; + }, +}; + +Blockly.Blocks["motion_direction"] = { + /** + * Block to report direction. + * @this Blockly.Block + */ + init: function () { + this.jsonInit({ + message0: Blockly.Msg.MOTION_DIRECTION, + category: Categories.motion, + extensions: ["colours_motion", "output_number"], + }); + this.checkboxInFlyout = true; + }, +}; + +Blockly.Blocks["motion_scroll_right"] = { + /** + * Block to scroll the stage right. Does not actually do anything. This is + * an obsolete block that is implemented for compatibility with Scratch 2.0 + * projects. + * @this Blockly.Block + */ + init: function () { + this.jsonInit({ + message0: Blockly.Msg.MOTION_SCROLLRIGHT, + args0: [ + { + type: "input_value", + name: "DISTANCE", + }, + ], + category: Categories.motion, + extensions: ["colours_motion", "shape_statement"], + }); + }, +}; + +Blockly.Blocks["motion_scroll_up"] = { + /** + * Block to scroll the stage up. Does not actually do anything. This is an + * obsolete block that is implemented for compatibility with Scratch 2.0 + * projects. + * @this Blockly.Block + */ + init: function () { + this.jsonInit({ + message0: Blockly.Msg.MOTION_SCROLLUP, + args0: [ + { + type: "input_value", + name: "DISTANCE", + }, + ], + category: Categories.motion, + extensions: ["colours_motion", "shape_statement"], + }); + }, +}; + +Blockly.Blocks["motion_align_scene"] = { + /** + * Block to change the stage's scrolling alignment. Does not actually do + * anything. This is an obsolete block that is implemented for compatibility + * with Scratch 2.0 projects. + * @this Blockly.Block + */ + init: function () { + this.jsonInit({ + message0: Blockly.Msg.MOTION_ALIGNSCENE, + args0: [ + { + type: "field_dropdown", + name: "ALIGNMENT", + options: [ + [Blockly.Msg.MOTION_ALIGNSCENE_BOTTOMLEFT, "bottom-left"], + [Blockly.Msg.MOTION_ALIGNSCENE_BOTTOMRIGHT, "bottom-right"], + [Blockly.Msg.MOTION_ALIGNSCENE_MIDDLE, "middle"], + [Blockly.Msg.MOTION_ALIGNSCENE_TOPLEFT, "top-left"], + [Blockly.Msg.MOTION_ALIGNSCENE_TOPRIGHT, "top-right"], + ], + }, + ], + category: Categories.motion, + extensions: ["colours_motion", "shape_statement"], + }); + }, +}; + +Blockly.Blocks["motion_xscroll"] = { + /** + * Block to report the stage's scroll position's X value. Does not actually + * do anything. This is an obsolete block that is implemented for + * compatibility with Scratch 2.0 projects. + * @this Blockly.Block + */ + init: function () { + this.jsonInit({ + message0: Blockly.Msg.MOTION_XSCROLL, + category: Categories.motion, + extensions: ["colours_motion", "output_number"], + }); + }, +}; + +Blockly.Blocks["motion_yscroll"] = { + /** + * Block to report the stage's scroll position's Y value. Does not actually + * do anything. This is an obsolete block that is implemented for + * compatibility with Scratch 2.0 projects. + * @this Blockly.Block + */ + init: function () { + this.jsonInit({ + message0: Blockly.Msg.MOTION_YSCROLL, + category: Categories.motion, + extensions: ["colours_motion", "output_number"], + }); + }, +}; diff --git a/blocks_common/note.js b/src/blocks/note.js similarity index 61% rename from blocks_common/note.js rename to src/blocks/note.js index 4fb673964b..2256798aac 100644 --- a/blocks_common/note.js +++ b/src/blocks/note.js @@ -22,31 +22,31 @@ * @fileoverview Note block. * @author ericr@media.mit.edu (Eric Rosenbaum) */ -import * as Blockly from 'blockly/core'; -import {Colours} from '../core/colours.js'; -import * as Constants from '../src/constants.js'; +import * as Blockly from "blockly/core"; +import { Colours } from "../colours.js"; +import * as Constants from "../constants.js"; -Blockly.Blocks['note'] = { +Blockly.Blocks["note"] = { /** * Block for musical note value. * @this Blockly.Block */ - init: function() { + init: function () { this.jsonInit({ - "message0": "%1", - "args0": [ + message0: "%1", + args0: [ { - "type": "field_note", - "name": "NOTE", - "value": 60 - } + type: "field_note", + name: "NOTE", + value: 60, + }, ], - "outputShape": Constants.OUTPUT_SHAPE_ROUND, - "output": "Number", - "colour": Colours.textField, - "colourSecondary": Colours.textField, - "colourTertiary": Colours.textField, - "colourQuaternary": Colours.textField + outputShape: Constants.OUTPUT_SHAPE_ROUND, + output: "Number", + colour: Colours.textField, + colourSecondary: Colours.textField, + colourTertiary: Colours.textField, + colourQuaternary: Colours.textField, }); - } + }, }; diff --git a/src/blocks/operators.js b/src/blocks/operators.js new file mode 100644 index 0000000000..be93a82334 --- /dev/null +++ b/src/blocks/operators.js @@ -0,0 +1,463 @@ +/** + * @license + * Visual Blocks Editor + * + * Copyright 2012 Google Inc. + * https://developers.google.com/blockly/ + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import * as Blockly from "blockly/core"; +import { Categories } from "../categories.js"; + +Blockly.Blocks["operator_add"] = { + /** + * Block for adding two numbers. + * @this Blockly.Block + */ + init: function () { + this.jsonInit({ + message0: Blockly.Msg.OPERATORS_ADD, + args0: [ + { + type: "input_value", + name: "NUM1", + }, + { + type: "input_value", + name: "NUM2", + }, + ], + category: Categories.operators, + extensions: ["colours_operators", "output_number"], + }); + }, +}; + +Blockly.Blocks["operator_subtract"] = { + /** + * Block for subtracting two numbers. + * @this Blockly.Block + */ + init: function () { + this.jsonInit({ + message0: Blockly.Msg.OPERATORS_SUBTRACT, + args0: [ + { + type: "input_value", + name: "NUM1", + }, + { + type: "input_value", + name: "NUM2", + }, + ], + category: Categories.operators, + extensions: ["colours_operators", "output_number"], + }); + }, +}; + +Blockly.Blocks["operator_multiply"] = { + /** + * Block for multiplying two numbers. + * @this Blockly.Block + */ + init: function () { + this.jsonInit({ + message0: Blockly.Msg.OPERATORS_MULTIPLY, + args0: [ + { + type: "input_value", + name: "NUM1", + }, + { + type: "input_value", + name: "NUM2", + }, + ], + category: Categories.operators, + extensions: ["colours_operators", "output_number"], + }); + }, +}; + +Blockly.Blocks["operator_divide"] = { + /** + * Block for dividing two numbers. + * @this Blockly.Block + */ + init: function () { + this.jsonInit({ + message0: Blockly.Msg.OPERATORS_DIVIDE, + args0: [ + { + type: "input_value", + name: "NUM1", + }, + { + type: "input_value", + name: "NUM2", + }, + ], + category: Categories.operators, + extensions: ["colours_operators", "output_number"], + }); + }, +}; + +Blockly.Blocks["operator_random"] = { + /** + * Block for picking a random number. + * @this Blockly.Block + */ + init: function () { + this.jsonInit({ + message0: Blockly.Msg.OPERATORS_RANDOM, + args0: [ + { + type: "input_value", + name: "FROM", + }, + { + type: "input_value", + name: "TO", + }, + ], + category: Categories.operators, + extensions: ["colours_operators", "output_number"], + }); + }, +}; + +Blockly.Blocks["operator_lt"] = { + /** + * Block for less than comparator. + * @this Blockly.Block + */ + init: function () { + this.jsonInit({ + message0: Blockly.Msg.OPERATORS_LT, + args0: [ + { + type: "input_value", + name: "OPERAND1", + }, + { + type: "input_value", + name: "OPERAND2", + }, + ], + category: Categories.operators, + extensions: ["colours_operators", "output_boolean"], + }); + }, +}; + +Blockly.Blocks["operator_equals"] = { + /** + * Block for equals comparator. + * @this Blockly.Block + */ + init: function () { + this.jsonInit({ + message0: Blockly.Msg.OPERATORS_EQUALS, + args0: [ + { + type: "input_value", + name: "OPERAND1", + }, + { + type: "input_value", + name: "OPERAND2", + }, + ], + category: Categories.operators, + extensions: ["colours_operators", "output_boolean"], + }); + }, +}; + +Blockly.Blocks["operator_gt"] = { + /** + * Block for greater than comparator. + * @this Blockly.Block + */ + init: function () { + this.jsonInit({ + message0: Blockly.Msg.OPERATORS_GT, + args0: [ + { + type: "input_value", + name: "OPERAND1", + }, + { + type: "input_value", + name: "OPERAND2", + }, + ], + category: Categories.operators, + extensions: ["colours_operators", "output_boolean"], + }); + }, +}; + +Blockly.Blocks["operator_and"] = { + /** + * Block for "and" boolean comparator. + * @this Blockly.Block + */ + init: function () { + this.jsonInit({ + message0: Blockly.Msg.OPERATORS_AND, + args0: [ + { + type: "input_value", + name: "OPERAND1", + check: "Boolean", + }, + { + type: "input_value", + name: "OPERAND2", + check: "Boolean", + }, + ], + category: Categories.operators, + extensions: ["colours_operators", "output_boolean"], + }); + }, +}; + +Blockly.Blocks["operator_or"] = { + /** + * Block for "or" boolean comparator. + * @this Blockly.Block + */ + init: function () { + this.jsonInit({ + message0: Blockly.Msg.OPERATORS_OR, + args0: [ + { + type: "input_value", + name: "OPERAND1", + check: "Boolean", + }, + { + type: "input_value", + name: "OPERAND2", + check: "Boolean", + }, + ], + category: Categories.operators, + extensions: ["colours_operators", "output_boolean"], + }); + }, +}; + +Blockly.Blocks["operator_not"] = { + /** + * Block for "not" unary boolean operator. + * @this Blockly.Block + */ + init: function () { + this.jsonInit({ + message0: Blockly.Msg.OPERATORS_NOT, + args0: [ + { + type: "input_value", + name: "OPERAND", + check: "Boolean", + }, + ], + category: Categories.operators, + extensions: ["colours_operators", "output_boolean"], + }); + }, +}; + +Blockly.Blocks["operator_join"] = { + /** + * Block for string join operator. + * @this Blockly.Block + */ + init: function () { + this.jsonInit({ + message0: Blockly.Msg.OPERATORS_JOIN, + args0: [ + { + type: "input_value", + name: "STRING1", + }, + { + type: "input_value", + name: "STRING2", + }, + ], + category: Categories.operators, + extensions: ["colours_operators", "output_string"], + }); + }, +}; + +Blockly.Blocks["operator_letter_of"] = { + /** + * Block for "letter _ of _" operator. + * @this Blockly.Block + */ + init: function () { + this.jsonInit({ + message0: Blockly.Msg.OPERATORS_LETTEROF, + args0: [ + { + type: "input_value", + name: "LETTER", + }, + { + type: "input_value", + name: "STRING", + }, + ], + category: Categories.operators, + extensions: ["colours_operators", "output_string"], + }); + }, +}; + +Blockly.Blocks["operator_length"] = { + /** + * Block for string length operator. + * @this Blockly.Block + */ + init: function () { + this.jsonInit({ + message0: Blockly.Msg.OPERATORS_LENGTH, + args0: [ + { + type: "input_value", + name: "STRING", + }, + ], + category: Categories.operators, + extensions: ["colours_operators", "output_string"], + }); + }, +}; + +Blockly.Blocks["operator_contains"] = { + /** + * Block for _ contains _ operator + * @this Blockly.Block + */ + init: function () { + this.jsonInit({ + message0: Blockly.Msg.OPERATORS_CONTAINS, + args0: [ + { + type: "input_value", + name: "STRING1", + }, + { + type: "input_value", + name: "STRING2", + }, + ], + category: Categories.operators, + extensions: ["colours_operators", "output_boolean"], + }); + }, +}; + +Blockly.Blocks["operator_mod"] = { + /** + * Block for mod two numbers. + * @this Blockly.Block + */ + init: function () { + this.jsonInit({ + message0: Blockly.Msg.OPERATORS_MOD, + args0: [ + { + type: "input_value", + name: "NUM1", + }, + { + type: "input_value", + name: "NUM2", + }, + ], + category: Categories.operators, + extensions: ["colours_operators", "output_number"], + }); + }, +}; + +Blockly.Blocks["operator_round"] = { + /** + * Block for rounding a numbers. + * @this Blockly.Block + */ + init: function () { + this.jsonInit({ + message0: Blockly.Msg.OPERATORS_ROUND, + args0: [ + { + type: "input_value", + name: "NUM", + }, + ], + category: Categories.operators, + extensions: ["colours_operators", "output_number"], + }); + }, +}; + +Blockly.Blocks["operator_mathop"] = { + /** + * Block for "advanced" math ops on a number. + * @this Blockly.Block + */ + init: function () { + this.jsonInit({ + message0: Blockly.Msg.OPERATORS_MATHOP, + args0: [ + { + type: "field_dropdown", + name: "OPERATOR", + options: [ + [Blockly.Msg.OPERATORS_MATHOP_ABS, "abs"], + [Blockly.Msg.OPERATORS_MATHOP_FLOOR, "floor"], + [Blockly.Msg.OPERATORS_MATHOP_CEILING, "ceiling"], + [Blockly.Msg.OPERATORS_MATHOP_SQRT, "sqrt"], + [Blockly.Msg.OPERATORS_MATHOP_SIN, "sin"], + [Blockly.Msg.OPERATORS_MATHOP_COS, "cos"], + [Blockly.Msg.OPERATORS_MATHOP_TAN, "tan"], + [Blockly.Msg.OPERATORS_MATHOP_ASIN, "asin"], + [Blockly.Msg.OPERATORS_MATHOP_ACOS, "acos"], + [Blockly.Msg.OPERATORS_MATHOP_ATAN, "atan"], + [Blockly.Msg.OPERATORS_MATHOP_LN, "ln"], + [Blockly.Msg.OPERATORS_MATHOP_LOG, "log"], + [Blockly.Msg.OPERATORS_MATHOP_EEXP, "e ^"], + [Blockly.Msg.OPERATORS_MATHOP_10EXP, "10 ^"], + ], + }, + { + type: "input_value", + name: "NUM", + }, + ], + category: Categories.operators, + extensions: ["colours_operators", "output_number"], + }); + }, +}; diff --git a/blocks_vertical/procedures.js b/src/blocks/procedures.js similarity index 99% rename from blocks_vertical/procedures.js rename to src/blocks/procedures.js index cdde28ff1f..68e8b4e5ca 100644 --- a/blocks_vertical/procedures.js +++ b/src/blocks/procedures.js @@ -23,8 +23,8 @@ */ import * as Blockly from "blockly/core"; -import { Colours } from "../core/colours.js"; -import { FieldTextInputRemovable } from "../core/field_textinput_removable.js"; +import { Colours } from "../colours.js"; +import { FieldTextInputRemovable } from "../fields/field_textinput_removable.js"; class DuplicateOnDragDraggable { constructor(block) { diff --git a/blocks_vertical/sensing.js b/src/blocks/sensing.js similarity index 99% rename from blocks_vertical/sensing.js rename to src/blocks/sensing.js index c25eae5159..c2f4c79424 100644 --- a/blocks_vertical/sensing.js +++ b/src/blocks/sensing.js @@ -19,8 +19,8 @@ */ import * as Blockly from "blockly/core"; -import { Categories } from "../src/categories.js"; -import * as Constants from "../src/constants.js"; +import { Categories } from "../categories.js"; +import * as Constants from "../constants.js"; Blockly.Blocks["sensing_touchingobject"] = { /** diff --git a/src/blocks/sound.js b/src/blocks/sound.js new file mode 100644 index 0000000000..16941408ec --- /dev/null +++ b/src/blocks/sound.js @@ -0,0 +1,209 @@ +/** + * @license + * Visual Blocks Editor + * + * Copyright 2016 Massachusetts Institute of Technology + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import * as Blockly from "blockly/core"; +import { Categories } from "../categories.js"; + +Blockly.Blocks["sound_sounds_menu"] = { + /** + * Sound effects drop-down menu. Populated dynamically by scratch-gui. + * @this Blockly.Block + */ +}; + +Blockly.Blocks["sound_play"] = { + /** + * Block to play sound. + * @this Blockly.Block + */ + init: function () { + this.jsonInit({ + message0: Blockly.Msg.SOUND_PLAY, + args0: [ + { + type: "input_value", + name: "SOUND_MENU", + }, + ], + category: Categories.sound, + extensions: ["colours_sounds", "shape_statement"], + }); + }, +}; + +Blockly.Blocks["sound_playuntildone"] = { + /** + * Block to play sound until done. + * @this Blockly.Block + */ + init: function () { + this.jsonInit({ + message0: Blockly.Msg.SOUND_PLAYUNTILDONE, + args0: [ + { + type: "input_value", + name: "SOUND_MENU", + }, + ], + category: Categories.sound, + extensions: ["colours_sounds", "shape_statement"], + }); + }, +}; + +Blockly.Blocks["sound_stopallsounds"] = { + /** + * Block to stop all sounds + * @this Blockly.Block + */ + init: function () { + this.jsonInit({ + message0: Blockly.Msg.SOUND_STOPALLSOUNDS, + category: Categories.sound, + extensions: ["colours_sounds", "shape_statement"], + }); + }, +}; + +Blockly.Blocks["sound_seteffectto"] = { + /** + * Block to set the audio effect + * @this Blockly.Block + */ + init: function () { + this.jsonInit({ + message0: Blockly.Msg.SOUND_SETEFFECTO, + args0: [ + { + type: "field_dropdown", + name: "EFFECT", + options: [ + [Blockly.Msg.SOUND_EFFECTS_PITCH, "PITCH"], + [Blockly.Msg.SOUND_EFFECTS_PAN, "PAN"], + ], + }, + { + type: "input_value", + name: "VALUE", + }, + ], + category: Categories.sound, + extensions: ["colours_sounds", "shape_statement"], + }); + }, +}; + +Blockly.Blocks["sound_changeeffectby"] = { + /** + * Block to change the audio effect + * @this Blockly.Block + */ + init: function () { + this.jsonInit({ + message0: Blockly.Msg.SOUND_CHANGEEFFECTBY, + args0: [ + { + type: "field_dropdown", + name: "EFFECT", + options: [ + [Blockly.Msg.SOUND_EFFECTS_PITCH, "PITCH"], + [Blockly.Msg.SOUND_EFFECTS_PAN, "PAN"], + ], + }, + { + type: "input_value", + name: "VALUE", + }, + ], + category: Categories.sound, + extensions: ["colours_sounds", "shape_statement"], + }); + }, +}; + +Blockly.Blocks["sound_cleareffects"] = { + /** + * Block to clear audio effects + * @this Blockly.Block + */ + init: function () { + this.jsonInit({ + message0: Blockly.Msg.SOUND_CLEAREFFECTS, + category: Categories.sound, + extensions: ["colours_sounds", "shape_statement"], + }); + }, +}; + +Blockly.Blocks["sound_changevolumeby"] = { + /** + * Block to change the sprite's volume by a certain value + * @this Blockly.Block + */ + init: function () { + this.jsonInit({ + message0: Blockly.Msg.SOUND_CHANGEVOLUMEBY, + args0: [ + { + type: "input_value", + name: "VOLUME", + }, + ], + category: Categories.sound, + extensions: ["colours_sounds", "shape_statement"], + }); + }, +}; + +Blockly.Blocks["sound_setvolumeto"] = { + /** + * Block to set the sprite's volume to a certain percent + * @this Blockly.Block + */ + init: function () { + this.jsonInit({ + message0: Blockly.Msg.SOUND_SETVOLUMETO, + args0: [ + { + type: "input_value", + name: "VOLUME", + }, + ], + category: Categories.sound, + extensions: ["colours_sounds", "shape_statement"], + }); + }, +}; + +Blockly.Blocks["sound_volume"] = { + /** + * Block to report volume + * @this Blockly.Block + */ + init: function () { + this.jsonInit({ + message0: Blockly.Msg.SOUND_VOLUME, + category: Categories.sound, + checkboxInFlyout: true, + extensions: ["colours_sounds", "output_number"], + }); + this.checkboxInFlyout = true; + }, +}; diff --git a/blocks_common/text.js b/src/blocks/text.js similarity index 67% rename from blocks_common/text.js rename to src/blocks/text.js index aa66f2059b..f404ddee19 100644 --- a/blocks_common/text.js +++ b/src/blocks/text.js @@ -22,28 +22,28 @@ * @fileoverview Text blocks for Blockly. * @author fraser@google.com (Neil Fraser) */ -import * as Blockly from 'blockly'; -import {Colours} from '../core/colours.js'; +import * as Blockly from "blockly/core"; +import { Colours } from "../colours.js"; -Blockly.Blocks['text'] = { +Blockly.Blocks["text"] = { /** * Block for text value. * @this Blockly.Block */ - init: function() { + init: function () { this.jsonInit({ - "message0": "%1", - "args0": [ + message0: "%1", + args0: [ { - "type": "field_input", - "name": "TEXT" - } + type: "field_input", + name: "TEXT", + }, ], - "output": "String", - "colour": Colours.textField, - "colourSecondary": Colours.textField, - "colourTertiary": Colours.textField, - "colourQuaternary": Colours.textField + output: "String", + colour: Colours.textField, + colourSecondary: Colours.textField, + colourTertiary: Colours.textField, + colourQuaternary: Colours.textField, }); - } + }, }; diff --git a/blocks_vertical/vertical_extensions.js b/src/blocks/vertical_extensions.js similarity index 98% rename from blocks_vertical/vertical_extensions.js rename to src/blocks/vertical_extensions.js index f234e68cb5..474fbd5ace 100644 --- a/blocks_vertical/vertical_extensions.js +++ b/src/blocks/vertical_extensions.js @@ -26,9 +26,9 @@ * @author fenichel@google.com (Rachel Fenichel) */ import * as Blockly from "blockly/core"; -import { Colours } from "../core/colours.js"; -import { ScratchProcedures } from "../src/procedures.js"; -import * as Constants from "../src/constants.js"; +import { Colours } from "../colours.js"; +import { ScratchProcedures } from "../procedures.js"; +import * as Constants from "../constants.js"; const VerticalExtensions = {}; /** diff --git a/src/categories.js b/src/categories.js index f691dbef7b..1ea1a6640d 100644 --- a/src/categories.js +++ b/src/categories.js @@ -1,15 +1,15 @@ const Categories = { - "motion": "motion", - "looks": "looks", - "sound": "sounds", - "pen": "pen", - "data": "data", - "dataLists": "data-lists", - "event": "events", - "control": "control", - "sensing": "sensing", - "operators": "operators", - "more": "more" + motion: "motion", + looks: "looks", + sound: "sounds", + pen: "pen", + data: "data", + dataLists: "data-lists", + event: "events", + control: "control", + sensing: "sensing", + operators: "operators", + more: "more", }; -export {Categories}; +export { Categories }; diff --git a/src/checkable_continuous_flyout.js b/src/checkable_continuous_flyout.js index 7d0cf6130a..77e90ea3ad 100644 --- a/src/checkable_continuous_flyout.js +++ b/src/checkable_continuous_flyout.js @@ -1,4 +1,4 @@ -import * as Blockly from "blockly"; +import * as Blockly from "blockly/core"; import { ContinuousFlyout } from "@blockly/continuous-toolbox"; export class CheckableContinuousFlyout extends ContinuousFlyout { diff --git a/src/colours.js b/src/colours.js new file mode 100644 index 0000000000..c1f8cfab54 --- /dev/null +++ b/src/colours.js @@ -0,0 +1,179 @@ +/** + * @license + * Visual Blocks Editor + * + * Copyright 2016 Massachusetts Institute of Technology + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import * as Blockly from "blockly/core"; + +const cssColours = { + // SVG colours: these must be specificed in #RRGGBB style + // To add an opacity, this must be specified as a separate property (for SVG fill-opacity) + motion: { + primary: "#4C97FF", + secondary: "#4280D7", + tertiary: "#3373CC", + quaternary: "#3373CC", + }, + looks: { + primary: "#9966FF", + secondary: "#855CD6", + tertiary: "#774DCB", + quaternary: "#774DCB", + }, + sounds: { + primary: "#CF63CF", + secondary: "#C94FC9", + tertiary: "#BD42BD", + quaternary: "#BD42BD", + }, + control: { + primary: "#FFAB19", + secondary: "#EC9C13", + tertiary: "#CF8B17", + quaternary: "#CF8B17", + }, + event: { + primary: "#FFBF00", + secondary: "#E6AC00", + tertiary: "#CC9900", + quaternary: "#CC9900", + }, + sensing: { + primary: "#5CB1D6", + secondary: "#47A8D1", + tertiary: "#2E8EB8", + quaternary: "#2E8EB8", + }, + pen: { + primary: "#0fBD8C", + secondary: "#0DA57A", + tertiary: "#0B8E69", + quaternary: "#0B8E69", + }, + operators: { + primary: "#59C059", + secondary: "#46B946", + tertiary: "#389438", + quaternary: "#389438", + }, + data: { + primary: "#FF8C1A", + secondary: "#FF8000", + tertiary: "#DB6E00", + quaternary: "#DB6E00", + }, + // This is not a new category, but rather for differentiation + // between lists and scalar variables. + data_lists: { + primary: "#FF661A", + secondary: "#FF5500", + tertiary: "#E64D00", + quaternary: "#E64D00", + }, + more: { + primary: "#FF6680", + secondary: "#FF4D6A", + tertiary: "#FF3355", + quaternary: "#FF3355", + }, + text: "#FFFFFF", + workspace: "#F9F9F9", + toolboxHover: "#4C97FF", + toolboxSelected: "#e9eef2", + toolboxText: "#575E75", + toolbox: "#FFFFFF", + flyout: "#F9F9F9", + scrollbar: "#CECDCE", + scrollbarHover: "#CECDCE", + textField: "#FFFFFF", + textFieldText: "#575E75", + insertionMarker: "#000000", + insertionMarkerOpacity: 0.2, + dragShadowOpacity: 0.6, + stackGlow: "#FFF200", + stackGlowSize: 4, + stackGlowOpacity: 1, + replacementGlow: "#FFFFFF", + replacementGlowSize: 2, + replacementGlowOpacity: 1, + colourPickerStroke: "#FFFFFF", + // CSS colours: support RGBA + fieldShadow: "rgba(0,0,0,0.1)", + dropDownShadow: "rgba(0, 0, 0, .3)", + numPadBackground: "#547AB2", + numPadBorder: "#435F91", + numPadActiveBackground: "#435F91", + numPadText: "white", // Do not use hex here, it cannot be inlined with data-uri SVG + valueReportBackground: "#FFFFFF", + valueReportBorder: "#AAAAAA", + menuHover: "rgba(0, 0, 0, 0.2)", +}; + +const Colours = { + ...cssColours, + overrideColours: function (colours) { + // Colour overrides provided by the injection + if (colours) { + for (var colourProperty in colours) { + if ( + colours.hasOwnProperty(colourProperty) && + this.hasOwnProperty(colourProperty) + ) { + // If a property is in both colours option and Blockly.Colours, + // set the Blockly.Colours value to the override. + // Override Blockly category color object properties with those + // provided. + var colourPropertyValue = colours[colourProperty]; + if (goog.isObject(colourPropertyValue)) { + for (var colourSequence in colourPropertyValue) { + if ( + colourPropertyValue.hasOwnProperty(colourSequence) && + this[colourProperty].hasOwnProperty(colourSequence) + ) { + this[colourProperty][colourSequence] = + colourPropertyValue[colourSequence]; + } + } + } else { + this[colourProperty] = colourPropertyValue; + } + } + } + } + }, +}; + +function varify(coloursObj, prefix = "--colour") { + return Object.keys(coloursObj) + .map((key) => { + const colour = coloursObj[key]; + if (typeof colour === "string") { + return `${prefix}-${key}: ${colour};`; + } else { + return varify(colour, `${prefix}-${key}`); + } + }) + .join("\n"); +} + +const cssVariables = `:root { + ${varify(cssColours)} +}`; + +Blockly.Css.register(cssVariables); + +export { Colours }; diff --git a/src/context_menu_items.js b/src/context_menu_items.js index aca1ae0796..afa423b372 100644 --- a/src/context_menu_items.js +++ b/src/context_menu_items.js @@ -61,7 +61,9 @@ export function registerDeleteAll() { if (!scope.workspace) { return ""; } - const deletableBlocksLength = getDeletableBlocksInWorkspace(scope.workspace).length; + const deletableBlocksLength = getDeletableBlocksInWorkspace( + scope.workspace + ).length; if (deletableBlocksLength === 1) { return Blockly.Msg["DELETE_BLOCK"]; } @@ -74,7 +76,9 @@ export function registerDeleteAll() { if (!scope.workspace) { return "disabled"; } - const deletableBlocksLength = getDeletableBlocksInWorkspace(scope.workspace).length; + const deletableBlocksLength = getDeletableBlocksInWorkspace( + scope.workspace + ).length; return deletableBlocksLength > 0 ? "enabled" : "disabled"; }, callback(scope) { diff --git a/core/css.js b/src/css.js similarity index 100% rename from core/css.js rename to src/css.js diff --git a/src/events_block_comment_base.js b/src/events/events_block_comment_base.js similarity index 100% rename from src/events_block_comment_base.js rename to src/events/events_block_comment_base.js diff --git a/src/events_block_comment_change.js b/src/events/events_block_comment_change.js similarity index 100% rename from src/events_block_comment_change.js rename to src/events/events_block_comment_change.js diff --git a/src/events_block_comment_collapse.js b/src/events/events_block_comment_collapse.js similarity index 100% rename from src/events_block_comment_collapse.js rename to src/events/events_block_comment_collapse.js diff --git a/src/events_block_comment_create.js b/src/events/events_block_comment_create.js similarity index 100% rename from src/events_block_comment_create.js rename to src/events/events_block_comment_create.js diff --git a/src/events_block_comment_delete.js b/src/events/events_block_comment_delete.js similarity index 100% rename from src/events_block_comment_delete.js rename to src/events/events_block_comment_delete.js diff --git a/src/events_block_comment_move.js b/src/events/events_block_comment_move.js similarity index 100% rename from src/events_block_comment_move.js rename to src/events/events_block_comment_move.js diff --git a/src/events_block_comment_resize.js b/src/events/events_block_comment_resize.js similarity index 100% rename from src/events_block_comment_resize.js rename to src/events/events_block_comment_resize.js diff --git a/src/events_block_drag_end.js b/src/events/events_block_drag_end.js similarity index 100% rename from src/events_block_drag_end.js rename to src/events/events_block_drag_end.js diff --git a/src/events_block_drag_outside.js b/src/events/events_block_drag_outside.js similarity index 100% rename from src/events_block_drag_outside.js rename to src/events/events_block_drag_outside.js diff --git a/src/events_scratch_variable_create.js b/src/events/events_scratch_variable_create.js similarity index 100% rename from src/events_scratch_variable_create.js rename to src/events/events_scratch_variable_create.js diff --git a/core/field_colour_slider.js b/src/fields/field_colour_slider.js similarity index 66% rename from core/field_colour_slider.js rename to src/fields/field_colour_slider.js index c02e254179..b70b1ea4f6 100644 --- a/core/field_colour_slider.js +++ b/src/fields/field_colour_slider.js @@ -22,8 +22,8 @@ * @fileoverview Colour input field. * @author fraser@google.com (Neil Fraser) */ -import * as Blockly from 'blockly/core'; -import {FieldColour} from '@blockly/field-colour'; +import * as Blockly from "blockly/core"; +import { FieldColour } from "@blockly/field-colour"; /** * Class for a slider-based colour input field. @@ -52,7 +52,7 @@ export class FieldColourSlider extends FieldColour { /** * Path to the eyedropper svg icon. */ - this.EYEDROPPER_PATH = 'eyedropper.svg'; + this.EYEDROPPER_PATH = "eyedropper.svg"; this.SERIALIZABLE = true; this.EDITABLE = true; } @@ -65,7 +65,7 @@ export class FieldColourSlider extends FieldColour { * @nocollapse */ static fromJson(options) { - return new FieldColourSlider(options['colour']); + return new FieldColourSlider(options["colour"]); } doValueUpdate_(newValue) { @@ -82,16 +82,26 @@ export class FieldColourSlider extends FieldColour { */ createColourStops_(channel) { var stops = []; - for(var n = 0; n <= 360; n += 20) { + for (var n = 0; n <= 360; n += 20) { switch (channel) { - case 'hue': - stops.push(Blockly.utils.colour.hsvToHex(n, this.saturation_, this.brightness_)); + case "hue": + stops.push( + Blockly.utils.colour.hsvToHex(n, this.saturation_, this.brightness_) + ); break; - case 'saturation': - stops.push(Blockly.utils.colour.hsvToHex(this.hue_, n / 360, this.brightness_)); + case "saturation": + stops.push( + Blockly.utils.colour.hsvToHex(this.hue_, n / 360, this.brightness_) + ); break; - case 'brightness': - stops.push(Blockly.utils.colour.hsvToHex(this.hue_, this.saturation_, 255 * n / 360)); + case "brightness": + stops.push( + Blockly.utils.colour.hsvToHex( + this.hue_, + this.saturation_, + (255 * n) / 360 + ) + ); break; default: throw new Error("Unknown channel for colour sliders: " + channel); @@ -107,8 +117,8 @@ export class FieldColourSlider extends FieldColour { * @private */ setGradient_(node, channel) { - var gradient = this.createColourStops_(channel).join(','); - node.style['background'] = `linear-gradient(to right, ${gradient})`; + var gradient = this.createColourStops_(channel).join(","); + node.style["background"] = `linear-gradient(to right, ${gradient})`; } /** @@ -118,14 +128,20 @@ export class FieldColourSlider extends FieldColour { updateDom_() { if (this.hueSlider_) { // Update the slider backgrounds - this.setGradient_(this.hueSlider_, 'hue'); - this.setGradient_(this.saturationSlider_, 'saturation'); - this.setGradient_(this.brightnessSlider_, 'brightness'); + this.setGradient_(this.hueSlider_, "hue"); + this.setGradient_(this.saturationSlider_, "saturation"); + this.setGradient_(this.brightnessSlider_, "brightness"); // Update the readouts - this.hueReadout_.textContent = Math.floor(100 * this.hue_ / 360).toFixed(0); - this.saturationReadout_.textContent = Math.floor(100 * this.saturation_).toFixed(0); - this.brightnessReadout_.textContent = Math.floor(100 * this.brightness_ / 255).toFixed(0); + this.hueReadout_.textContent = Math.floor( + (100 * this.hue_) / 360 + ).toFixed(0); + this.saturationReadout_.textContent = Math.floor( + 100 * this.saturation_ + ).toFixed(0); + this.brightnessReadout_.textContent = Math.floor( + (100 * this.brightness_) / 255 + ).toFixed(0); } } @@ -148,12 +164,12 @@ export class FieldColourSlider extends FieldColour { * @private */ createLabelDom_(labelText) { - var labelContainer = document.createElement('div'); - labelContainer.setAttribute('class', 'scratchColourPickerLabel'); - var readout = document.createElement('span'); - readout.setAttribute('class', 'scratchColourPickerReadout'); - var label = document.createElement('span'); - label.setAttribute('class', 'scratchColourPickerLabelText'); + var labelContainer = document.createElement("div"); + labelContainer.setAttribute("class", "scratchColourPickerLabel"); + var readout = document.createElement("span"); + readout.setAttribute("class", "scratchColourPickerReadout"); + var label = document.createElement("span"); + label.setAttribute("class", "scratchColourPickerLabelText"); label.textContent = labelText; labelContainer.appendChild(label); labelContainer.appendChild(readout); @@ -168,20 +184,24 @@ export class FieldColourSlider extends FieldColour { */ sliderCallbackFactory_(channel) { var thisField = this; - return function(event) { + return function (event) { var channelValue = event.target.value; switch (channel) { - case 'hue': + case "hue": thisField.hue_ = channelValue; break; - case 'saturation': + case "saturation": thisField.saturation_ = channelValue; break; - case 'brightness': + case "brightness": thisField.brightness_ = channelValue; break; } - var colour = Blockly.utils.colour.hsvToHex(thisField.hue_, thisField.saturation_, thisField.brightness_); + var colour = Blockly.utils.colour.hsvToHex( + thisField.hue_, + thisField.saturation_, + thisField.brightness_ + ); if (colour !== null) { thisField.setValue(colour, true); } @@ -194,10 +214,14 @@ export class FieldColourSlider extends FieldColour { */ activateEyedropperInternal_() { var thisField = this; - FieldColourSlider.activateEyedropper_(function(chosenColour) { + FieldColourSlider.activateEyedropper_(function (chosenColour) { // Update the internal hue/saturation/brightness values so sliders update. const components = Blockly.utils.colour.hexToRgb(chosenColour); - const {hue, saturation, value} = thisField.rgbToHsv(components[0], components[1], components[2]); + const { hue, saturation, value } = thisField.rgbToHsv( + components[0], + components[1], + components[2] + ); thisField.hue_ = hue; thisField.saturation_ = saturation; thisField.brightness_ = value; @@ -213,12 +237,16 @@ export class FieldColourSlider extends FieldColour { Blockly.DropDownDiv.hideWithoutAnimation(); Blockly.DropDownDiv.clearContent(); var div = Blockly.DropDownDiv.getContentDiv(); - div.className = 'scratchColourPicker'; + div.className = "scratchColourPicker"; // Init color component values that are used while the editor is open // in order to keep the slider values stable. const components = Blockly.utils.colour.hexToRgb(this.getValue()); - var {hue, saturation, value} = this.rgbToHsv(components[0], components[1], components[2]); + var { hue, saturation, value } = this.rgbToHsv( + components[0], + components[1], + components[2] + ); this.hue_ = hue; this.saturation_ = saturation; this.brightness_ = value; @@ -226,49 +254,55 @@ export class FieldColourSlider extends FieldColour { var hueElements = this.createLabelDom_(Blockly.Msg.COLOUR_HUE_LABEL); div.appendChild(hueElements[0]); this.hueReadout_ = hueElements[1]; - this.hueSlider_ = document.createElement('input'); - this.hueSlider_.type = 'range'; + this.hueSlider_ = document.createElement("input"); + this.hueSlider_.type = "range"; this.hueSlider_.min = 0; this.hueSlider_.max = 360; - this.hueSlider_.className = 'scratchColourSlider'; + this.hueSlider_.className = "scratchColourSlider"; div.appendChild(this.hueSlider_); - var saturationElements = - this.createLabelDom_(Blockly.Msg.COLOUR_SATURATION_LABEL); + var saturationElements = this.createLabelDom_( + Blockly.Msg.COLOUR_SATURATION_LABEL + ); div.appendChild(saturationElements[0]); this.saturationReadout_ = saturationElements[1]; - this.saturationSlider_ = document.createElement('input'); - this.saturationSlider_.type = 'range'; + this.saturationSlider_ = document.createElement("input"); + this.saturationSlider_.type = "range"; this.saturationSlider_.step = 0.001; this.saturationSlider_.min = 0; this.saturationSlider_.max = 1.0; - this.saturationSlider_.className = 'scratchColourSlider'; + this.saturationSlider_.className = "scratchColourSlider"; div.appendChild(this.saturationSlider_); - var brightnessElements = - this.createLabelDom_(Blockly.Msg.COLOUR_BRIGHTNESS_LABEL); + var brightnessElements = this.createLabelDom_( + Blockly.Msg.COLOUR_BRIGHTNESS_LABEL + ); div.appendChild(brightnessElements[0]); this.brightnessReadout_ = brightnessElements[1]; - this.brightnessSlider_ = document.createElement('input'); - this.brightnessSlider_.type = 'range'; + this.brightnessSlider_ = document.createElement("input"); + this.brightnessSlider_.type = "range"; this.brightnessSlider_.min = 0; this.brightnessSlider_.max = 255; - this.brightnessSlider_.className = 'scratchColourSlider'; + this.brightnessSlider_.className = "scratchColourSlider"; div.appendChild(this.brightnessSlider_); if (FieldColourSlider.activateEyedropper_) { - var button = document.createElement('button'); - button.setAttribute('class', 'scratchEyedropper'); - var image = document.createElement('img'); - image.src = Blockly.getMainWorkspace().options.pathToMedia + this.EYEDROPPER_PATH; + var button = document.createElement("button"); + button.setAttribute("class", "scratchEyedropper"); + var image = document.createElement("img"); + image.src = + Blockly.getMainWorkspace().options.pathToMedia + this.EYEDROPPER_PATH; button.appendChild(image); div.appendChild(button); - this.eyedropperEventData_ = - Blockly.browserEvents.conditionalBind(button, 'click', this, - this.activateEyedropperInternal_); + this.eyedropperEventData_ = Blockly.browserEvents.conditionalBind( + button, + "click", + this, + this.activateEyedropperInternal_ + ); } - Blockly.DropDownDiv.setColour('#ffffff', '#dddddd'); + Blockly.DropDownDiv.setColour("#ffffff", "#dddddd"); Blockly.DropDownDiv.showPositionedByBlock(this, this.sourceBlock_); // Set value updates the slider positions @@ -276,11 +310,23 @@ export class FieldColourSlider extends FieldColour { this.setValue(this.getValue()); this.hueChangeEventKey_ = Blockly.browserEvents.bind( - this.hueSlider_, 'input', this, this.sliderCallbackFactory_('hue')); + this.hueSlider_, + "input", + this, + this.sliderCallbackFactory_("hue") + ); this.saturationChangeEventKey_ = Blockly.browserEvents.bind( - this.saturationSlider_, 'input', this, this.sliderCallbackFactory_('saturation')); + this.saturationSlider_, + "input", + this, + this.sliderCallbackFactory_("saturation") + ); this.brightnessChangeEventKey_ = Blockly.browserEvents.bind( - this.brightnessSlider_, 'input', this, this.sliderCallbackFactory_('brightness')); + this.brightnessSlider_, + "input", + this, + this.sliderCallbackFactory_("brightness") + ); } dispose() { @@ -311,15 +357,15 @@ export class FieldColourSlider extends FieldColour { hue = 0; saturation = 0; } else { - const delta = (max - min); + const delta = max - min; saturation = delta / max; if (red == max) { hue = (green - blue) / delta; } else if (green == max) { - hue = 2 + ((blue - red) / delta); + hue = 2 + (blue - red) / delta; } else { - hue = 4 + ((red - green) / delta); + hue = 4 + (red - green) / delta; } hue *= 60; if (hue < 0) { @@ -330,8 +376,8 @@ export class FieldColourSlider extends FieldColour { } } - return {hue, saturation, value}; + return { hue, saturation, value }; } } -Blockly.fieldRegistry.register('field_colour_slider', FieldColourSlider); +Blockly.fieldRegistry.register("field_colour_slider", FieldColourSlider); diff --git a/core/field_matrix.js b/src/fields/field_matrix.js similarity index 61% rename from core/field_matrix.js rename to src/fields/field_matrix.js index af4d912f38..71955614ca 100644 --- a/core/field_matrix.js +++ b/src/fields/field_matrix.js @@ -23,7 +23,7 @@ * Displays an editable 5x5 matrix for controlling LED arrays. * @author khanning@gmail.com (Kreg Hanning) */ -import * as Blockly from 'blockly/core'; +import * as Blockly from "blockly/core"; /** * Class for a matrix field. @@ -119,7 +119,7 @@ export class FieldMatrix extends Blockly.Field { * @nocollapse */ static fromJson(options) { - return new FieldMatrix(options['matrix']); + return new FieldMatrix(options["matrix"]); } /** @@ -177,7 +177,7 @@ export class FieldMatrix extends Blockly.Field { * @type {string} * @const */ - static ZEROS = '0000000000000000000000000'; + static ZEROS = "0000000000000000000000000"; /** * String with 25 '1' chars. @@ -185,7 +185,7 @@ export class FieldMatrix extends Blockly.Field { * @type {string} * @const */ - static ONES = '1111111111111111111111111'; + static ONES = "1111111111111111111111111"; /** * Called when the field is placed on a block. @@ -197,47 +197,61 @@ export class FieldMatrix extends Blockly.Field { const dropdownArrowPadding = this.getConstants().GRID_UNIT * 2; var thumbX = dropdownArrowPadding / 2; var thumbY = (this.size_.height - FieldMatrix.THUMBNAIL_SIZE) / 2; - var thumbnail = Blockly.utils.dom.createSvgElement('g', { - 'transform': 'translate(' + thumbX + ', ' + thumbY + ')', - 'pointer-events': 'bounding-box', 'cursor': 'pointer' - }, this.fieldGroup_); + var thumbnail = Blockly.utils.dom.createSvgElement( + "g", + { + transform: "translate(" + thumbX + ", " + thumbY + ")", + "pointer-events": "bounding-box", + cursor: "pointer", + }, + this.fieldGroup_ + ); this.ledThumbNodes_ = []; var nodeSize = FieldMatrix.THUMBNAIL_NODE_SIZE; var nodePad = FieldMatrix.THUMBNAIL_NODE_PAD; for (var i = 0; i < 5; i++) { for (var n = 0; n < 5; n++) { var attr = { - 'x': ((nodeSize + nodePad) * n) + nodePad, - 'y': ((nodeSize + nodePad) * i) + nodePad, - 'width': nodeSize, 'height': nodeSize, - 'rx': nodePad, 'ry': nodePad + x: (nodeSize + nodePad) * n + nodePad, + y: (nodeSize + nodePad) * i + nodePad, + width: nodeSize, + height: nodeSize, + rx: nodePad, + ry: nodePad, }; this.ledThumbNodes_.push( - Blockly.utils.dom.createSvgElement('rect', attr, thumbnail) + Blockly.utils.dom.createSvgElement("rect", attr, thumbnail) ); } - thumbnail.style.cursor = 'default'; + thumbnail.style.cursor = "default"; this.updateMatrix_(); } if (!this.arrow_) { - var arrowX = FieldMatrix.THUMBNAIL_SIZE + - dropdownArrowPadding * 1.5; + var arrowX = FieldMatrix.THUMBNAIL_SIZE + dropdownArrowPadding * 1.5; var arrowY = (this.size_.height - FieldMatrix.ARROW_SIZE) / 2; - this.arrow_ = Blockly.utils.dom.createSvgElement('image', { - 'height': FieldMatrix.ARROW_SIZE + 'px', - 'width': FieldMatrix.ARROW_SIZE + 'px', - 'transform': 'translate(' + arrowX + ', ' + arrowY + ')' - }, this.fieldGroup_); - this.arrow_.setAttributeNS('http://www.w3.org/1999/xlink', - 'xlink:href', Blockly.getMainWorkspace().options.pathToMedia + - 'dropdown-arrow.svg'); - this.arrow_.style.cursor = 'default'; + this.arrow_ = Blockly.utils.dom.createSvgElement( + "image", + { + height: FieldMatrix.ARROW_SIZE + "px", + width: FieldMatrix.ARROW_SIZE + "px", + transform: "translate(" + arrowX + ", " + arrowY + ")", + }, + this.fieldGroup_ + ); + this.arrow_.setAttributeNS( + "http://www.w3.org/1999/xlink", + "xlink:href", + Blockly.getMainWorkspace().options.pathToMedia + "dropdown-arrow.svg" + ); + this.arrow_.style.cursor = "default"; } } doClassValidation_(matrix) { - return matrix ? matrix + FieldMatrix.ZEROS.substr(0, 25 - matrix.length) : matrix; + return matrix + ? matrix + FieldMatrix.ZEROS.substr(0, 25 - matrix.length) + : matrix; } doValueUpdate_(newValue) { @@ -254,63 +268,90 @@ export class FieldMatrix extends Blockly.Field { showEditor_() { var div = Blockly.DropDownDiv.getContentDiv(); // Build the SVG DOM. - var matrixSize = (FieldMatrix.MATRIX_NODE_SIZE * 5) + - (FieldMatrix.MATRIX_NODE_PAD * 6); - this.matrixStage_ = Blockly.utils.dom.createSvgElement('svg', { - 'xmlns': 'http://www.w3.org/2000/svg', - 'xmlns:html': 'http://www.w3.org/1999/xhtml', - 'xmlns:xlink': 'http://www.w3.org/1999/xlink', - 'version': '1.1', - 'height': matrixSize + 'px', - 'width': matrixSize + 'px' - }, div); + var matrixSize = + FieldMatrix.MATRIX_NODE_SIZE * 5 + FieldMatrix.MATRIX_NODE_PAD * 6; + this.matrixStage_ = Blockly.utils.dom.createSvgElement( + "svg", + { + xmlns: "http://www.w3.org/2000/svg", + "xmlns:html": "http://www.w3.org/1999/xhtml", + "xmlns:xlink": "http://www.w3.org/1999/xlink", + version: "1.1", + height: matrixSize + "px", + width: matrixSize + "px", + }, + div + ); // Create the 5x5 matrix this.ledButtons_ = []; for (var i = 0; i < 5; i++) { for (var n = 0; n < 5; n++) { - var x = (FieldMatrix.MATRIX_NODE_SIZE * n) + - (FieldMatrix.MATRIX_NODE_PAD * (n + 1)); - var y = (FieldMatrix.MATRIX_NODE_SIZE * i) + - (FieldMatrix.MATRIX_NODE_PAD * (i + 1)); + var x = + FieldMatrix.MATRIX_NODE_SIZE * n + + FieldMatrix.MATRIX_NODE_PAD * (n + 1); + var y = + FieldMatrix.MATRIX_NODE_SIZE * i + + FieldMatrix.MATRIX_NODE_PAD * (i + 1); var attr = { - 'x': x + 'px', 'y': y + 'px', - 'width': FieldMatrix.MATRIX_NODE_SIZE, - 'height': FieldMatrix.MATRIX_NODE_SIZE, - 'rx': FieldMatrix.MATRIX_NODE_RADIUS, - 'ry': FieldMatrix.MATRIX_NODE_RADIUS + x: x + "px", + y: y + "px", + width: FieldMatrix.MATRIX_NODE_SIZE, + height: FieldMatrix.MATRIX_NODE_SIZE, + rx: FieldMatrix.MATRIX_NODE_RADIUS, + ry: FieldMatrix.MATRIX_NODE_RADIUS, }; - var led = Blockly.utils.dom.createSvgElement('rect', attr, this.matrixStage_); + var led = Blockly.utils.dom.createSvgElement( + "rect", + attr, + this.matrixStage_ + ); this.matrixStage_.appendChild(led); this.ledButtons_.push(led); } } // Div for lower button menu - var buttonDiv = document.createElement('div'); + var buttonDiv = document.createElement("div"); // Button to clear matrix - var clearButtonDiv = document.createElement('div'); - clearButtonDiv.className = 'scratchMatrixButtonDiv'; - var clearButton = this.createButton_(this.sourceBlock_.getColourSecondary()); + var clearButtonDiv = document.createElement("div"); + clearButtonDiv.className = "scratchMatrixButtonDiv"; + var clearButton = this.createButton_( + this.sourceBlock_.getColourSecondary() + ); clearButtonDiv.appendChild(clearButton); // Button to fill matrix - var fillButtonDiv = document.createElement('div'); - fillButtonDiv.className = 'scratchMatrixButtonDiv'; - var fillButton = this.createButton_('#FFFFFF'); + var fillButtonDiv = document.createElement("div"); + fillButtonDiv.className = "scratchMatrixButtonDiv"; + var fillButton = this.createButton_("#FFFFFF"); fillButtonDiv.appendChild(fillButton); buttonDiv.appendChild(clearButtonDiv); buttonDiv.appendChild(fillButtonDiv); div.appendChild(buttonDiv); - Blockly.DropDownDiv.setColour(this.sourceBlock_.getColour(), - this.sourceBlock_.getColourTertiary()); + Blockly.DropDownDiv.setColour( + this.sourceBlock_.getColour(), + this.sourceBlock_.getColourTertiary() + ); Blockly.DropDownDiv.showPositionedByBlock(this, this.sourceBlock_); - this.matrixTouchWrapper_ = - Blockly.browserEvents.bind(this.matrixStage_, 'mousedown', this, this.onMouseDown); - this.clearButtonWrapper_ = - Blockly.browserEvents.bind(clearButton, 'click', this, this.clearMatrix_); - this.fillButtonWrapper_ = - Blockly.browserEvents.bind(fillButton, 'click', this, this.fillMatrix_); + this.matrixTouchWrapper_ = Blockly.browserEvents.bind( + this.matrixStage_, + "mousedown", + this, + this.onMouseDown + ); + this.clearButtonWrapper_ = Blockly.browserEvents.bind( + clearButton, + "click", + this, + this.clearMatrix_ + ); + this.fillButtonWrapper_ = Blockly.browserEvents.bind( + fillButton, + "click", + this, + this.fillMatrix_ + ); // Update the matrix for the current value this.updateMatrix_(); @@ -322,25 +363,31 @@ export class FieldMatrix extends Blockly.Field { * @return {SvgElement} The button svg element. */ createButton_(fill) { - var button = Blockly.utils.dom.createSvgElement('svg', { - 'xmlns': 'http://www.w3.org/2000/svg', - 'xmlns:html': 'http://www.w3.org/1999/xhtml', - 'xmlns:xlink': 'http://www.w3.org/1999/xlink', - 'version': '1.1', - 'height': FieldMatrix.MATRIX_NODE_SIZE + 'px', - 'width': FieldMatrix.MATRIX_NODE_SIZE + 'px' + var button = Blockly.utils.dom.createSvgElement("svg", { + xmlns: "http://www.w3.org/2000/svg", + "xmlns:html": "http://www.w3.org/1999/xhtml", + "xmlns:xlink": "http://www.w3.org/1999/xlink", + version: "1.1", + height: FieldMatrix.MATRIX_NODE_SIZE + "px", + width: FieldMatrix.MATRIX_NODE_SIZE + "px", }); var nodeSize = FieldMatrix.MATRIX_NODE_SIZE / 4; var nodePad = FieldMatrix.MATRIX_NODE_SIZE / 16; for (var i = 0; i < 3; i++) { for (var n = 0; n < 3; n++) { - Blockly.utils.dom.createSvgElement('rect', { - 'x': ((nodeSize + nodePad) * n) + nodePad, - 'y': ((nodeSize + nodePad) * i) + nodePad, - 'width': nodeSize, 'height': nodeSize, - 'rx': nodePad, 'ry': nodePad, - 'fill': fill - }, button); + Blockly.utils.dom.createSvgElement( + "rect", + { + x: (nodeSize + nodePad) * n + nodePad, + y: (nodeSize + nodePad) * i + nodePad, + width: nodeSize, + height: nodeSize, + rx: nodePad, + ry: nodePad, + fill: fill, + }, + button + ); } } return button; @@ -353,12 +400,20 @@ export class FieldMatrix extends Blockly.Field { updateMatrix_() { const matrix = this.getValue(); for (var i = 0; i < matrix.length; i++) { - if (matrix[i] === '0') { - this.fillMatrixNode_(this.ledButtons_, i, this.sourceBlock_.getColourSecondary()); - this.fillMatrixNode_(this.ledThumbNodes_, i, this.sourceBlock_.getColour()); + if (matrix[i] === "0") { + this.fillMatrixNode_( + this.ledButtons_, + i, + this.sourceBlock_.getColourSecondary() + ); + this.fillMatrixNode_( + this.ledThumbNodes_, + i, + this.sourceBlock_.getColour() + ); } else { - this.fillMatrixNode_(this.ledButtons_, i, '#FFFFFF'); - this.fillMatrixNode_(this.ledThumbNodes_, i, '#FFFFFF'); + this.fillMatrixNode_(this.ledButtons_, i, "#FFFFFF"); + this.fillMatrixNode_(this.ledThumbNodes_, i, "#FFFFFF"); } } } @@ -389,32 +444,33 @@ export class FieldMatrix extends Blockly.Field { */ fillMatrixNode_(node, index, fill) { if (!node || !node[index] || !fill) return; - node[index].setAttribute('fill', fill); + node[index].setAttribute("fill", fill); } setLEDNode_(led, state) { if (led < 0 || led > 24) return; const oldMatrix = this.getValue(); - const newMatrix = oldMatrix.substr(0, led) + state + oldMatrix.substr(led + 1); + const newMatrix = + oldMatrix.substr(0, led) + state + oldMatrix.substr(led + 1); this.setValue(newMatrix); } fillLEDNode_(led) { if (led < 0 || led > 24) return; - this.setLEDNode_(led, '1'); + this.setLEDNode_(led, "1"); } clearLEDNode_(led) { if (led < 0 || led > 24) return; - this.setLEDNode_(led, '0'); + this.setLEDNode_(led, "0"); } toggleLEDNode_(led) { if (led < 0 || led > 24) return; - if (this.getValue().charAt(led) === '0') { - this.setLEDNode_(led, '1'); + if (this.getValue().charAt(led) === "0") { + this.setLEDNode_(led, "1"); } else { - this.setLEDNode_(led, '0'); + this.setLEDNode_(led, "0"); } } @@ -423,16 +479,24 @@ export class FieldMatrix extends Blockly.Field { * @param {!Event} e Mouse event. */ onMouseDown(e) { - this.matrixMoveWrapper_ = - Blockly.browserEvents.bind(document.body, 'mousemove', this, this.onMouseMove); - this.matrixReleaseWrapper_ = - Blockly.browserEvents.bind(document.body, 'mouseup', this, this.onMouseUp); + this.matrixMoveWrapper_ = Blockly.browserEvents.bind( + document.body, + "mousemove", + this, + this.onMouseMove + ); + this.matrixReleaseWrapper_ = Blockly.browserEvents.bind( + document.body, + "mouseup", + this, + this.onMouseUp + ); var ledHit = this.checkForLED_(e); if (ledHit > -1) { - if (this.getValue().charAt(ledHit) === '0') { - this.paintStyle_ = 'fill'; + if (this.getValue().charAt(ledHit) === "0") { + this.paintStyle_ = "fill"; } else { - this.paintStyle_ = 'clear'; + this.paintStyle_ = "clear"; } this.toggleLEDNode_(ledHit); this.updateMatrix_(); @@ -462,9 +526,9 @@ export class FieldMatrix extends Blockly.Field { if (this.paintStyle_) { var led = this.checkForLED_(e); if (led < 0) return; - if (this.paintStyle_ === 'clear') { + if (this.paintStyle_ === "clear") { this.clearLEDNode_(led); - } else if (this.paintStyle_ === 'fill') { + } else if (this.paintStyle_ === "fill") { this.fillLEDNode_(led); } } @@ -482,13 +546,13 @@ export class FieldMatrix extends Blockly.Field { var dx = e.clientX - bBox.left; var dy = e.clientY - bBox.top; var min = nodePad / 2; - var max = bBox.width - (nodePad / 2); + var max = bBox.width - nodePad / 2; if (dx < min || dx > max || dy < min || dy > max) { return -1; } var xDiv = Math.trunc((dx - nodePad / 2) / (nodeSize + nodePad)); var yDiv = Math.trunc((dy - nodePad / 2) / (nodeSize + nodePad)); - return xDiv + (yDiv * nodePad); + return xDiv + yDiv * nodePad; } /** @@ -497,26 +561,26 @@ export class FieldMatrix extends Blockly.Field { * @private */ dispose() { - super.dispose(); - this.matrixStage_ = null; - if (this.mouseDownWrapper_) { - Blockly.browserEvents.unbind(this.mouseDownWrapper_); - } - if (this.matrixTouchWrapper_) { - Blockly.browserEvents.unbind(this.matrixTouchWrapper_); - } - if (this.matrixReleaseWrapper_) { - Blockly.browserEvents.unbind(this.matrixReleaseWrapper_); - } - if (this.matrixMoveWrapper_) { - Blockly.browserEvents.unbind(this.matrixMoveWrapper_); - } - if (this.clearButtonWrapper_) { - Blockly.browserEvents.unbind(this.clearButtonWrapper_); - } - if (this.fillButtonWrapper_) { - Blockly.browserEvents.unbind(this.fillButtonWrapper_); - } + super.dispose(); + this.matrixStage_ = null; + if (this.mouseDownWrapper_) { + Blockly.browserEvents.unbind(this.mouseDownWrapper_); + } + if (this.matrixTouchWrapper_) { + Blockly.browserEvents.unbind(this.matrixTouchWrapper_); + } + if (this.matrixReleaseWrapper_) { + Blockly.browserEvents.unbind(this.matrixReleaseWrapper_); + } + if (this.matrixMoveWrapper_) { + Blockly.browserEvents.unbind(this.matrixMoveWrapper_); + } + if (this.clearButtonWrapper_) { + Blockly.browserEvents.unbind(this.clearButtonWrapper_); + } + if (this.fillButtonWrapper_) { + Blockly.browserEvents.unbind(this.fillButtonWrapper_); + } } updateSize_(margin) { @@ -524,8 +588,10 @@ export class FieldMatrix extends Blockly.Field { let totalHeight = constants.FIELD_TEXT_HEIGHT; this.size_.height = totalHeight; - this.size_.width = FieldMatrix.THUMBNAIL_SIZE + - FieldMatrix.ARROW_SIZE + (constants.GRID_UNIT * 2 * 1.5); + this.size_.width = + FieldMatrix.THUMBNAIL_SIZE + + FieldMatrix.ARROW_SIZE + + constants.GRID_UNIT * 2 * 1.5; this.positionBorderRect_(); } @@ -535,4 +601,4 @@ export class FieldMatrix extends Blockly.Field { } } -Blockly.fieldRegistry.register('field_matrix', FieldMatrix); +Blockly.fieldRegistry.register("field_matrix", FieldMatrix); diff --git a/core/field_note.js b/src/fields/field_note.js similarity index 67% rename from core/field_note.js rename to src/fields/field_note.js index b2b51a3960..20de842164 100644 --- a/core/field_note.js +++ b/src/fields/field_note.js @@ -22,7 +22,7 @@ * @fileoverview Note input field, for selecting a musical note on a piano. * @author ericr@media.mit.edu (Eric Rosenbaum) */ -import * as Blockly from 'blockly/core'; +import * as Blockly from "blockly/core"; /** * Class for a note input field, for selecting a musical note on a piano. @@ -37,7 +37,7 @@ import * as Blockly from 'blockly/core'; */ export class FieldNote extends Blockly.FieldTextInput { constructor(opt_value, opt_validator) { - opt_value = (opt_value && !isNaN(opt_value)) ? String(opt_value) : '0'; + opt_value = opt_value && !isNaN(opt_value) ? String(opt_value) : "0"; super(opt_value, opt_validator); /** @@ -188,42 +188,42 @@ export class FieldNote extends Blockly.FieldTextInput { * @type {string} * @const */ - static SHADOW_COLOR = '#000'; + static SHADOW_COLOR = "#000"; /** * Opacity for the shadow on the piano. * @type {string} * @const */ - static SHADOW_OPACITY = .2; + static SHADOW_OPACITY = 0.2; /** * A color for the white piano keys. * @type {string} * @const */ - static WHITE_KEY_COLOR = '#FFFFFF'; + static WHITE_KEY_COLOR = "#FFFFFF"; /** * A color for the black piano keys. * @type {string} * @const */ - static BLACK_KEY_COLOR = '#323133'; + static BLACK_KEY_COLOR = "#323133"; /** * A color for stroke around black piano keys. * @type {string} * @const */ - static BLACK_KEY_STROKE = '#555555'; + static BLACK_KEY_STROKE = "#555555"; /** * A color for the selected state of a piano key. * @type {string} * @const */ - static KEY_SELECTED_COLOR = '#b0d6ff'; + static KEY_SELECTED_COLOR = "#b0d6ff"; /** * The number of white keys in one octave on the piano. @@ -280,19 +280,19 @@ export class FieldNote extends Blockly.FieldTextInput { * @const */ static KEY_INFO = [ - {name: 'C', pitch: 0}, - {name: 'C♯', pitch: 1, isBlack: true}, - {name: 'D', pitch: 2}, - {name: 'E♭', pitch: 3, isBlack: true}, - {name: 'E', pitch: 4}, - {name: 'F', pitch: 5}, - {name: 'F♯', pitch: 6, isBlack: true}, - {name: 'G', pitch: 7}, - {name: 'G♯', pitch: 8, isBlack: true}, - {name: 'A', pitch: 9}, - {name: 'B♭', pitch: 10, isBlack: true}, - {name: 'B', pitch: 11}, - {name: 'C', pitch: 12} + { name: "C", pitch: 0 }, + { name: "C♯", pitch: 1, isBlack: true }, + { name: "D", pitch: 2 }, + { name: "E♭", pitch: 3, isBlack: true }, + { name: "E", pitch: 4 }, + { name: "F", pitch: 5 }, + { name: "F♯", pitch: 6, isBlack: true }, + { name: "G", pitch: 7 }, + { name: "G♯", pitch: 8, isBlack: true }, + { name: "A", pitch: 9 }, + { name: "B♭", pitch: 10, isBlack: true }, + { name: "B", pitch: 11 }, + { name: "C", pitch: 12 }, ]; /** @@ -315,7 +315,7 @@ export class FieldNote extends Blockly.FieldTextInput { * @type {string} * @const */ - static ARROW_SVG_PATH = 'icons/arrow_button.svg'; + static ARROW_SVG_PATH = "icons/arrow_button.svg"; /** * The size of the square octave buttons. @@ -332,7 +332,7 @@ export class FieldNote extends Blockly.FieldTextInput { * @nocollapse */ static fromJson(options) { - return new FieldNote(options['note']); + return new FieldNote(options["note"]); } /** @@ -342,10 +342,10 @@ export class FieldNote extends Blockly.FieldTextInput { */ dispose() { super.dispose(); - this.mouseDownWrappers_.forEach(function(wrapper) { + this.mouseDownWrappers_.forEach(function (wrapper) { Blockly.browserEvents.unbind(wrapper); }); - this.mouseEnterWrappers_.forEach(function(wrapper) { + this.mouseEnterWrappers_.forEach(function (wrapper) { Blockly.browserEvents.unbind(wrapper); }); if (this.mouseUpWrapper_) { @@ -374,91 +374,136 @@ export class FieldNote extends Blockly.FieldTextInput { // Build the SVG DOM. var div = Blockly.DropDownDiv.getContentDiv(); - this.fieldEditorWidth_ = FieldNote.NUM_WHITE_KEYS * FieldNote.WHITE_KEY_WIDTH + + this.fieldEditorWidth_ = + FieldNote.NUM_WHITE_KEYS * FieldNote.WHITE_KEY_WIDTH + FieldNote.EDGE_PADDING; - this.fieldEditorHeight_ = FieldNote.TOP_MENU_HEIGHT + + this.fieldEditorHeight_ = + FieldNote.TOP_MENU_HEIGHT + FieldNote.WHITE_KEY_HEIGHT + FieldNote.EDGE_PADDING; - var svg = Blockly.utils.dom.createSvgElement('svg', { - 'xmlns': 'http://www.w3.org/2000/svg', - 'xmlns:html': 'http://www.w3.org/1999/xhtml', - 'xmlns:xlink': 'http://www.w3.org/1999/xlink', - 'version': '1.1', - 'height': this.fieldEditorHeight_ + 'px', - 'width': this.fieldEditorWidth_ + 'px' - }, div); + var svg = Blockly.utils.dom.createSvgElement( + "svg", + { + xmlns: "http://www.w3.org/2000/svg", + "xmlns:html": "http://www.w3.org/1999/xhtml", + "xmlns:xlink": "http://www.w3.org/1999/xlink", + version: "1.1", + height: this.fieldEditorHeight_ + "px", + width: this.fieldEditorWidth_ + "px", + }, + div + ); // Add the white and black keys // Since we are adding the keys from left to right in order, they need // to be in two groups in order to layer correctly. - this.pianoSVG_ = Blockly.utils.dom.createSvgElement('g', {}, svg); - var whiteKeyGroup = Blockly.utils.dom.createSvgElement('g', {}, this.pianoSVG_); - var blackKeyGroup = Blockly.utils.dom.createSvgElement('g', {}, this.pianoSVG_); + this.pianoSVG_ = Blockly.utils.dom.createSvgElement("g", {}, svg); + var whiteKeyGroup = Blockly.utils.dom.createSvgElement( + "g", + {}, + this.pianoSVG_ + ); + var blackKeyGroup = Blockly.utils.dom.createSvgElement( + "g", + {}, + this.pianoSVG_ + ); // Add three piano octaves, so we can animate moving up or down an octave. // Only the middle octave gets bound to events. this.keySVGs_ = []; - this.addPianoOctave_(-this.fieldEditorWidth_ + FieldNote.EDGE_PADDING, - whiteKeyGroup, blackKeyGroup, null); + this.addPianoOctave_( + -this.fieldEditorWidth_ + FieldNote.EDGE_PADDING, + whiteKeyGroup, + blackKeyGroup, + null + ); this.addPianoOctave_(0, whiteKeyGroup, blackKeyGroup, this.keySVGs_); - this.addPianoOctave_(this.fieldEditorWidth_ - FieldNote.EDGE_PADDING, - whiteKeyGroup, blackKeyGroup, null); + this.addPianoOctave_( + this.fieldEditorWidth_ - FieldNote.EDGE_PADDING, + whiteKeyGroup, + blackKeyGroup, + null + ); // Note name indicator at the top of the field - this.noteNameText_ = Blockly.utils.dom.createSvgElement('text', - { - 'x': this.fieldEditorWidth_ / 2, - 'y': FieldNote.TOP_MENU_HEIGHT / 2, - 'class': 'blocklyText', - 'text-anchor': 'middle', - 'dominant-baseline': 'middle', - }, svg); + this.noteNameText_ = Blockly.utils.dom.createSvgElement( + "text", + { + x: this.fieldEditorWidth_ / 2, + y: FieldNote.TOP_MENU_HEIGHT / 2, + class: "blocklyText", + "text-anchor": "middle", + "dominant-baseline": "middle", + }, + svg + ); // Note names on the low and high C keys var lowCX = FieldNote.WHITE_KEY_WIDTH / 2; this.lowCText_ = this.addCKeyLabel_(lowCX, svg); - var highCX = lowCX + (FieldNote.WHITE_KEY_WIDTH * - (FieldNote.NUM_WHITE_KEYS - 1)); + var highCX = + lowCX + FieldNote.WHITE_KEY_WIDTH * (FieldNote.NUM_WHITE_KEYS - 1); this.highCText_ = this.addCKeyLabel_(highCX, svg); // Horizontal line at the top of the keys - Blockly.utils.dom.createSvgElement('line', - { - 'stroke': this.sourceBlock_.parentBlock_.getColourTertiary(), - 'x1': 0, - 'y1': FieldNote.TOP_MENU_HEIGHT, - 'x2': this.fieldEditorWidth_, - 'y2': FieldNote.TOP_MENU_HEIGHT - }, svg); + Blockly.utils.dom.createSvgElement( + "line", + { + stroke: this.sourceBlock_.parentBlock_.getColourTertiary(), + x1: 0, + y1: FieldNote.TOP_MENU_HEIGHT, + x2: this.fieldEditorWidth_, + y2: FieldNote.TOP_MENU_HEIGHT, + }, + svg + ); // Drop shadow at the top of the keys - Blockly.utils.dom.createSvgElement('rect', - { - 'x': 0, - 'y': FieldNote.TOP_MENU_HEIGHT, - 'width': this.fieldEditorWidth_, - 'height': FieldNote.SHADOW_HEIGHT, - 'fill': FieldNote.SHADOW_COLOR, - 'fill-opacity': FieldNote.SHADOW_OPACITY - }, svg); + Blockly.utils.dom.createSvgElement( + "rect", + { + x: 0, + y: FieldNote.TOP_MENU_HEIGHT, + width: this.fieldEditorWidth_, + height: FieldNote.SHADOW_HEIGHT, + fill: FieldNote.SHADOW_COLOR, + "fill-opacity": FieldNote.SHADOW_OPACITY, + }, + svg + ); // Octave buttons this.octaveDownButton = this.addOctaveButton_(0, true, svg); this.octaveUpButton = this.addOctaveButton_( - (this.fieldEditorWidth_ + FieldNote.INSET * 2) - - FieldNote.OCTAVE_BUTTON_SIZE, false, svg); + this.fieldEditorWidth_ + + FieldNote.INSET * 2 - + FieldNote.OCTAVE_BUTTON_SIZE, + false, + svg + ); - this.octaveDownMouseDownWrapper_ = - Blockly.browserEvents.bind(this.octaveDownButton, 'mousedown', this, function() { + this.octaveDownMouseDownWrapper_ = Blockly.browserEvents.bind( + this.octaveDownButton, + "mousedown", + this, + function () { this.changeOctaveBy_(-1); - }); - this.octaveUpMouseDownWrapper_ = - Blockly.browserEvents.bind(this.octaveUpButton, 'mousedown', this,function() { - this.changeOctaveBy_(1); - }); - Blockly.DropDownDiv.setColour(this.sourceBlock_.parentBlock_.getColour(), - this.sourceBlock_.parentBlock_.getColourTertiary()); + } + ); + this.octaveUpMouseDownWrapper_ = Blockly.browserEvents.bind( + this.octaveUpButton, + "mousedown", + this, + function () { + this.changeOctaveBy_(1); + } + ); + Blockly.DropDownDiv.setColour( + this.sourceBlock_.parentBlock_.getColour(), + this.sourceBlock_.parentBlock_.getColourTertiary() + ); Blockly.DropDownDiv.showPositionedByBlock(this, this.sourceBlock_); this.updateSelection_(); @@ -496,24 +541,32 @@ export class FieldNote extends Blockly.FieldTextInput { group = whiteKeyGroup; } var attr = { - 'd': this.getPianoKeyPath_(x, y, width, height), - 'fill': fill, - 'stroke': stroke + d: this.getPianoKeyPath_(x, y, width, height), + fill: fill, + stroke: stroke, }; x += xIncrement; - var keySVG = Blockly.utils.dom.createSvgElement('path', attr, group); + var keySVG = Blockly.utils.dom.createSvgElement("path", attr, group); if (keySVGarray) { keySVGarray[i] = keySVG; - keySVG.setAttribute('data-pitch', FieldNote.KEY_INFO[i].pitch); - keySVG.setAttribute('data-name', FieldNote.KEY_INFO[i].name); - keySVG.setAttribute('data-isBlack', FieldNote.KEY_INFO[i].isBlack); - - this.mouseDownWrappers_[i] = - Blockly.browserEvents.bind(keySVG, 'mousedown', this, this.onMouseDownOnKey_); - this.mouseEnterWrappers_[i] = - Blockly.browserEvents.bind(keySVG, 'mouseenter', this, this.onMouseEnter_); + keySVG.setAttribute("data-pitch", FieldNote.KEY_INFO[i].pitch); + keySVG.setAttribute("data-name", FieldNote.KEY_INFO[i].name); + keySVG.setAttribute("data-isBlack", FieldNote.KEY_INFO[i].isBlack); + + this.mouseDownWrappers_[i] = Blockly.browserEvents.bind( + keySVG, + "mousedown", + this, + this.onMouseDownOnKey_ + ); + this.mouseEnterWrappers_[i] = Blockly.browserEvents.bind( + keySVG, + "mouseenter", + this, + this.onMouseEnter_ + ); } } } @@ -529,15 +582,50 @@ export class FieldNote extends Blockly.FieldTextInput { * @private */ getPianoKeyPath_(x, y, width, height) { - return 'M' + x + ' ' + y + ' ' + - 'L' + x + ' ' + (y + height - FieldNote.KEY_RADIUS) + ' ' + - 'Q' + x + ' ' + (y + height) + ' ' + - (x + FieldNote.KEY_RADIUS) + ' ' + (y + height) + ' ' + - 'L' + (x + width - FieldNote.KEY_RADIUS) + ' ' + (y + height) + ' ' + - 'Q' + (x + width) + ' ' + (y + height) + ' ' + - (x + width) + ' ' + (y + height - FieldNote.KEY_RADIUS) + ' ' + - 'L' + (x + width) + ' ' + y + ' ' + - 'L' + x + ' ' + y; + return ( + "M" + + x + + " " + + y + + " " + + "L" + + x + + " " + + (y + height - FieldNote.KEY_RADIUS) + + " " + + "Q" + + x + + " " + + (y + height) + + " " + + (x + FieldNote.KEY_RADIUS) + + " " + + (y + height) + + " " + + "L" + + (x + width - FieldNote.KEY_RADIUS) + + " " + + (y + height) + + " " + + "Q" + + (x + width) + + " " + + (y + height) + + " " + + (x + width) + + " " + + (y + height - FieldNote.KEY_RADIUS) + + " " + + "L" + + (x + width) + + " " + + y + + " " + + "L" + + x + + " " + + y + ); } /** @@ -549,32 +637,40 @@ export class FieldNote extends Blockly.FieldTextInput { * @private */ addOctaveButton_(x, flipped, svg) { - var group = Blockly.utils.dom.createSvgElement('g', {}, svg); + var group = Blockly.utils.dom.createSvgElement("g", {}, svg); var imageSize = FieldNote.OCTAVE_BUTTON_SIZE; - var arrow = Blockly.utils.dom.createSvgElement('image', - { - 'width': imageSize, - 'height': imageSize, - 'x': x - FieldNote.INSET, - 'y': -1 * FieldNote.INSET - }, group); + var arrow = Blockly.utils.dom.createSvgElement( + "image", + { + width: imageSize, + height: imageSize, + x: x - FieldNote.INSET, + y: -1 * FieldNote.INSET, + }, + group + ); arrow.setAttributeNS( - 'http://www.w3.org/1999/xlink', - 'xlink:href', - Blockly.getMainWorkspace().options.pathToMedia + FieldNote.ARROW_SVG_PATH + "http://www.w3.org/1999/xlink", + "xlink:href", + Blockly.getMainWorkspace().options.pathToMedia + FieldNote.ARROW_SVG_PATH + ); + Blockly.utils.dom.createSvgElement( + "line", + { + stroke: this.sourceBlock_.parentBlock_.getColourTertiary(), + x1: x - FieldNote.INSET, + y1: 0, + x2: x - FieldNote.INSET, + y2: FieldNote.TOP_MENU_HEIGHT - FieldNote.INSET, + }, + group ); - Blockly.utils.dom.createSvgElement('line', - { - 'stroke': this.sourceBlock_.parentBlock_.getColourTertiary(), - 'x1': x - FieldNote.INSET, - 'y1': 0, - 'x2': x - FieldNote.INSET, - 'y2': FieldNote.TOP_MENU_HEIGHT - FieldNote.INSET - }, group); if (flipped) { - var translateX = -1 * FieldNote.OCTAVE_BUTTON_SIZE + (FieldNote.INSET * 2); - group.setAttribute('transform', 'scale(-1, 1) ' + - 'translate(' + translateX + ', 0)'); + var translateX = -1 * FieldNote.OCTAVE_BUTTON_SIZE + FieldNote.INSET * 2; + group.setAttribute( + "transform", + "scale(-1, 1) " + "translate(" + translateX + ", 0)" + ); } return group; } @@ -587,14 +683,19 @@ export class FieldNote extends Blockly.FieldTextInput { * @private */ addCKeyLabel_(x, svg) { - return Blockly.utils.dom.createSvgElement('text', - { - 'x': x, - 'y': FieldNote.TOP_MENU_HEIGHT + FieldNote.WHITE_KEY_HEIGHT - - FieldNote.KEY_LABEL_PADDING, - 'class': 'scratchNotePickerKeyLabel', - 'text-anchor': 'middle' - }, svg); + return Blockly.utils.dom.createSvgElement( + "text", + { + x: x, + y: + FieldNote.TOP_MENU_HEIGHT + + FieldNote.WHITE_KEY_HEIGHT - + FieldNote.KEY_LABEL_PADDING, + class: "scratchNotePickerKeyLabel", + "text-anchor": "middle", + }, + svg + ); } /** @@ -619,7 +720,10 @@ export class FieldNote extends Blockly.FieldTextInput { * @private */ fadeSvgToOpacity_(svg, opacity) { - svg.setAttribute('style', 'opacity: ' + opacity + '; transition: opacity 0.1s;'); + svg.setAttribute( + "style", + "opacity: " + opacity + "; transition: opacity 0.1s;" + ); } /** @@ -629,7 +733,12 @@ export class FieldNote extends Blockly.FieldTextInput { */ onMouseDownOnKey_(e) { this.mouseIsDown_ = true; - this.mouseUpWrapper_ = Blockly.browserEvents.bind(document.body, 'mouseup', this, this.onMouseUp_); + this.mouseUpWrapper_ = Blockly.browserEvents.bind( + document.body, + "mouseup", + this, + this.onMouseUp_ + ); this.selectNoteWithMouseEvent_(e); } @@ -660,7 +769,8 @@ export class FieldNote extends Blockly.FieldTextInput { * @private */ selectNoteWithMouseEvent_(e) { - var newNoteNum = Number(e.target.getAttribute('data-pitch')) + this.displayedOctave_ * 12; + var newNoteNum = + Number(e.target.getAttribute("data-pitch")) + this.displayedOctave_ * 12; this.setEditorValue_(newNoteNum); this.playNoteInternal_(); } @@ -671,10 +781,7 @@ export class FieldNote extends Blockly.FieldTextInput { */ playNoteInternal_() { if (FieldNote.playNote_) { - FieldNote.playNote_( - Number(this.getValue()), - 'Music', - ); + FieldNote.playNote_(Number(this.getValue()), "Music"); } } @@ -685,7 +792,7 @@ export class FieldNote extends Blockly.FieldTextInput { * @param {string} id An id to select a scratch extension to play the note. * @private */ - static playNote_ = function(/* noteNum, id*/) { + static playNote_ = function (/* noteNum, id*/) { return; }; @@ -706,7 +813,7 @@ export class FieldNote extends Blockly.FieldTextInput { return; } - var newNote = Number(this.getText()) + (octaves * 12); + var newNote = Number(this.getText()) + octaves * 12; this.setEditorValue_(newNote); this.animationTarget_ = this.fieldEditorWidth_ * octaves * -1; @@ -722,14 +829,18 @@ export class FieldNote extends Blockly.FieldTextInput { stepOctaveAnimation_() { var absDiff = Math.abs(this.animationPos_ - this.animationTarget_); if (absDiff < 1) { - this.pianoSVG_.setAttribute('transform', 'translate(0, 0)'); + this.pianoSVG_.setAttribute("transform", "translate(0, 0)"); this.setCKeyLabelsVisible_(true); this.playNoteInternal_(); return; } - this.animationPos_ += (this.animationTarget_ - this.animationPos_) * + this.animationPos_ += + (this.animationTarget_ - this.animationPos_) * FieldNote.ANIMATION_FRACTION; - this.pianoSVG_.setAttribute('transform', 'translate(' + this.animationPos_ + ',0)'); + this.pianoSVG_.setAttribute( + "transform", + "translate(" + this.animationPos_ + ",0)" + ); requestAnimationFrame(this.stepOctaveAnimation_.bind(this)); } @@ -751,7 +862,7 @@ export class FieldNote extends Blockly.FieldTextInput { * @private */ noteNumToKeyIndex_(noteNum) { - return Math.floor(noteNum) - (this.displayedOctave_ * 12); + return Math.floor(noteNum) - this.displayedOctave_ * 12; } /** @@ -762,33 +873,36 @@ export class FieldNote extends Blockly.FieldTextInput { var noteNum = Number(this.getText()); // If the note is outside the currently displayed octave, update it - if (this.displayedOctave_ == null || - noteNum > ((this.displayedOctave_ * 12) + 12) || - noteNum < (this.displayedOctave_ * 12)) { + if ( + this.displayedOctave_ == null || + noteNum > this.displayedOctave_ * 12 + 12 || + noteNum < this.displayedOctave_ * 12 + ) { this.displayedOctave_ = Math.floor(noteNum / 12); } var index = this.noteNumToKeyIndex_(noteNum); // Clear the highlight on all keys - this.keySVGs_.forEach(function(svg) { - var isBlack = svg.getAttribute('data-isBlack'); - if (isBlack === 'true') { - svg.setAttribute('fill', FieldNote.BLACK_KEY_COLOR); + this.keySVGs_.forEach(function (svg) { + var isBlack = svg.getAttribute("data-isBlack"); + if (isBlack === "true") { + svg.setAttribute("fill", FieldNote.BLACK_KEY_COLOR); } else { - svg.setAttribute('fill', FieldNote.WHITE_KEY_COLOR); + svg.setAttribute("fill", FieldNote.WHITE_KEY_COLOR); } }); // Set the highlight on the selected key if (this.keySVGs_[index]) { - this.keySVGs_[index].setAttribute('fill', FieldNote.KEY_SELECTED_COLOR); + this.keySVGs_[index].setAttribute("fill", FieldNote.KEY_SELECTED_COLOR); // Update the note name text - var noteName = FieldNote.KEY_INFO[index].name; - this.noteNameText_.textContent = noteName + ' (' + Math.floor(noteNum) + ')'; + var noteName = FieldNote.KEY_INFO[index].name; + this.noteNameText_.textContent = + noteName + " (" + Math.floor(noteNum) + ")"; // Update the low and high C note names var lowCNum = this.displayedOctave_ * 12; - this.lowCText_.textContent = 'C(' + lowCNum + ')'; - this.highCText_.textContent = 'C(' + (lowCNum + 12) + ')'; + this.lowCText_.textContent = "C(" + lowCNum + ")"; + this.highCText_.textContent = "C(" + (lowCNum + 12) + ")"; } } @@ -815,4 +929,4 @@ export class FieldNote extends Blockly.FieldTextInput { } } -Blockly.fieldRegistry.register('field_note', FieldNote); +Blockly.fieldRegistry.register("field_note", FieldNote); diff --git a/core/field_number.js b/src/fields/field_number.js similarity index 69% rename from core/field_number.js rename to src/fields/field_number.js index 356c52d781..c44c8de250 100644 --- a/core/field_number.js +++ b/src/fields/field_number.js @@ -22,8 +22,8 @@ * @fileoverview Field for numbers. Includes validator and numpad on touch. * @author tmickel@mit.edu (Tim Mickel) */ -import * as Blockly from 'blockly/core'; -import {Colours} from './colours.js'; +import * as Blockly from "blockly/core"; +import { Colours } from "../colours.js"; /** * Class for an editable number field. @@ -61,33 +61,50 @@ class FieldNumberPicker extends Blockly.FieldNumber { * @const */ // Calculator order - static NUMPAD_BUTTONS = - ['7', '8', '9', '4', '5', '6', '1', '2', '3', '.', '0', '-', ' ']; + static NUMPAD_BUTTONS = [ + "7", + "8", + "9", + "4", + "5", + "6", + "1", + "2", + "3", + ".", + "0", + "-", + " ", + ]; /** * Src for the delete icon to be shown on the num-pad. * @type {string} * @const */ - static NUMPAD_DELETE_ICON = 'data:image/svg+xml;utf8,' + - '' + ''; + Colours.numPadText + + '"/>'; configure_(config) { super.configure_(config); - this.decimalAllowed_ = (typeof config.precision == 'undefined') || - isNaN(config.precision) || (config.precision == 0) || - (Math.floor(config.precision) != config.precision); - this.negativeAllowed_ = (typeof config.min == 'undefined') || isNaN(config.min) || - config.min < 0; + this.decimalAllowed_ = + typeof config.precision == "undefined" || + isNaN(config.precision) || + config.precision == 0 || + Math.floor(config.precision) != config.precision; + this.negativeAllowed_ = + typeof config.min == "undefined" || isNaN(config.min) || config.min < 0; this.exponentialAllowed_ = this.decimalAllowed_; } @@ -115,9 +132,9 @@ class FieldNumberPicker extends Blockly.FieldNumber { * appropriate. * @private */ - showEditor_(e, ) { + showEditor_(e) { // Do not focus on mobile devices so we can show the num-pad - var showNumPad = e && e.pointerType === 'touch'; + var showNumPad = e && e.pointerType === "touch"; super.showEditor_(e, showNumPad); // Show a numeric keypad in the drop-down on touch @@ -147,15 +164,17 @@ class FieldNumberPicker extends Blockly.FieldNumber { var contentDiv = Blockly.DropDownDiv.getContentDiv(); // Accessibility properties - contentDiv.setAttribute('role', 'menu'); - contentDiv.setAttribute('aria-haspopup', 'true'); + contentDiv.setAttribute("role", "menu"); + contentDiv.setAttribute("aria-haspopup", "true"); this.addButtons_(contentDiv); // Set colour and size of drop-down - Blockly.DropDownDiv.setColour(this.sourceBlock_.parentBlock_.getColour(), - this.sourceBlock_.getColourTertiary()); - contentDiv.style.width = FieldNumberPicker.DROPDOWN_WIDTH + 'px'; + Blockly.DropDownDiv.setColour( + this.sourceBlock_.parentBlock_.getColour(), + this.sourceBlock_.getColourTertiary() + ); + contentDiv.style.width = FieldNumberPicker.DROPDOWN_WIDTH + "px"; this.position_(); } @@ -180,9 +199,17 @@ class FieldNumberPicker extends Blockly.FieldNumber { var secondaryY = position.y; Blockly.DropDownDiv.setBoundsElement( - this.sourceBlock_.workspace.getParentSvg().parentNode); - Blockly.DropDownDiv.show(this, this.getSourceBlock().RTL, primaryX, primaryY, secondaryX, secondaryY, - this.onHide_.bind(this)); + this.sourceBlock_.workspace.getParentSvg().parentNode + ); + Blockly.DropDownDiv.show( + this, + this.getSourceBlock().RTL, + primaryX, + primaryY, + secondaryX, + secondaryY, + this.onHide_.bind(this) + ); } /** @@ -197,44 +224,64 @@ class FieldNumberPicker extends Blockly.FieldNumber { // Add numeric keypad buttons var buttons = FieldNumberPicker.NUMPAD_BUTTONS; - for (var i = 0, buttonText; buttonText = buttons[i]; i++) { - var button = document.createElement('button'); - button.setAttribute('role', 'menuitem'); - button.setAttribute('class', 'blocklyNumPadButton'); - button.setAttribute('style', - 'background:' + buttonColour + ';' + - 'border: 1px solid ' + buttonBorderColour + ';'); + for (var i = 0, buttonText; (buttonText = buttons[i]); i++) { + var button = document.createElement("button"); + button.setAttribute("role", "menuitem"); + button.setAttribute("class", "blocklyNumPadButton"); + button.setAttribute( + "style", + "background:" + + buttonColour + + ";" + + "border: 1px solid " + + buttonBorderColour + + ";" + ); button.title = buttonText; button.innerHTML = buttonText; - Blockly.browserEvents.bind(button, 'mousedown', button, - this.numPadButtonTouch.bind(this)); - if (buttonText == '.' && !this.decimalAllowed_) { + Blockly.browserEvents.bind( + button, + "mousedown", + button, + this.numPadButtonTouch.bind(this) + ); + if (buttonText == "." && !this.decimalAllowed_) { // Don't show the decimal point for inputs that must be round numbers - button.setAttribute('style', 'visibility: hidden'); - } else if (buttonText == '-' && !this.negativeAllowed_) { + button.setAttribute("style", "visibility: hidden"); + } else if (buttonText == "-" && !this.negativeAllowed_) { continue; - } else if (buttonText == ' ' && !this.negativeAllowed_) { + } else if (buttonText == " " && !this.negativeAllowed_) { continue; - } else if (buttonText == ' ' && this.negativeAllowed_) { - button.setAttribute('style', 'visibility: hidden'); + } else if (buttonText == " " && this.negativeAllowed_) { + button.setAttribute("style", "visibility: hidden"); } contentDiv.appendChild(button); } // Add erase button to the end - var eraseButton = document.createElement('button'); - eraseButton.setAttribute('role', 'menuitem'); - eraseButton.setAttribute('class', 'blocklyNumPadButton'); - eraseButton.setAttribute('style', - 'background:' + buttonColour + ';' + - 'border: 1px solid ' + buttonBorderColour + ';'); - eraseButton.title = 'Delete'; - - var eraseImage = document.createElement('img'); + var eraseButton = document.createElement("button"); + eraseButton.setAttribute("role", "menuitem"); + eraseButton.setAttribute("class", "blocklyNumPadButton"); + eraseButton.setAttribute( + "style", + "background:" + + buttonColour + + ";" + + "border: 1px solid " + + buttonBorderColour + + ";" + ); + eraseButton.title = "Delete"; + + var eraseImage = document.createElement("img"); eraseImage.src = FieldNumberPicker.NUMPAD_DELETE_ICON; eraseButton.appendChild(eraseImage); - Blockly.browserEvents.bind(eraseButton, 'mousedown', null, - this.numPadEraseButtonTouch.bind(this)); + Blockly.browserEvents.bind( + eraseButton, + "mousedown", + null, + this.numPadEraseButtonTouch.bind(this) + ); contentDiv.appendChild(eraseButton); } @@ -253,8 +300,10 @@ class FieldNumberPicker extends Blockly.FieldNumber { var selectionEnd = this.htmlInput_.selectionEnd; // Splice in the new value - var newValue = oldValue.slice(0, selectionStart) + spliceValue + - oldValue.slice(selectionEnd); + var newValue = + oldValue.slice(0, selectionStart) + + spliceValue + + oldValue.slice(selectionEnd); // Set new value and advance the cursor this.updateDisplay_(newValue, selectionStart + spliceValue.length); @@ -284,8 +333,8 @@ class FieldNumberPicker extends Blockly.FieldNumber { } // Cut out selected range - var newValue = oldValue.slice(0, selectionStart) + - oldValue.slice(selectionEnd); + var newValue = + oldValue.slice(0, selectionStart) + oldValue.slice(selectionEnd); this.updateDisplay_(newValue, selectionStart); @@ -305,7 +354,7 @@ class FieldNumberPicker extends Blockly.FieldNumber { updateDisplay_(newValue, newSelection) { this.setEditorValue_(newValue); // Resize and scroll the text field appropriately - const htmlInput = this.htmlInput_ + const htmlInput = this.htmlInput_; htmlInput.setSelectionRange(newSelection, newSelection); htmlInput.scrollLeft = htmlInput.scrollWidth; } @@ -315,12 +364,12 @@ class FieldNumberPicker extends Blockly.FieldNumber { */ onHide_() { // Clear accessibility properties - Blockly.DropDownDiv.getContentDiv().removeAttribute('role'); - Blockly.DropDownDiv.getContentDiv().removeAttribute('aria-haspopup'); + Blockly.DropDownDiv.getContentDiv().removeAttribute("role"); + Blockly.DropDownDiv.getContentDiv().removeAttribute("aria-haspopup"); } } -FieldNumberPicker.prototype.DEFAULT_VALUE = ''; +FieldNumberPicker.prototype.DEFAULT_VALUE = ""; -Blockly.fieldRegistry.unregister('field_number'); -Blockly.fieldRegistry.register('field_number', FieldNumberPicker); +Blockly.fieldRegistry.unregister("field_number"); +Blockly.fieldRegistry.register("field_number", FieldNumberPicker); diff --git a/core/field_textinput_removable.js b/src/fields/field_textinput_removable.js similarity index 79% rename from core/field_textinput_removable.js rename to src/fields/field_textinput_removable.js index 7549e9ff90..27bafa3feb 100644 --- a/core/field_textinput_removable.js +++ b/src/fields/field_textinput_removable.js @@ -22,7 +22,7 @@ * @fileoverview Text input field with floating "remove" button. * @author pkaplan@media.mit.edu (Paul Kaplan) */ -import * as Blockly from 'blockly/core'; +import * as Blockly from "blockly/core"; /** * Class for an editable text field displaying a deletion icon when selected. @@ -46,13 +46,19 @@ export class FieldTextInputRemovable extends Blockly.FieldTextInput { super.showEditor_(); const div = Blockly.WidgetDiv.getDiv(); - div.className += ' removableTextInput'; - const removeButton = document.createElement('img'); - removeButton.className = 'blocklyTextRemoveIcon'; - removeButton.setAttribute('src', - this.sourceBlock_.workspace.options.pathToMedia + 'icons/remove.svg'); - this.removeButtonMouseWrapper_ = Blockly.browserEvents.bind(removeButton, - 'mousedown', this, this.removeCallback_); + div.className += " removableTextInput"; + const removeButton = document.createElement("img"); + removeButton.className = "blocklyTextRemoveIcon"; + removeButton.setAttribute( + "src", + this.sourceBlock_.workspace.options.pathToMedia + "icons/remove.svg" + ); + this.removeButtonMouseWrapper_ = Blockly.browserEvents.bind( + removeButton, + "mousedown", + this, + this.removeCallback_ + ); div.appendChild(removeButton); } @@ -65,7 +71,7 @@ export class FieldTextInputRemovable extends Blockly.FieldTextInput { if (this.sourceBlock_ && this.sourceBlock_.removeFieldCallback) { this.sourceBlock_.removeFieldCallback(this); } else { - console.warn('Expected a source block with removeFieldCallback'); + console.warn("Expected a source block with removeFieldCallback"); } } @@ -78,13 +84,16 @@ export class FieldTextInputRemovable extends Blockly.FieldTextInput { * @public */ fromJson(options) { - const text = Blockly.utils.replaceMessageReferences(options['text']); + const text = Blockly.utils.replaceMessageReferences(options["text"]); const field = new FieldTextInputRemovable(text, null, options); - if (typeof options['spellcheck'] == 'boolean') { - field.setSpellcheck(options['spellcheck']); + if (typeof options["spellcheck"] == "boolean") { + field.setSpellcheck(options["spellcheck"]); } return field; } } -Blockly.fieldRegistry.register('field_input_removable', FieldTextInputRemovable); +Blockly.fieldRegistry.register( + "field_input_removable", + FieldTextInputRemovable +); diff --git a/src/field_variable.js b/src/fields/field_variable.js similarity index 96% rename from src/field_variable.js rename to src/fields/field_variable.js index 6c3f16b973..d45f846ee8 100644 --- a/src/field_variable.js +++ b/src/fields/field_variable.js @@ -23,9 +23,9 @@ * @author fraser@google.com (Neil Fraser) */ import * as Blockly from "blockly/core"; -import * as Constants from "./constants.js"; -import { ScratchMsgs } from "../msg/scratch_msgs.js"; -import { createVariable, renameVariable } from "./variables.js"; +import * as Constants from "../constants.js"; +import { ScratchMsgs } from "../../msg/scratch_msgs.js"; +import { createVariable, renameVariable } from "../variables.js"; class FieldVariable extends Blockly.FieldVariable { constructor(varName, validator, variableTypes, defaultType, config) { diff --git a/src/field_variable_getter.js b/src/fields/field_variable_getter.js similarity index 100% rename from src/field_variable_getter.js rename to src/fields/field_variable_getter.js diff --git a/core/field_vertical_separator.js b/src/fields/field_vertical_separator.js similarity index 78% rename from core/field_vertical_separator.js rename to src/fields/field_vertical_separator.js index 9d0b6d045c..ae252094ed 100644 --- a/core/field_vertical_separator.js +++ b/src/fields/field_vertical_separator.js @@ -22,7 +22,7 @@ * @fileoverview Vertical separator field. Draws a vertical line. * @author ericr@media.mit.edu (Eric Rosenbaum) */ -import * as Blockly from 'blockly/core'; +import * as Blockly from "blockly/core"; /** * Class for a vertical separator line. @@ -46,11 +46,12 @@ class FieldVerticalSeparator extends Blockly.Field { * @package * @nocollapse */ - static fromJson = function( - /* eslint-disable no-unused-vars */ _element - /* eslint-enable no-unused-vars */) { + static fromJson = function ( + /* eslint-disable no-unused-vars */ _element + /* eslint-enable no-unused-vars */ + ) { return new FieldVerticalSeparator(); - } + }; /** * Install this field on a block. @@ -60,15 +61,18 @@ class FieldVerticalSeparator extends Blockly.Field { this.size_ = new Blockly.utils.Size(1, height); /** @type {SVGElement} */ - this.lineElement_ = Blockly.utils.dom.createSvgElement('line', - { - 'stroke': this.sourceBlock_.getColourSecondary(), - 'stroke-linecap': 'round', - 'x1': 0, - 'y1': 0, - 'x2': 0, - 'y2': height - }, this.fieldGroup_); + this.lineElement_ = Blockly.utils.dom.createSvgElement( + "line", + { + stroke: this.sourceBlock_.getColourSecondary(), + "stroke-linecap": "round", + x1: 0, + y1: 0, + x2: 0, + y2: height, + }, + this.fieldGroup_ + ); } /** @@ -79,8 +83,8 @@ class FieldVerticalSeparator extends Blockly.Field { * @package */ setLineHeight(newHeight) { - this.lineElement_.setAttribute('y2', newHeight); - }; + this.lineElement_.setAttribute("y2", newHeight); + } /** * Get the value of this field. A no-op in this case. @@ -92,7 +96,7 @@ class FieldVerticalSeparator extends Blockly.Field { } getText() { - return ''; + return ""; } /** @@ -101,8 +105,9 @@ class FieldVerticalSeparator extends Blockly.Field { * @override */ setValue( - /* eslint-disable no-unused-vars */ src - /* eslint-enable no-unused-vars */) { + /* eslint-disable no-unused-vars */ src + /* eslint-enable no-unused-vars */ + ) { return; } @@ -123,4 +128,7 @@ class FieldVerticalSeparator extends Blockly.Field { } } -Blockly.fieldRegistry.register('field_vertical_separator', FieldVerticalSeparator); +Blockly.fieldRegistry.register( + "field_vertical_separator", + FieldVerticalSeparator +); diff --git a/src/glows.js b/src/glows.js index 7172e6c9dc..af5808833f 100644 --- a/src/glows.js +++ b/src/glows.js @@ -1,5 +1,5 @@ -import * as Blockly from 'blockly/core'; -import {Colours} from '../core/colours.js'; +import * as Blockly from "blockly/core"; +import { Colours } from "./colours.js"; /** * Glow/unglow a stack in the workspace. @@ -8,71 +8,91 @@ import {Colours} from '../core/colours.js'; */ export function glowStack(id, isGlowingStack) { if (id) { - const block = Blockly.getMainWorkspace().getBlockById(id) || - Blockly.getMainWorkspace().getFlyout().getWorkspace().getBlockById(id); + const block = + Blockly.getMainWorkspace().getBlockById(id) || + Blockly.getMainWorkspace().getFlyout().getWorkspace().getBlockById(id); if (!block) { - throw 'Tried to glow block that does not exist.'; + throw "Tried to glow block that does not exist."; } const svg = block.getSvgRoot(); - if (isGlowingStack && !svg.hasAttribute('filter')) { - svg.setAttribute('filter', 'url(#blocklyStackGlowFilter)'); - } else if (!isGlowingStack && svg.hasAttribute('filter')) { - svg.removeAttribute('filter'); + if (isGlowingStack && !svg.hasAttribute("filter")) { + svg.setAttribute("filter", "url(#blocklyStackGlowFilter)"); + } else if (!isGlowingStack && svg.hasAttribute("filter")) { + svg.removeAttribute("filter"); } } } export function buildGlowFilter(workspace) { const svg = workspace.getParentSvg(); - const defs = Blockly.utils.dom.createSvgElement(Blockly.utils.Svg.DEFS, {}, svg); + const defs = Blockly.utils.dom.createSvgElement( + Blockly.utils.Svg.DEFS, + {}, + svg + ); // Using a dilate distorts the block shape. // Instead use a gaussian blur, and then set all alpha to 1 with a transfer. - const stackGlowFilter = Blockly.utils.dom.createSvgElement('filter', - { - 'id': 'blocklyStackGlowFilter', - 'height': '160%', - 'width': '180%', - y: '-30%', - x: '-40%' - }, - defs); - Blockly.utils.dom.createSvgElement('feGaussianBlur', - { - 'in': 'SourceGraphic', - 'stdDeviation': Colours.stackGlowSize - }, - stackGlowFilter); + const stackGlowFilter = Blockly.utils.dom.createSvgElement( + "filter", + { + id: "blocklyStackGlowFilter", + height: "160%", + width: "180%", + y: "-30%", + x: "-40%", + }, + defs + ); + Blockly.utils.dom.createSvgElement( + "feGaussianBlur", + { + in: "SourceGraphic", + stdDeviation: Colours.stackGlowSize, + }, + stackGlowFilter + ); // Set all gaussian blur pixels to 1 opacity before applying flood const componentTransfer = Blockly.utils.dom.createSvgElement( - 'feComponentTransfer', {'result': 'outBlur'}, stackGlowFilter); - Blockly.utils.dom.createSvgElement('feFuncA', - { - 'type': 'table', - 'tableValues': '0' + ' 1'.repeat(16), - }, - componentTransfer); + "feComponentTransfer", + { result: "outBlur" }, + stackGlowFilter + ); + Blockly.utils.dom.createSvgElement( + "feFuncA", + { + type: "table", + tableValues: "0" + " 1".repeat(16), + }, + componentTransfer + ); // Color the highlight - Blockly.utils.dom.createSvgElement('feFlood', - { - 'flood-color': Colours.stackGlow, - 'flood-opacity': Colours.stackGlowOpacity, - 'result': 'outColor' - }, - stackGlowFilter); - Blockly.utils.dom.createSvgElement('feComposite', - { - 'in': 'outColor', - 'in2': 'outBlur', - 'operator': 'in', - 'result': 'outGlow' - }, - stackGlowFilter); - Blockly.utils.dom.createSvgElement('feComposite', - { - 'in': 'SourceGraphic', - 'in2': 'outGlow', - 'operator': 'over' - }, - stackGlowFilter); + Blockly.utils.dom.createSvgElement( + "feFlood", + { + "flood-color": Colours.stackGlow, + "flood-opacity": Colours.stackGlowOpacity, + result: "outColor", + }, + stackGlowFilter + ); + Blockly.utils.dom.createSvgElement( + "feComposite", + { + in: "outColor", + in2: "outBlur", + operator: "in", + result: "outGlow", + }, + stackGlowFilter + ); + Blockly.utils.dom.createSvgElement( + "feComposite", + { + in: "SourceGraphic", + in2: "outGlow", + operator: "over", + }, + stackGlowFilter + ); } diff --git a/src/index.js b/src/index.js index 7a6182431e..14dfb96749 100644 --- a/src/index.js +++ b/src/index.js @@ -7,25 +7,25 @@ import * as Blockly from "blockly/core"; import { registerFieldAngle } from "@blockly/field-angle"; registerFieldAngle(); -import "../blocks_common/colour.js"; -import "../blocks_common/math.js"; -import "../blocks_common/matrix.js"; -import "../blocks_common/note.js"; -import "../blocks_common/text.js"; -import "../blocks_vertical/vertical_extensions.js"; -import "../blocks_vertical/control.js"; -import "../blocks_vertical/data.js"; -import "../blocks_vertical/event.js"; -import "../blocks_vertical/looks.js"; -import "../blocks_vertical/motion.js"; -import "../blocks_vertical/operators.js"; -import "../blocks_vertical/procedures.js"; -import "../blocks_vertical/sensing.js"; -import "../blocks_vertical/sound.js"; -import * as scratchBlocksUtils from "../core/scratch_blocks_utils.js"; +import "./blocks/colour.js"; +import "./blocks/math.js"; +import "./blocks/matrix.js"; +import "./blocks/note.js"; +import "./blocks/text.js"; +import "./blocks/vertical_extensions.js"; +import "./blocks/control.js"; +import "./blocks/data.js"; +import "./blocks/event.js"; +import "./blocks/looks.js"; +import "./blocks/motion.js"; +import "./blocks/operators.js"; +import "./blocks/procedures.js"; +import "./blocks/sensing.js"; +import "./blocks/sound.js"; +import * as scratchBlocksUtils from "./scratch_blocks_utils.js"; import * as ScratchVariables from "./variables.js"; -import "../core/css.js"; -import "../core/field_vertical_separator.js"; +import "./css.js"; +import "./fields/field_vertical_separator.js"; import "./renderer/renderer.js"; import * as contextMenuItems from "./context_menu_items.js"; import { @@ -42,26 +42,26 @@ import "./scratch_dragger.js"; import "./scratch_variable_map.js"; import "./scratch_variable_model.js"; import "./scratch_connection_checker.js"; -import "./events_block_comment_change.js"; -import "./events_block_comment_collapse.js"; -import "./events_block_comment_create.js"; -import "./events_block_comment_delete.js"; -import "./events_block_comment_move.js"; -import "./events_block_comment_resize.js"; -import "./events_scratch_variable_create.js"; -import "./field_variable.js"; -import "./field_variable_getter.js"; +import "./events/events_block_comment_change.js"; +import "./events/events_block_comment_collapse.js"; +import "./events/events_block_comment_create.js"; +import "./events/events_block_comment_delete.js"; +import "./events/events_block_comment_move.js"; +import "./events/events_block_comment_resize.js"; +import "./events/events_scratch_variable_create.js"; +import "./fields/field_variable.js"; +import "./fields/field_variable_getter.js"; import { buildShadowFilter } from "./shadows.js"; -export * from "blockly"; +export * from "blockly/core"; export * from "./block_reporting.js"; export * from "./categories.js"; export * from "./procedures.js"; -export * from "../core/colours.js"; -export * from "../core/field_colour_slider.js"; -export * from "../core/field_matrix.js"; -export * from "../core/field_note.js"; -export * from "../core/field_number.js"; +export * from "./colours.js"; +export * from "./fields/field_colour_slider.js"; +export * from "./fields/field_matrix.js"; +export * from "./fields/field_note.js"; +export * from "./fields/field_number.js"; export * from "../msg/scratch_msgs.js"; export * from "./constants.js"; export { glowStack }; diff --git a/src/procedures.js b/src/procedures.js index c6296e9476..1ce112e0a2 100644 --- a/src/procedures.js +++ b/src/procedures.js @@ -25,7 +25,7 @@ import * as Blockly from "blockly/core"; import * as Constants from "./constants.js"; -import * as scratchBlocksUtils from "../core/scratch_blocks_utils.js"; +import * as scratchBlocksUtils from "../src/scratch_blocks_utils.js"; /** * Find all user-created procedure definition mutations in a workspace. diff --git a/core/scratch_blocks_utils.js b/src/scratch_blocks_utils.js similarity index 100% rename from core/scratch_blocks_utils.js rename to src/scratch_blocks_utils.js diff --git a/src/scratch_continuous_category.js b/src/scratch_continuous_category.js index dac529127a..0cbfa12e66 100644 --- a/src/scratch_continuous_category.js +++ b/src/scratch_continuous_category.js @@ -1,16 +1,16 @@ -import * as Blockly from 'blockly/core'; -import {ContinuousCategory} from '@blockly/continuous-toolbox'; +import * as Blockly from "blockly/core"; +import { ContinuousCategory } from "@blockly/continuous-toolbox"; class ScratchContinuousCategory extends ContinuousCategory { createIconDom_() { if (this.toolboxItemDef_.iconURI) { - const icon = document.createElement('img'); + const icon = document.createElement("img"); icon.src = this.toolboxItemDef_.iconURI; - icon.className = 'categoryIconBubble'; + icon.className = "categoryIconBubble"; return icon; } else { const icon = super.createIconDom_(); - icon.style.border = `1px solid ${this.toolboxItemDef_['secondaryColour']}`; + icon.style.border = `1px solid ${this.toolboxItemDef_["secondaryColour"]}`; return icon; } } @@ -18,7 +18,7 @@ class ScratchContinuousCategory extends ContinuousCategory { setSelected(isSelected) { super.setSelected(isSelected); // Prevent hardcoding the background color to grey. - this.rowDiv_.style.backgroundColor = ''; + this.rowDiv_.style.backgroundColor = ""; } } @@ -26,5 +26,5 @@ Blockly.registry.register( Blockly.registry.Type.TOOLBOX_ITEM, Blockly.ToolboxCategory.registrationName, ScratchContinuousCategory, - true, -); \ No newline at end of file + true +); diff --git a/src/scratch_continuous_toolbox.js b/src/scratch_continuous_toolbox.js index 0be28b0a95..2a9f7b0950 100644 --- a/src/scratch_continuous_toolbox.js +++ b/src/scratch_continuous_toolbox.js @@ -1,5 +1,5 @@ -import * as Blockly from 'blockly/core'; -import {ContinuousToolbox} from '@blockly/continuous-toolbox'; +import * as Blockly from "blockly/core"; +import { ContinuousToolbox } from "@blockly/continuous-toolbox"; export class ScratchContinuousToolbox extends ContinuousToolbox { refreshSelection() { diff --git a/src/scratch_dragger.js b/src/scratch_dragger.js index ce40b0edfd..0e3f885df7 100644 --- a/src/scratch_dragger.js +++ b/src/scratch_dragger.js @@ -5,8 +5,8 @@ */ import * as Blockly from "blockly/core"; -import { BlockDragOutside } from "./events_block_drag_outside.js"; -import { BlockDragEnd } from "./events_block_drag_end.js"; +import { BlockDragOutside } from "./events/events_block_drag_outside.js"; +import { BlockDragEnd } from "./events/events_block_drag_end.js"; const BOUNDLESS_CLASS = "boundless"; diff --git a/src/shadows.js b/src/shadows.js index c585a4211c..ea40cf1ffb 100644 --- a/src/shadows.js +++ b/src/shadows.js @@ -4,43 +4,58 @@ * SPDX-License-Identifier: Apache-2.0 */ -import * as Blockly from 'blockly/core'; -import {Colours} from '../core/colours.js'; +import * as Blockly from "blockly/core"; +import { Colours } from "./colours.js"; export function buildShadowFilter(workspace) { const svg = workspace.getParentSvg(); - const defs = Blockly.utils.dom.createSvgElement(Blockly.utils.Svg.DEFS, {}, svg); + const defs = Blockly.utils.dom.createSvgElement( + Blockly.utils.Svg.DEFS, + {}, + svg + ); // Adjust these width/height, x/y properties to stop the shadow from clipping - var dragShadowFilter = Blockly.utils.dom.createSvgElement('filter', - { - 'id': 'blocklyDragShadowFilter', - 'height': '140%', - 'width': '140%', - 'y': '-20%', - 'x': '-20%' - }, - defs); - Blockly.utils.dom.createSvgElement('feGaussianBlur', - { - 'in': 'SourceAlpha', - 'stdDeviation': '6' - }, - dragShadowFilter); + var dragShadowFilter = Blockly.utils.dom.createSvgElement( + "filter", + { + id: "blocklyDragShadowFilter", + height: "140%", + width: "140%", + y: "-20%", + x: "-20%", + }, + defs + ); + Blockly.utils.dom.createSvgElement( + "feGaussianBlur", + { + in: "SourceAlpha", + stdDeviation: "6", + }, + dragShadowFilter + ); var componentTransfer = Blockly.utils.dom.createSvgElement( - 'feComponentTransfer', {'result': 'offsetBlur'}, dragShadowFilter); + "feComponentTransfer", + { result: "offsetBlur" }, + dragShadowFilter + ); // Shadow opacity is specified in the adjustable colour library, // since the darkness of the shadow largely depends on the workspace colour. - Blockly.utils.dom.createSvgElement('feFuncA', - { - 'type': 'linear', - 'slope': Colours.dragShadowOpacity - }, - componentTransfer); - Blockly.utils.dom.createSvgElement('feComposite', - { - 'in': 'SourceGraphic', - 'in2': 'offsetBlur', - 'operator': 'over' - }, - dragShadowFilter); + Blockly.utils.dom.createSvgElement( + "feFuncA", + { + type: "linear", + slope: Colours.dragShadowOpacity, + }, + componentTransfer + ); + Blockly.utils.dom.createSvgElement( + "feComposite", + { + in: "SourceGraphic", + in2: "offsetBlur", + operator: "over", + }, + dragShadowFilter + ); } From 375e56db6918dc3475d5c8f29f53cd03f138e4a7 Mon Sep 17 00:00:00 2001 From: Aaron Dodson Date: Fri, 23 Aug 2024 15:56:45 -0700 Subject: [PATCH 073/130] fix: don't show scope options when renaming a variable from the variable getter context menu (#139) --- src/blocks/data.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/blocks/data.js b/src/blocks/data.js index 45869707b2..933168c09f 100644 --- a/src/blocks/data.js +++ b/src/blocks/data.js @@ -22,6 +22,7 @@ import * as Blockly from "blockly/core"; import { Categories } from "../categories.js"; import * as Constants from "../constants.js"; import * as scratchBlocksUtils from "../scratch_blocks_utils.js"; +import { renameVariable } from "../variables.js"; Blockly.Blocks["data_variable"] = { /** @@ -670,7 +671,7 @@ const RENAME_OPTION_CALLBACK_FACTORY = function (block, fieldName) { return function () { var workspace = block.workspace; var variable = block.getField(fieldName).getVariable(); - Blockly.Variables.renameVariable(workspace, variable); + renameVariable(workspace, variable); }; }; From ef7911cf7fd12d6370733bdd3778560925bd050c Mon Sep 17 00:00:00 2001 From: Aaron Dodson Date: Fri, 23 Aug 2024 16:04:30 -0700 Subject: [PATCH 074/130] fix: use Scratch's FieldAngle (#138) * chore: field_angle.js into src/fields * chore: format field_angle.js * refactor: clean up and modernize field_angle.js * chore: use field_angle.js instead of the Blockly plugin version * chore: remove the Blockly angle field * fix: fix angle normalization --- core/field_angle.js | 398 ----------------------------------- package-lock.json | 18 -- package.json | 1 - src/fields/field_angle.js | 426 ++++++++++++++++++++++++++++++++++++++ src/index.js | 3 +- 5 files changed, 427 insertions(+), 419 deletions(-) delete mode 100644 core/field_angle.js create mode 100644 src/fields/field_angle.js diff --git a/core/field_angle.js b/core/field_angle.js deleted file mode 100644 index f178a2a748..0000000000 --- a/core/field_angle.js +++ /dev/null @@ -1,398 +0,0 @@ -/** - * @license - * Visual Blocks Editor - * - * Copyright 2013 Google Inc. - * https://developers.google.com/blockly/ - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @fileoverview Angle input field. - * @author fraser@google.com (Neil Fraser) - */ -'use strict'; - -goog.provide('Blockly.FieldAngle'); - -goog.require('Blockly.DropDownDiv'); -goog.require('Blockly.FieldTextInput'); -goog.require('goog.math'); -goog.require('goog.userAgent'); - - -/** - * Class for an editable angle field. - * @param {(string|number)=} opt_value The initial content of the field. The - * value should cast to a number, and if it does not, '0' will be used. - * @param {Function=} opt_validator An optional function that is called - * to validate any constraints on what the user entered. Takes the new - * text as an argument and returns the accepted text or null to abort - * the change. - * @extends {Blockly.FieldTextInput} - * @constructor - */ -Blockly.FieldAngle = function(opt_value, opt_validator) { - // Add degree symbol: '360°' (LTR) or '°360' (RTL) - this.symbol_ = Blockly.utils.createSvgElement('tspan', {}, null); - this.symbol_.appendChild(document.createTextNode('\u00B0')); - - var numRestrictor = new RegExp("[\\d]|[\\.]|[-]|[eE]"); - - opt_value = (opt_value && !isNaN(opt_value)) ? String(opt_value) : '0'; - Blockly.FieldAngle.superClass_.constructor.call( - this, opt_value, opt_validator, numRestrictor); - this.addArgType('angle'); -}; -goog.inherits(Blockly.FieldAngle, Blockly.FieldTextInput); - -/** - * Construct a FieldAngle from a JSON arg object. - * @param {!Object} options A JSON object with options (angle). - * @returns {!Blockly.FieldAngle} The new field instance. - * @package - * @nocollapse - */ -Blockly.FieldAngle.fromJson = function(options) { - return new Blockly.FieldAngle(options['angle']); -}; - -/** - * Round angles to the nearest 15 degrees when using mouse. - * Set to 0 to disable rounding. - */ -Blockly.FieldAngle.ROUND = 15; - -/** - * Half the width of protractor image. - */ -Blockly.FieldAngle.HALF = 120 / 2; - -/* The following two settings work together to set the behaviour of the angle - * picker. While many combinations are possible, two modes are typical: - * Math mode. - * 0 deg is right, 90 is up. This is the style used by protractors. - * Blockly.FieldAngle.CLOCKWISE = false; - * Blockly.FieldAngle.OFFSET = 0; - * Compass mode. - * 0 deg is up, 90 is right. This is the style used by maps. - * Blockly.FieldAngle.CLOCKWISE = true; - * Blockly.FieldAngle.OFFSET = 90; - */ - -/** - * Angle increases clockwise (true) or counterclockwise (false). - */ -Blockly.FieldAngle.CLOCKWISE = true; - -/** - * Offset the location of 0 degrees (and all angles) by a constant. - * Usually either 0 (0 = right) or 90 (0 = up). - */ -Blockly.FieldAngle.OFFSET = 90; - -/** - * Maximum allowed angle before wrapping. - * Usually either 360 (for 0 to 359.9) or 180 (for -179.9 to 180). - */ -Blockly.FieldAngle.WRAP = 180; - -/** - * Radius of drag handle - */ -Blockly.FieldAngle.HANDLE_RADIUS = 10; - -/** - * Width of drag handle arrow - */ -Blockly.FieldAngle.ARROW_WIDTH = Blockly.FieldAngle.HANDLE_RADIUS; - -/** - * Half the stroke-width used for the "glow" around the drag handle, rounded up to nearest whole pixel - */ - -Blockly.FieldAngle.HANDLE_GLOW_WIDTH = 3; - -/** - * Radius of protractor circle. Slightly smaller than protractor size since - * otherwise SVG crops off half the border at the edges. - */ -Blockly.FieldAngle.RADIUS = Blockly.FieldAngle.HALF - - Blockly.FieldAngle.HANDLE_RADIUS - Blockly.FieldAngle.HANDLE_GLOW_WIDTH; - -/** - * Radius of central dot circle. - */ -Blockly.FieldAngle.CENTER_RADIUS = 2; - -/** - * Path to the arrow svg icon. - */ -Blockly.FieldAngle.ARROW_SVG_PATH = 'icons/arrow.svg'; - -/** - * Clean up this FieldAngle, as well as the inherited FieldTextInput. - * @return {!Function} Closure to call on destruction of the WidgetDiv. - * @private - */ -Blockly.FieldAngle.prototype.dispose_ = function() { - var thisField = this; - return function() { - Blockly.FieldAngle.superClass_.dispose_.call(thisField)(); - thisField.gauge_ = null; - if (thisField.mouseDownWrapper_) { - Blockly.unbindEvent_(thisField.mouseDownWrapper_); - } - if (thisField.mouseUpWrapper_) { - Blockly.unbindEvent_(thisField.mouseUpWrapper_); - } - if (thisField.mouseMoveWrapper_) { - Blockly.unbindEvent_(thisField.mouseMoveWrapper_); - } - }; -}; - -/** - * Show the inline free-text editor on top of the text. - * @private - */ -Blockly.FieldAngle.prototype.showEditor_ = function() { - // Mobile browsers have issues with in-line textareas (focus & keyboards). - Blockly.FieldAngle.superClass_.showEditor_.call(this, this.useTouchInteraction_); - // If there is an existing drop-down someone else owns, hide it immediately and clear it. - Blockly.DropDownDiv.hideWithoutAnimation(); - Blockly.DropDownDiv.clearContent(); - var div = Blockly.DropDownDiv.getContentDiv(); - // Build the SVG DOM. - var svg = Blockly.utils.createSvgElement('svg', { - 'xmlns': 'http://www.w3.org/2000/svg', - 'xmlns:html': 'http://www.w3.org/1999/xhtml', - 'xmlns:xlink': 'http://www.w3.org/1999/xlink', - 'version': '1.1', - 'height': (Blockly.FieldAngle.HALF * 2) + 'px', - 'width': (Blockly.FieldAngle.HALF * 2) + 'px' - }, div); - Blockly.utils.createSvgElement('circle', { - 'cx': Blockly.FieldAngle.HALF, 'cy': Blockly.FieldAngle.HALF, - 'r': Blockly.FieldAngle.RADIUS, - 'class': 'blocklyAngleCircle' - }, svg); - this.gauge_ = Blockly.utils.createSvgElement('path', - {'class': 'blocklyAngleGauge'}, svg); - // The moving line, x2 and y2 are set in updateGraph_ - this.line_ = Blockly.utils.createSvgElement('line',{ - 'x1': Blockly.FieldAngle.HALF, - 'y1': Blockly.FieldAngle.HALF, - 'class': 'blocklyAngleLine' - }, svg); - // The fixed vertical line at the offset - var offsetRadians = Math.PI * Blockly.FieldAngle.OFFSET / 180; - Blockly.utils.createSvgElement('line', { - 'x1': Blockly.FieldAngle.HALF, - 'y1': Blockly.FieldAngle.HALF, - 'x2': Blockly.FieldAngle.HALF + Blockly.FieldAngle.RADIUS * Math.cos(offsetRadians), - 'y2': Blockly.FieldAngle.HALF - Blockly.FieldAngle.RADIUS * Math.sin(offsetRadians), - 'class': 'blocklyAngleLine' - }, svg); - // Draw markers around the edge. - for (var angle = 0; angle < 360; angle += 15) { - Blockly.utils.createSvgElement('line', { - 'x1': Blockly.FieldAngle.HALF + Blockly.FieldAngle.RADIUS - 13, - 'y1': Blockly.FieldAngle.HALF, - 'x2': Blockly.FieldAngle.HALF + Blockly.FieldAngle.RADIUS - 7, - 'y2': Blockly.FieldAngle.HALF, - 'class': 'blocklyAngleMarks', - 'transform': 'rotate(' + angle + ',' + - Blockly.FieldAngle.HALF + ',' + Blockly.FieldAngle.HALF + ')' - }, svg); - } - // Center point - Blockly.utils.createSvgElement('circle', { - 'cx': Blockly.FieldAngle.HALF, 'cy': Blockly.FieldAngle.HALF, - 'r': Blockly.FieldAngle.CENTER_RADIUS, - 'class': 'blocklyAngleCenterPoint' - }, svg); - // Handle group: a circle and the arrow image - this.handle_ = Blockly.utils.createSvgElement('g', {}, svg); - Blockly.utils.createSvgElement('circle', { - 'cx': 0, - 'cy': 0, - 'r': Blockly.FieldAngle.HANDLE_RADIUS, - 'class': 'blocklyAngleDragHandle' - }, this.handle_); - this.arrowSvg_ = Blockly.utils.createSvgElement('image', - { - 'width': Blockly.FieldAngle.ARROW_WIDTH, - 'height': Blockly.FieldAngle.ARROW_WIDTH, - 'x': -Blockly.FieldAngle.ARROW_WIDTH / 2, - 'y': -Blockly.FieldAngle.ARROW_WIDTH / 2, - 'class': 'blocklyAngleDragArrow' - }, - this.handle_); - this.arrowSvg_.setAttributeNS( - 'http://www.w3.org/1999/xlink', - 'xlink:href', - Blockly.mainWorkspace.options.pathToMedia + Blockly.FieldAngle.ARROW_SVG_PATH - ); - - Blockly.DropDownDiv.setColour(this.sourceBlock_.parentBlock_.getColour(), - this.sourceBlock_.getColourTertiary()); - Blockly.DropDownDiv.setCategory(this.sourceBlock_.parentBlock_.getCategory()); - Blockly.DropDownDiv.showPositionedByBlock(this, this.sourceBlock_); - - this.mouseDownWrapper_ = - Blockly.bindEvent_(this.handle_, 'mousedown', this, this.onMouseDown); - - this.updateGraph_(); -}; -/** - * Set the angle to match the mouse's position. - * @param {!Event} e Mouse move event. - */ -Blockly.FieldAngle.prototype.onMouseDown = function() { - this.mouseMoveWrapper_ = Blockly.bindEvent_(document.body, 'mousemove', this, this.onMouseMove); - this.mouseUpWrapper_ = Blockly.bindEvent_(document.body, 'mouseup', this, this.onMouseUp); -}; - -/** - * Set the angle to match the mouse's position. - * @param {!Event} e Mouse move event. - */ -Blockly.FieldAngle.prototype.onMouseUp = function() { - Blockly.unbindEvent_(this.mouseMoveWrapper_); - Blockly.unbindEvent_(this.mouseUpWrapper_); -}; - -/** - * Set the angle to match the mouse's position. - * @param {!Event} e Mouse move event. - */ -Blockly.FieldAngle.prototype.onMouseMove = function(e) { - e.preventDefault(); - var bBox = this.gauge_.ownerSVGElement.getBoundingClientRect(); - var dx = e.clientX - bBox.left - Blockly.FieldAngle.HALF; - var dy = e.clientY - bBox.top - Blockly.FieldAngle.HALF; - var angle = Math.atan(-dy / dx); - if (isNaN(angle)) { - // This shouldn't happen, but let's not let this error propagate further. - return; - } - angle = goog.math.toDegrees(angle); - // 0: East, 90: North, 180: West, 270: South. - if (dx < 0) { - angle += 180; - } else if (dy > 0) { - angle += 360; - } - if (Blockly.FieldAngle.CLOCKWISE) { - angle = Blockly.FieldAngle.OFFSET + 360 - angle; - } else { - angle -= Blockly.FieldAngle.OFFSET; - } - if (Blockly.FieldAngle.ROUND) { - angle = Math.round(angle / Blockly.FieldAngle.ROUND) * - Blockly.FieldAngle.ROUND; - } - angle = this.callValidator(angle); - Blockly.FieldTextInput.htmlInput_.value = angle; - this.setValue(angle); - this.validate_(); - this.resizeEditor_(); -}; - -/** - * Insert a degree symbol. - * @param {?string} text New text. - */ -Blockly.FieldAngle.prototype.setText = function(text) { - Blockly.FieldAngle.superClass_.setText.call(this, text); - if (!this.textElement_) { - // Not rendered yet. - return; - } - this.updateGraph_(); - // Cached width is obsolete. Clear it. - this.size_.width = 0; -}; - -/** - * Redraw the graph with the current angle. - * @private - */ -Blockly.FieldAngle.prototype.updateGraph_ = function() { - if (!this.gauge_) { - return; - } - var angleDegrees = Number(this.getText()) % 360 + Blockly.FieldAngle.OFFSET; - var angleRadians = goog.math.toRadians(angleDegrees); - var path = ['M ', Blockly.FieldAngle.HALF, ',', Blockly.FieldAngle.HALF]; - var x2 = Blockly.FieldAngle.HALF; - var y2 = Blockly.FieldAngle.HALF; - if (!isNaN(angleRadians)) { - var angle1 = goog.math.toRadians(Blockly.FieldAngle.OFFSET); - var x1 = Math.cos(angle1) * Blockly.FieldAngle.RADIUS; - var y1 = Math.sin(angle1) * -Blockly.FieldAngle.RADIUS; - if (Blockly.FieldAngle.CLOCKWISE) { - angleRadians = 2 * angle1 - angleRadians; - } - x2 += Math.cos(angleRadians) * Blockly.FieldAngle.RADIUS; - y2 -= Math.sin(angleRadians) * Blockly.FieldAngle.RADIUS; - // Use large arc only if input value is greater than wrap - var largeFlag = Math.abs(angleDegrees - Blockly.FieldAngle.OFFSET) > 180 ? 1 : 0; - var sweepFlag = Number(Blockly.FieldAngle.CLOCKWISE); - if (angleDegrees < Blockly.FieldAngle.OFFSET) { - sweepFlag = 1 - sweepFlag; // Sweep opposite direction if less than the offset - } - path.push(' l ', x1, ',', y1, - ' A ', Blockly.FieldAngle.RADIUS, ',', Blockly.FieldAngle.RADIUS, - ' 0 ', largeFlag, ' ', sweepFlag, ' ', x2, ',', y2, ' z'); - - // Image rotation needs to be set in degrees - if (Blockly.FieldAngle.CLOCKWISE) { - var imageRotation = angleDegrees + 2 * Blockly.FieldAngle.OFFSET; - } else { - var imageRotation = -angleDegrees; - } - this.arrowSvg_.setAttribute('transform', 'rotate(' + (imageRotation) + ')'); - } - this.gauge_.setAttribute('d', path.join('')); - this.line_.setAttribute('x2', x2); - this.line_.setAttribute('y2', y2); - this.handle_.setAttribute('transform', 'translate(' + x2 + ',' + y2 + ')'); -}; - -/** - * Ensure that only an angle may be entered. - * @param {string} text The user's text. - * @return {?string} A string representing a valid angle, or null if invalid. - */ -Blockly.FieldAngle.prototype.classValidator = function(text) { - if (text === null) { - return null; - } - var n = parseFloat(text || 0); - if (isNaN(n)) { - return null; - } - n = n % 360; - if (n < 0) { - n += 360; - } - if (n > Blockly.FieldAngle.WRAP) { - n -= 360; - } - return String(n); -}; - -Blockly.Field.register('field_angle', Blockly.FieldAngle); diff --git a/package-lock.json b/package-lock.json index 1635af2260..67f0db052b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,7 +10,6 @@ "license": "Apache-2.0", "dependencies": { "@blockly/continuous-toolbox": "^5.0.15", - "@blockly/field-angle": "^4.0.2", "@blockly/field-colour": "^4.0.2", "blockly": "^11.0.0" }, @@ -134,17 +133,6 @@ "blockly": "^10.0.0" } }, - "node_modules/@blockly/field-angle": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@blockly/field-angle/-/field-angle-4.0.2.tgz", - "integrity": "sha512-N7kxQtmoPUuu3oKtOrrVpqBa6hMagmKxwDZkh9mvo2K0AiFbysVzmqfXhz1gGt4Z9ve617h9gTO4dk/qWpc/fQ==", - "engines": { - "node": ">=8.0.0" - }, - "peerDependencies": { - "blockly": "^10.0.0" - } - }, "node_modules/@blockly/field-colour": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/@blockly/field-colour/-/field-colour-4.0.2.tgz", @@ -7120,12 +7108,6 @@ "integrity": "sha512-3JCSimCo5KEWvvN4qC66vs2L/WtJIHepoIfkPNcbvMwjwYxJ484UPK2LKdlyI1842mgFfcYM3nTERjfa+Q4rXA==", "requires": {} }, - "@blockly/field-angle": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@blockly/field-angle/-/field-angle-4.0.2.tgz", - "integrity": "sha512-N7kxQtmoPUuu3oKtOrrVpqBa6hMagmKxwDZkh9mvo2K0AiFbysVzmqfXhz1gGt4Z9ve617h9gTO4dk/qWpc/fQ==", - "requires": {} - }, "@blockly/field-colour": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/@blockly/field-colour/-/field-colour-4.0.2.tgz", diff --git a/package.json b/package.json index 7b831293e4..7dc0d31c1e 100644 --- a/package.json +++ b/package.json @@ -28,7 +28,6 @@ }, "dependencies": { "@blockly/continuous-toolbox": "^5.0.15", - "@blockly/field-angle": "^4.0.2", "@blockly/field-colour": "^4.0.2", "blockly": "^11.0.0" } diff --git a/src/fields/field_angle.js b/src/fields/field_angle.js new file mode 100644 index 0000000000..c0dc321cd3 --- /dev/null +++ b/src/fields/field_angle.js @@ -0,0 +1,426 @@ +/** + * @license + * Visual Blocks Editor + * + * Copyright 2013 Google Inc. + * https://developers.google.com/blockly/ + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @fileoverview Angle input field. + * @author fraser@google.com (Neil Fraser) + */ +"use strict"; + +import * as Blockly from "blockly/core"; + +class FieldAngle extends Blockly.FieldNumber { + /** + * Construct a FieldAngle from a JSON arg object. + * @param {!Object} options A JSON object with options (angle). + * @returns {!Blockly.FieldAngle} The new field instance. + * @package + * @nocollapse + */ + fromJson(options) { + return new FieldAngle(options["angle"]); + } + + /** + * Round angles to the nearest 15 degrees when using mouse. + * Set to 0 to disable rounding. + */ + ROUND = 15; + + /** + * Half the width of protractor image. + */ + HALF = 120 / 2; + + /* The following two settings work together to set the behaviour of the angle + * picker. While many combinations are possible, two modes are typical: + * Math mode. + * 0 deg is right, 90 is up. This is the style used by protractors. + * CLOCKWISE = false; + * OFFSET = 0; + * Compass mode. + * 0 deg is up, 90 is right. This is the style used by maps. + * CLOCKWISE = true; + * OFFSET = 90; + */ + + /** + * Angle increases clockwise (true) or counterclockwise (false). + */ + CLOCKWISE = true; + + /** + * Offset the location of 0 degrees (and all angles) by a constant. + * Usually either 0 (0 = right) or 90 (0 = up). + */ + OFFSET = 90; + + /** + * Maximum allowed angle before wrapping. + * Usually either 360 (for 0 to 359.9) or 180 (for -179.9 to 180). + */ + WRAP = 180; + + /** + * Radius of drag handle + */ + HANDLE_RADIUS = 10; + + /** + * Width of drag handle arrow + */ + ARROW_WIDTH = this.HANDLE_RADIUS; + + /** + * Half the stroke-width used for the "glow" around the drag handle, rounded up to nearest whole pixel + */ + + HANDLE_GLOW_WIDTH = 3; + + /** + * Radius of protractor circle. Slightly smaller than protractor size since + * otherwise SVG crops off half the border at the edges. + */ + RADIUS = this.HALF - this.HANDLE_RADIUS - this.HANDLE_GLOW_WIDTH; + + /** + * Radius of central dot circle. + */ + CENTER_RADIUS = 2; + + /** + * Path to the arrow svg icon. + */ + ARROW_SVG_PATH = "icons/arrow.svg"; + + /** + * Clean up this FieldAngle, as well as the inherited FieldTextInput. + * @return {!Function} Closure to call on destruction of the WidgetDiv. + * @private + */ + dispose() { + super.dispose(); + this.gauge_ = null; + if (this.mouseDownWrapper_) { + Blockly.browserEvents.unbind(this.mouseDownWrapper_); + } + if (this.mouseUpWrapper_) { + Blockly.browserEvents.unbind(this.mouseUpWrapper_); + } + if (this.mouseMoveWrapper_) { + Blockly.browserEvents.unbind(this.mouseMoveWrapper_); + } + } + + /** + * Show the inline free-text editor on top of the text. + * @private + */ + showEditor_(event) { + super.showEditor_(event); + // If there is an existing drop-down someone else owns, hide it immediately and clear it. + Blockly.DropDownDiv.hideWithoutAnimation(); + Blockly.DropDownDiv.clearContent(); + var div = Blockly.DropDownDiv.getContentDiv(); + // Build the SVG DOM. + var svg = Blockly.utils.dom.createSvgElement( + "svg", + { + xmlns: "http://www.w3.org/2000/svg", + "xmlns:html": "http://www.w3.org/1999/xhtml", + "xmlns:xlink": "http://www.w3.org/1999/xlink", + version: "1.1", + height: this.HALF * 2 + "px", + width: this.HALF * 2 + "px", + }, + div + ); + Blockly.utils.dom.createSvgElement( + "circle", + { + cx: this.HALF, + cy: this.HALF, + r: this.RADIUS, + class: "blocklyAngleCircle", + }, + svg + ); + this.gauge_ = Blockly.utils.dom.createSvgElement( + "path", + { class: "blocklyAngleGauge" }, + svg + ); + // The moving line, x2 and y2 are set in updateGraph_ + this.line_ = Blockly.utils.dom.createSvgElement( + "line", + { + x1: this.HALF, + y1: this.HALF, + class: "blocklyAngleLine", + }, + svg + ); + // The fixed vertical line at the offset + var offsetRadians = (Math.PI * this.OFFSET) / 180; + Blockly.utils.dom.createSvgElement( + "line", + { + x1: this.HALF, + y1: this.HALF, + x2: this.HALF + this.RADIUS * Math.cos(offsetRadians), + y2: this.HALF - this.RADIUS * Math.sin(offsetRadians), + class: "blocklyAngleLine", + }, + svg + ); + // Draw markers around the edge. + for (var angle = 0; angle < 360; angle += 15) { + Blockly.utils.dom.createSvgElement( + "line", + { + x1: this.HALF + this.RADIUS - 13, + y1: this.HALF, + x2: this.HALF + this.RADIUS - 7, + y2: this.HALF, + class: "blocklyAngleMarks", + transform: + "rotate(" + angle + "," + this.HALF + "," + this.HALF + ")", + }, + svg + ); + } + // Center point + Blockly.utils.dom.createSvgElement( + "circle", + { + cx: this.HALF, + cy: this.HALF, + r: this.CENTER_RADIUS, + class: "blocklyAngleCenterPoint", + }, + svg + ); + // Handle group: a circle and the arrow image + this.handle_ = Blockly.utils.dom.createSvgElement("g", {}, svg); + Blockly.utils.dom.createSvgElement( + "circle", + { + cx: 0, + cy: 0, + r: this.HANDLE_RADIUS, + class: "blocklyAngleDragHandle", + }, + this.handle_ + ); + this.arrowSvg_ = Blockly.utils.dom.createSvgElement( + "image", + { + width: this.ARROW_WIDTH, + height: this.ARROW_WIDTH, + x: -this.ARROW_WIDTH / 2, + y: -this.ARROW_WIDTH / 2, + class: "blocklyAngleDragArrow", + }, + this.handle_ + ); + this.arrowSvg_.setAttributeNS( + "http://www.w3.org/1999/xlink", + "xlink:href", + Blockly.getMainWorkspace().options.pathToMedia + this.ARROW_SVG_PATH + ); + + Blockly.DropDownDiv.setColour( + this.getSourceBlock().getParent().getColour(), + this.getSourceBlock().getColourTertiary() + ); + Blockly.DropDownDiv.showPositionedByBlock(this, this.getSourceBlock()); + + this.mouseDownWrapper_ = Blockly.browserEvents.bind( + this.handle_, + "mousedown", + this, + this.onMouseDown + ); + + this.updateGraph_(); + } + + /** + * Set the angle to match the mouse's position. + * @param {!Event} e Mouse move event. + */ + onMouseDown() { + this.mouseMoveWrapper_ = Blockly.browserEvents.bind( + document.body, + "mousemove", + this, + this.onMouseMove + ); + this.mouseUpWrapper_ = Blockly.browserEvents.bind( + document.body, + "mouseup", + this, + this.onMouseUp + ); + } + + /** + * Set the angle to match the mouse's position. + * @param {!Event} e Mouse move event. + */ + onMouseUp() { + Blockly.browserEvents.unbind(this.mouseMoveWrapper_); + Blockly.browserEvents.unbind(this.mouseUpWrapper_); + } + + /** + * Set the angle to match the mouse's position. + * @param {!Event} e Mouse move event. + */ + onMouseMove(e) { + e.preventDefault(); + var bBox = this.gauge_.ownerSVGElement.getBoundingClientRect(); + var dx = e.clientX - bBox.left - this.HALF; + var dy = e.clientY - bBox.top - this.HALF; + var angle = Math.atan(-dy / dx); + if (isNaN(angle)) { + // This shouldn't happen, but let's not let this error propagate further. + return; + } + angle = this.toDegrees(angle); + // 0: East, 90: North, 180: West, 270: South. + if (dx < 0) { + angle += 180; + } else if (dy > 0) { + angle += 360; + } + if (this.CLOCKWISE) { + angle = this.OFFSET + 360 - angle; + } else { + angle -= this.OFFSET; + } + if (this.ROUND) { + angle = Math.round(angle / this.ROUND) * this.ROUND; + } + this.setValue(angle); + this.setEditorValue_(this.getValue()); + this.resizeEditor_(); + } + + /** + * Redraw the graph with the current angle. + * @private + */ + updateGraph_() { + if (!this.gauge_) { + return; + } + var angleDegrees = (this.getValue() % 360) + this.OFFSET; + var angleRadians = this.toRadians(angleDegrees); + var path = ["M ", this.HALF, ",", this.HALF]; + var x2 = this.HALF; + var y2 = this.HALF; + if (!isNaN(angleRadians)) { + var angle1 = this.toRadians(this.OFFSET); + var x1 = Math.cos(angle1) * this.RADIUS; + var y1 = Math.sin(angle1) * -this.RADIUS; + if (this.CLOCKWISE) { + angleRadians = 2 * angle1 - angleRadians; + } + x2 += Math.cos(angleRadians) * this.RADIUS; + y2 -= Math.sin(angleRadians) * this.RADIUS; + // Use large arc only if input value is greater than wrap + var largeFlag = Math.abs(angleDegrees - this.OFFSET) > 180 ? 1 : 0; + var sweepFlag = Number(this.CLOCKWISE); + if (angleDegrees < this.OFFSET) { + sweepFlag = 1 - sweepFlag; // Sweep opposite direction if less than the offset + } + path.push( + " l ", + x1, + ",", + y1, + " A ", + this.RADIUS, + ",", + this.RADIUS, + " 0 ", + largeFlag, + " ", + sweepFlag, + " ", + x2, + ",", + y2, + " z" + ); + + // Image rotation needs to be set in degrees + if (this.CLOCKWISE) { + var imageRotation = angleDegrees + 2 * this.OFFSET; + } else { + var imageRotation = -angleDegrees; + } + this.arrowSvg_.setAttribute("transform", "rotate(" + imageRotation + ")"); + } + this.gauge_.setAttribute("d", path.join("")); + this.line_.setAttribute("x2", x2); + this.line_.setAttribute("y2", y2); + this.handle_.setAttribute("transform", "translate(" + x2 + "," + y2 + ")"); + } + + /** + * Ensure that only an angle may be entered. + * @param {string} text The user's text. + * @return {?string} A string representing a valid angle, or null if invalid. + */ + doClassValidation_(text) { + if (text === null) { + return null; + } + var n = parseFloat(text || 0); + if (isNaN(n)) { + return null; + } + n = n % 360; + if (n < 0) { + n += 360; + } + if (n > this.WRAP) { + n -= 360; + } + return Number(n); + } + + doValueUpdate_(newValue) { + super.doValueUpdate_(newValue); + this.updateGraph_(); + } + + toDegrees(radians) { + return (radians * 180) / Math.PI; + } + + toRadians(degrees) { + return (degrees * Math.PI) / 180; + } +} + +Blockly.fieldRegistry.register("field_angle", FieldAngle); diff --git a/src/index.js b/src/index.js index 14dfb96749..e8ce1b7c66 100644 --- a/src/index.js +++ b/src/index.js @@ -5,8 +5,6 @@ */ import * as Blockly from "blockly/core"; -import { registerFieldAngle } from "@blockly/field-angle"; -registerFieldAngle(); import "./blocks/colour.js"; import "./blocks/math.js"; import "./blocks/matrix.js"; @@ -58,6 +56,7 @@ export * from "./block_reporting.js"; export * from "./categories.js"; export * from "./procedures.js"; export * from "./colours.js"; +export * from "./fields/field_angle.js"; export * from "./fields/field_colour_slider.js"; export * from "./fields/field_matrix.js"; export * from "./fields/field_note.js"; From 3811d93f57c2a72a8a830a7326e2d27694bec7b7 Mon Sep 17 00:00:00 2001 From: Aaron Dodson Date: Wed, 28 Aug 2024 11:03:34 -0700 Subject: [PATCH 075/130] fix: select new variable blocks' monitor checkboxes after creation (#140) --- src/scratch_continuous_toolbox.js | 10 ++++++++++ src/variables.js | 4 ++-- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/scratch_continuous_toolbox.js b/src/scratch_continuous_toolbox.js index 2a9f7b0950..87bb5cf4b6 100644 --- a/src/scratch_continuous_toolbox.js +++ b/src/scratch_continuous_toolbox.js @@ -2,11 +2,21 @@ import * as Blockly from "blockly/core"; import { ContinuousToolbox } from "@blockly/continuous-toolbox"; export class ScratchContinuousToolbox extends ContinuousToolbox { + postRenderCallbacks = []; + refreshSelection() { // Intentionally a no-op, Scratch manually manages refreshing the toolbox via forceRerender(). } forceRerender() { super.refreshSelection(); + let callback; + while ((callback = this.postRenderCallbacks.shift())) { + callback(); + } + } + + runAfterRerender(callback) { + this.postRenderCallbacks.push(callback); } } diff --git a/src/variables.js b/src/variables.js index 7fac2359aa..2397013096 100644 --- a/src/variables.js +++ b/src/variables.js @@ -117,9 +117,9 @@ export function createVariable(workspace, opt_callback, opt_type) { var flyout = workspace.isFlyout ? workspace : workspace.getFlyout(); var variableBlockId = variable.getId(); - if (flyout.setCheckboxState) { + workspace.getToolbox().runAfterRerender(() => { flyout.setCheckboxState(variableBlockId, true); - } + }); if (opt_callback) { opt_callback(variableBlockId); From d3e1a1b39099ec8a8ca72f3cac21fac5d588d449 Mon Sep 17 00:00:00 2001 From: Aaron Dodson Date: Wed, 28 Aug 2024 14:00:33 -0700 Subject: [PATCH 076/130] fix: fix toolbox category selection (#141) --- src/scratch_continuous_toolbox.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/scratch_continuous_toolbox.js b/src/scratch_continuous_toolbox.js index 87bb5cf4b6..cfeceabfda 100644 --- a/src/scratch_continuous_toolbox.js +++ b/src/scratch_continuous_toolbox.js @@ -9,11 +9,13 @@ export class ScratchContinuousToolbox extends ContinuousToolbox { } forceRerender() { + const selectedCategoryName = this.selectedItem_?.getName(); super.refreshSelection(); let callback; while ((callback = this.postRenderCallbacks.shift())) { callback(); } + this.selectCategoryByName(selectedCategoryName); } runAfterRerender(callback) { From 6fbc2e5ef4d24279be3073021319e717963d76e4 Mon Sep 17 00:00:00 2001 From: Aaron Dodson Date: Thu, 29 Aug 2024 13:00:25 -0700 Subject: [PATCH 077/130] fix: fix the styling of contextual menus (#147) --- src/colours.js | 2 +- src/css.js | 220 ++----------------------------------------------- 2 files changed, 8 insertions(+), 214 deletions(-) diff --git a/src/colours.js b/src/colours.js index c1f8cfab54..dafdadd244 100644 --- a/src/colours.js +++ b/src/colours.js @@ -120,7 +120,7 @@ const cssColours = { numPadText: "white", // Do not use hex here, it cannot be inlined with data-uri SVG valueReportBackground: "#FFFFFF", valueReportBorder: "#AAAAAA", - menuHover: "rgba(0, 0, 0, 0.2)", + menuHover: "rgba(77, 151, 255, .25)", }; const Colours = { diff --git a/src/css.js b/src/css.js index d5127c7c40..73693c16af 100644 --- a/src/css.js +++ b/src/css.js @@ -735,12 +735,6 @@ const styles = ` background-color: var(--colour-numPadBackground); } - /* Override the default Closure URL. */ - .blocklyWidgetDiv .goog-option-selected .goog-menuitem-checkbox, - .blocklyWidgetDiv .goog-option-selected .goog-menuitem-icon { - background: url(<<>>/sprites.png) no-repeat -48px -16px !important; - } - /* Category tree in Toolbox. */ .blocklyToolboxDiv { background-color: var(--colour-toolbox); @@ -966,7 +960,7 @@ const styles = ` * @author attila@google.com (Attila Bodis) */ - .blocklyWidgetDiv .goog-menu { + .blocklyWidgetDiv .blocklyMenu { background: #fff; border-color: #ccc #666 #666 #ccc; border-style: solid; @@ -984,223 +978,23 @@ const styles = ` box-shadow: none; } - .blocklyWidgetDiv .blocklyMenu.blocklyFocused { + .blocklyWidgetDiv .blocklyMenu:focus { box-shadow: none; } - .blocklyDropDownDiv .goog-menu { + .blocklyDropDownDiv .blocklyMenu { cursor: default; font: normal 13px "Helvetica Neue", Helvetica, sans-serif; outline: none; z-index: 20000; /* Arbitrary, but some apps depend on it... */ } - /* Copied from: goog/css/menuitem.css */ - /* - * Copyright 2009 The Closure Library Authors. All Rights Reserved. - * - * Use of this source code is governed by the Apache License, Version 2.0. - * See the COPYING file for details. - */ - - /** - * Standard styling for menus created by goog.ui.MenuItemRenderer. - * - * @author attila@google.com (Attila Bodis) - */ - - /** - * State: resting. - * - * NOTE(mleibman,chrishenry): - * The RTL support in Closure is provided via two mechanisms -- "rtl" CSS - * classes and BiDi flipping done by the CSS compiler. Closure supports RTL - * with or without the use of the CSS compiler. In order for them not - * to conflict with each other, the "rtl" CSS classes need to have the #noflip - * annotation. The non-rtl counterparts should ideally have them as well, but, - * since .goog-menuitem existed without .goog-menuitem-rtl for so long before - * being added, there is a risk of people having templates where they are not - * rendering the .goog-menuitem-rtl class when in RTL and instead rely solely - * on the BiDi flipping by the CSS compiler. That's why we're not adding the - * #noflip to .goog-menuitem. - */ - .blocklyWidgetDiv .goog-menuitem { - font: normal 13px "Helvetica Neue", Helvetica, sans-serif; - list-style: none; - margin: 0; - /* 28px on the left for icon or checkbox; 7em on the right for shortcut. */ - padding: 4px 7em 4px 28px; - white-space: nowrap; - } - - .blocklyDropDownDiv .goog-menuitem { - color: var(--colour-text); - font: normal 13px "Helvetica Neue", Helvetica, sans-serif; - font-weight: bold; - list-style: none; - margin: 0; - min-height: 24px; - /* 28px on the left for icon or checkbox; 7em on the right for shortcut. */ - padding: 4px 7em 4px 28px; - white-space: nowrap; - } - - /* BiDi override for the resting state. */ - /* #noflip */ - .blocklyWidgetDiv .goog-menuitem.goog-menuitem-rtl, , - .blocklyDropDownDiv .goog-menuitem.goog-menuitem-rtl { - /* Flip left/right padding for BiDi. */ - padding-left: 7em; - padding-right: 28px; - } - - /* If a menu doesn't have checkable items or items with icons, remove padding. */ - .blocklyWidgetDiv .goog-menu-nocheckbox .goog-menuitem, - .blocklyWidgetDiv .goog-menu-noicon .goog-menuitem, , - .blocklyDropDownDiv .goog-menu-nocheckbox .goog-menuitem, - .blocklyDropDownDiv .goog-menu-noicon .goog-menuitem { , - padding-left: 12px; - } - - /* - * If a menu doesn't have items with shortcuts, leave just enough room for - * submenu arrows, if they are rendered. - */ - .blocklyWidgetDiv .goog-menu-noaccel .goog-menuitem, , - .blocklyDropDownDiv .goog-menu-noaccel .goog-menuitem { - padding-right: 20px; - } - - .blocklyWidgetDiv .goog-menuitem-content , - .blocklyDropDownDiv .goog-menuitem-content { - font: normal 13px "Helvetica Neue", Helvetica, sans-serif; - } - - /* State: disabled. */ - .blocklyWidgetDiv .goog-menuitem-disabled .goog-menuitem-accel, - .blocklyWidgetDiv .goog-menuitem-disabled .goog-menuitem-content, , - .blocklyDropDownDiv .goog-menuitem-disabled .goog-menuitem-accel, - .blocklyDropDownDiv .goog-menuitem-disabled .goog-menuitem-content { - color: #ccc !important; - } - - .blocklyWidgetDiv .goog-menuitem-disabled .goog-menuitem-icon, , - .blocklyDropDownDiv .goog-menuitem-disabled .goog-menuitem-icon { - opacity: 0.3; - -moz-opacity: 0.3; - filter: alpha(opacity=30); - } - - /* State: hover. */ - .blocklyWidgetDiv .goog-menuitem-highlight, - .blocklyWidgetDiv .goog-menuitem-hover { - background-color: #d6e9f8; - /* Use an explicit top and bottom border so that the selection is visible - * in high contrast mode. */ - border-color: #d6e9f8; - border-style: dotted; - border-width: 1px 0; - padding-bottom: 3px; - padding-top: 3px; - } - - .blocklyDropDownDiv .goog-menuitem-highlight, - .blocklyDropDownDiv .goog-menuitem-hover { - background-color: var(--colour-menuHover); - } - - /* State: selected/checked. */ - .blocklyWidgetDiv .goog-menuitem-checkbox, - .blocklyWidgetDiv .goog-menuitem-icon, , - .blocklyDropDownDiv .goog-menuitem-checkbox, - .blocklyDropDownDiv .goog-menuitem-icon { - background-repeat: no-repeat; - height: 16px; - left: 6px; - position: absolute; - right: auto; - vertical-align: middle; - width: 16px; - } - - .blocklyWidgetDiv .goog-option-selected .goog-menuitem-checkbox, - .blocklyWidgetDiv .goog-option-selected .goog-menuitem-icon, - .blocklyDropDownDiv .goog-option-selected .goog-menuitem-checkbox, - .blocklyDropDownDiv .goog-option-selected .goog-menuitem-icon { - /* Client apps may override the URL at which they serve the sprite. */ - background: url(<<>>/sprites.png) no-repeat -48px -16px !important; - position: static; /* Scroll with the menu. */ - float: left; - margin-left: -24px; - } - - /* BiDi override for the selected/checked state. */ - /* #noflip */ - .blocklyWidgetDiv .goog-menuitem-rtl .goog-menuitem-checkbox, - .blocklyWidgetDiv .goog-menuitem-rtl .goog-menuitem-icon, - .blocklyDropDownDiv .goog-menuitem-rtl .goog-menuitem-checkbox, - .blocklyDropDownDiv .goog-menuitem-rtl .goog-menuitem-icon { - /* Flip left/right positioning. */ - float: right; - margin-right: -24px; - } - - /* Keyboard shortcut ("accelerator") style. */ - .blocklyWidgetDiv .goog-menuitem-accel, , - .blocklyDropDownDiv .goog-menuitem-accel { - color: #999; - /* Keyboard shortcuts are untranslated; always left-to-right. */ - /* #noflip */ - direction: ltr; - left: auto; - padding: 0 6px; - position: absolute; - right: 0; - text-align: right; - } - - /* BiDi override for shortcut style. */ - /* #noflip */ - .blocklyWidgetDiv .goog-menuitem-rtl .goog-menuitem-accel, , - .blocklyDropDownDiv .goog-menuitem-rtl .goog-menuitem-accel { - /* Flip left/right positioning and text alignment. */ - left: 0; - right: auto; - text-align: left; - } - - /* Mnemonic styles. */ - .blocklyWidgetDiv .goog-menuitem-mnemonic-hint, , - .blocklyDropDownDiv .goog-menuitem-mnemonic-hint { - text-decoration: underline; - } - - .blocklyWidgetDiv .goog-menuitem-mnemonic-separator, , - .blocklyDropDownDiv .goog-menuitem-mnemonic-separator { - color: #999; - font-size: 12px; - padding-left: 4px; + .blocklyWidgetDiv .blocklyMenu .blocklyMenuItem:hover { + background: var(--colour-menuHover); } - /* Copied from: goog/css/menuseparator.css */ - /* - * Copyright 2009 The Closure Library Authors. All Rights Reserved. - * - * Use of this source code is governed by the Apache License, Version 2.0. - * See the COPYING file for details. - */ - - /** - * Standard styling for menus created by goog.ui.MenuSeparatorRenderer. - * - * @author attila@google.com (Attila Bodis) - */ - - .blocklyWidgetDiv .goog-menuseparator, , - .blocklyDropDownDiv .goog-menuseparator { - border-top: 1px solid #ccc; - margin: 4px 0; - padding: 0; + .blocklyWidgetDiv .blocklyMenu .blocklyMenuItemDisabled.blocklyMenuItem:hover { + background: none; } .blocklyFlyoutCheckbox { From 40eee91711fb2cc76494221ce2f8b08fc5d9f868 Mon Sep 17 00:00:00 2001 From: Aaron Dodson Date: Thu, 29 Aug 2024 13:03:49 -0700 Subject: [PATCH 078/130] fix: fix dropdown menu metrics (#148) --- src/css.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/css.js b/src/css.js index 73693c16af..0b3e39be2e 100644 --- a/src/css.js +++ b/src/css.js @@ -1142,6 +1142,8 @@ const styles = ` .blocklyDropDownDiv .blocklyMenuItem { color: #fff; font-weight: bold; + min-height: 32px; + padding: 4px 7em 4px 28px; } .blocklyToolboxSelected .blocklyTreeLabel { color: var(--colour-toolboxText); From 8e165cec9a45f5f9d17f2255ed3fd58f834881f7 Mon Sep 17 00:00:00 2001 From: Aaron Dodson Date: Fri, 30 Aug 2024 14:25:02 -0700 Subject: [PATCH 079/130] fix: fix a crash when adding a broadcast message (#150) --- src/variables.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/variables.js b/src/variables.js index 2397013096..20e1212362 100644 --- a/src/variables.js +++ b/src/variables.js @@ -117,7 +117,7 @@ export function createVariable(workspace, opt_callback, opt_type) { var flyout = workspace.isFlyout ? workspace : workspace.getFlyout(); var variableBlockId = variable.getId(); - workspace.getToolbox().runAfterRerender(() => { + workspace.getToolbox()?.runAfterRerender(() => { flyout.setCheckboxState(variableBlockId, true); }); From 0e802773ce3749a3f74f5fec986aba54312a56cd Mon Sep 17 00:00:00 2001 From: Aaron Dodson Date: Tue, 3 Sep 2024 11:10:52 -0700 Subject: [PATCH 080/130] fix: fix styling of dropdown menus (#152) * chore: remove block definitions monkeypatched by scratch-gui * refactor: use block styles instead of colors to color blocks * fix: fix highlighting of dropdown fields in shadow blocks * fix: prevent white hover highlight on non-shadow dropdown fields * fix: make selected dropdown color changes more robust * chore: remove duplicative sound colors * refactor: move block colors into a custom theme * chore: condense placeholder block definitions --- src/blocks/control.js | 31 ++------ src/blocks/event.js | 25 ++----- src/blocks/looks.js | 50 +++---------- src/blocks/math.js | 26 ++----- src/blocks/motion.js | 78 ++++---------------- src/blocks/note.js | 6 +- src/blocks/procedures.js | 13 +--- src/blocks/sensing.js | 116 +++++------------------------- src/blocks/sound.js | 10 ++- src/blocks/text.js | 6 +- src/blocks/vertical_extensions.js | 28 ++------ src/colours.js | 108 +--------------------------- src/css.js | 18 +++-- src/fields/field_dropdown.js | 31 ++++++++ src/fields/field_variable.js | 16 +++++ src/index.js | 6 +- src/scratch_theme.js | 84 ++++++++++++++++++++++ 17 files changed, 213 insertions(+), 439 deletions(-) create mode 100644 src/fields/field_dropdown.js create mode 100644 src/scratch_theme.js diff --git a/src/blocks/control.js b/src/blocks/control.js index bad0d43203..c7066f813d 100644 --- a/src/blocks/control.js +++ b/src/blocks/control.js @@ -20,7 +20,6 @@ import * as Blockly from "blockly/core"; import { Categories } from "../categories.js"; -import { Colours } from "../colours.js"; Blockly.Blocks["control_forever"] = { /** @@ -198,12 +197,7 @@ Blockly.Blocks["control_stop"] = { this.appendDummyInput() .appendField(Blockly.Msg.CONTROL_STOP) .appendField(stopDropdown, "STOP_OPTION"); - this.setColour( - Colours.control.primary, - Colours.control.secondary, - Colours.control.tertiary, - Colours.control.quaternary - ); + this.setStyle("colours_control"); this.setPreviousStatement(true); }, }; @@ -381,25 +375,10 @@ Blockly.Blocks["control_start_as_clone"] = { }, }; -Blockly.Blocks["control_create_clone_of_menu"] = { - /** - * Create-clone drop-down menu. - * @this Blockly.Block - */ - init: function () { - this.jsonInit({ - message0: "%1", - args0: [ - { - type: "field_dropdown", - name: "CLONE_OPTION", - options: [[Blockly.Msg.CONTROL_CREATECLONEOF_MYSELF, "_myself_"]], - }, - ], - extensions: ["colours_control", "output_string"], - }); - }, -}; +/** + * Create-clone drop-down menu. Populated dynamically by scratch-gui. + */ +Blockly.Blocks["control_create_clone_of_menu"] = {}; Blockly.Blocks["control_create_clone_of"] = { /** diff --git a/src/blocks/event.js b/src/blocks/event.js index 20ac9a0768..378006586e 100644 --- a/src/blocks/event.js +++ b/src/blocks/event.js @@ -142,26 +142,11 @@ Blockly.Blocks["event_whenbroadcastreceived"] = { }, }; -Blockly.Blocks["event_whenbackdropswitchesto"] = { - /** - * Block for when the current backdrop switched to a selected backdrop. - * @this Blockly.Block - */ - init: function () { - this.jsonInit({ - message0: Blockly.Msg.EVENT_WHENBACKDROPSWITCHESTO, - args0: [ - { - type: "field_dropdown", - name: "BACKDROP", - options: [["backdrop1", "BACKDROP1"]], - }, - ], - category: Categories.event, - extensions: ["colours_event", "shape_hat"], - }); - }, -}; +/** + * Block for when the current backdrop switched to a selected backdrop. + * Populated dynamically by scratch-gui. + */ +Blockly.Blocks["event_whenbackdropswitchesto"] = {}; Blockly.Blocks["event_whengreaterthan"] = { /** diff --git a/src/blocks/looks.js b/src/blocks/looks.js index 72a7443490..023e7d7162 100644 --- a/src/blocks/looks.js +++ b/src/blocks/looks.js @@ -339,28 +339,10 @@ Blockly.Blocks["looks_setstretchto"] = { }, }; -Blockly.Blocks["looks_costume"] = { - /** - * Costumes drop-down menu. - * @this Blockly.Block - */ - init: function () { - this.jsonInit({ - message0: "%1", - args0: [ - { - type: "field_dropdown", - name: "COSTUME", - options: [ - ["costume1", "COSTUME1"], - ["costume2", "COSTUME2"], - ], - }, - ], - extensions: ["colours_looks", "output_string"], - }); - }, -}; +/** + * Costumes drop-down menu. Populated dynamically by scratch-gui. + */ +Blockly.Blocks["looks_costume"] = {}; Blockly.Blocks["looks_switchcostumeto"] = { /** @@ -416,26 +398,10 @@ Blockly.Blocks["looks_switchbackdropto"] = { }, }; -Blockly.Blocks["looks_backdrops"] = { - /** - * Backdrop list - * @this Blockly.Block - */ - init: function () { - this.jsonInit({ - id: "looks_backdrops", - message0: "%1", - args0: [ - { - type: "field_dropdown", - name: "BACKDROP", - options: [["backdrop1", "BACKDROP1"]], - }, - ], - extensions: ["colours_looks", "output_string"], - }); - }, -}; +/** + * Backdrop list. Populated dynamically by scratch-gui. + */ +Blockly.Blocks["looks_backdrops"] = {}; Blockly.Blocks["looks_gotofrontback"] = { /** diff --git a/src/blocks/math.js b/src/blocks/math.js index ec5075cb5e..81ee5eeefe 100644 --- a/src/blocks/math.js +++ b/src/blocks/math.js @@ -23,7 +23,6 @@ * @author q.neutron@gmail.com (Quynh Neutron) */ import * as Blockly from "blockly/core"; -import { Colours } from "../colours.js"; import * as Constants from "../constants.js"; Blockly.Blocks["math_number"] = { @@ -43,10 +42,7 @@ Blockly.Blocks["math_number"] = { ], output: "Number", outputShape: Constants.OUTPUT_SHAPE_ROUND, - colour: Colours.textField, - colourSecondary: Colours.textField, - colourTertiary: Colours.textField, - colourQuaternary: Colours.textField, + extensions: ["colours_textfield"], }); }, }; @@ -68,10 +64,7 @@ Blockly.Blocks["math_integer"] = { ], output: "Number", outputShape: Constants.OUTPUT_SHAPE_ROUND, - colour: Colours.textField, - colourSecondary: Colours.textField, - colourTertiary: Colours.textField, - colourQuaternary: Colours.textField, + extensions: ["colours_textfield"], }); }, }; @@ -94,10 +87,7 @@ Blockly.Blocks["math_whole_number"] = { ], output: "Number", outputShape: Constants.OUTPUT_SHAPE_ROUND, - colour: Colours.textField, - colourSecondary: Colours.textField, - colourTertiary: Colours.textField, - colourQuaternary: Colours.textField, + extensions: ["colours_textfield"], }); }, }; @@ -119,10 +109,7 @@ Blockly.Blocks["math_positive_number"] = { ], output: "Number", outputShape: Constants.OUTPUT_SHAPE_ROUND, - colour: Colours.textField, - colourSecondary: Colours.textField, - colourTertiary: Colours.textField, - colourQuaternary: Colours.textField, + extensions: ["colours_textfield"], }); }, }; @@ -144,10 +131,7 @@ Blockly.Blocks["math_angle"] = { ], output: "Number", outputShape: Constants.OUTPUT_SHAPE_ROUND, - colour: Colours.textField, - colourSecondary: Colours.textField, - colourTertiary: Colours.textField, - colourQuaternary: Colours.textField, + extensions: ["colours_textfield"], }); }, }; diff --git a/src/blocks/motion.js b/src/blocks/motion.js index 920a033b35..65435172c3 100644 --- a/src/blocks/motion.js +++ b/src/blocks/motion.js @@ -115,28 +115,10 @@ Blockly.Blocks["motion_pointindirection"] = { }, }; -Blockly.Blocks["motion_pointtowards_menu"] = { - /** - * Point towards drop-down menu. - * @this Blockly.Block - */ - init: function () { - this.jsonInit({ - message0: "%1", - args0: [ - { - type: "field_dropdown", - name: "TOWARDS", - options: [ - [Blockly.Msg.MOTION_POINTTOWARDS_POINTER, "_mouse_"], - [Blockly.Msg.MOTION_POINTTOWARDS_RANDOM, "_random_"], - ], - }, - ], - extensions: ["colours_motion", "output_string"], - }); - }, -}; +/** + * Point towards drop-down menu. Populated dynamically by scratch-gui. + */ +Blockly.Blocks["motion_pointtowards_menu"] = {}; Blockly.Blocks["motion_pointtowards"] = { /** @@ -158,28 +140,10 @@ Blockly.Blocks["motion_pointtowards"] = { }, }; -Blockly.Blocks["motion_goto_menu"] = { - /** - * Go to drop-down menu. - * @this Blockly.Block - */ - init: function () { - this.jsonInit({ - message0: "%1", - args0: [ - { - type: "field_dropdown", - name: "TO", - options: [ - [Blockly.Msg.MOTION_GOTO_POINTER, "_mouse_"], - [Blockly.Msg.MOTION_GOTO_RANDOM, "_random_"], - ], - }, - ], - extensions: ["colours_motion", "output_string"], - }); - }, -}; +/** + * Go to drop-down menu. Populated dynamically by scratch-gui. + */ +Blockly.Blocks["motion_goto_menu"] = {}; Blockly.Blocks["motion_gotoxy"] = { /** @@ -253,28 +217,10 @@ Blockly.Blocks["motion_glidesecstoxy"] = { }, }; -Blockly.Blocks["motion_glideto_menu"] = { - /** - * Glide to drop-down menu - * @this Blockly.Block - */ - init: function () { - this.jsonInit({ - message0: "%1", - args0: [ - { - type: "field_dropdown", - name: "TO", - options: [ - [Blockly.Msg.MOTION_GLIDETO_POINTER, "_mouse_"], - [Blockly.Msg.MOTION_GLIDETO_RANDOM, "_random_"], - ], - }, - ], - extensions: ["colours_motion", "output_string"], - }); - }, -}; +/** + * Glide to drop-down menu. Populated dynamically by scratch-gui. + */ +Blockly.Blocks["motion_glideto_menu"] = {}; Blockly.Blocks["motion_glideto"] = { /** diff --git a/src/blocks/note.js b/src/blocks/note.js index 2256798aac..9a936744a0 100644 --- a/src/blocks/note.js +++ b/src/blocks/note.js @@ -23,7 +23,6 @@ * @author ericr@media.mit.edu (Eric Rosenbaum) */ import * as Blockly from "blockly/core"; -import { Colours } from "../colours.js"; import * as Constants from "../constants.js"; Blockly.Blocks["note"] = { @@ -43,10 +42,7 @@ Blockly.Blocks["note"] = { ], outputShape: Constants.OUTPUT_SHAPE_ROUND, output: "Number", - colour: Colours.textField, - colourSecondary: Colours.textField, - colourTertiary: Colours.textField, - colourQuaternary: Colours.textField, + extensions: ["colours_textfield"], }); }, }; diff --git a/src/blocks/procedures.js b/src/blocks/procedures.js index 68e8b4e5ca..20b65e217c 100644 --- a/src/blocks/procedures.js +++ b/src/blocks/procedures.js @@ -23,7 +23,6 @@ */ import * as Blockly from "blockly/core"; -import { Colours } from "../colours.js"; import { FieldTextInputRemovable } from "../fields/field_textinput_removable.js"; class DuplicateOnDragDraggable { @@ -984,11 +983,7 @@ Blockly.Blocks["argument_editor_boolean"] = { text: "foo", }, ], - colour: Colours.textField, - colourSecondary: Colours.textField, - colourTertiary: Colours.textField, - colourQuaternary: Colours.textField, - extensions: ["output_boolean"], + extensions: ["colours_textfield", "output_boolean"], }); // Exist on declaration and arguments editors, with different implementations. @@ -1007,11 +1002,7 @@ Blockly.Blocks["argument_editor_string_number"] = { text: "foo", }, ], - colour: Colours.textField, - colourSecondary: Colours.textField, - colourTertiary: Colours.textField, - colourQuaternary: Colours.textField, - extensions: ["output_number", "output_string"], + extensions: ["colours_textfield", "output_number", "output_string"], }); // Exist on declaration and arguments editors, with different implementations. diff --git a/src/blocks/sensing.js b/src/blocks/sensing.js index c2f4c79424..7c8567ad72 100644 --- a/src/blocks/sensing.js +++ b/src/blocks/sensing.js @@ -42,28 +42,10 @@ Blockly.Blocks["sensing_touchingobject"] = { }, }; -Blockly.Blocks["sensing_touchingobjectmenu"] = { - /** - * "Touching [Object]" Block Menu. - * @this Blockly.Block - */ - init: function () { - this.jsonInit({ - message0: "%1", - args0: [ - { - type: "field_dropdown", - name: "TOUCHINGOBJECTMENU", - options: [ - [Blockly.Msg.SENSING_TOUCHINGOBJECT_POINTER, "_mouse_"], - [Blockly.Msg.SENSING_TOUCHINGOBJECT_EDGE, "_edge_"], - ], - }, - ], - extensions: ["colours_sensing", "output_string"], - }); - }, -}; +/** + * "Touching [Object]" Block Menu. Populated dynamically by scratch-gui. + */ +Blockly.Blocks["sensing_touchingobjectmenu"] = {}; Blockly.Blocks["sensing_touchingcolor"] = { /** @@ -129,25 +111,10 @@ Blockly.Blocks["sensing_distanceto"] = { }, }; -Blockly.Blocks["sensing_distancetomenu"] = { - /** - * "Distance to [Object]" Block Menu. - * @this Blockly.Block - */ - init: function () { - this.jsonInit({ - message0: "%1", - args0: [ - { - type: "field_dropdown", - name: "DISTANCETOMENU", - options: [[Blockly.Msg.SENSING_DISTANCETO_POINTER, "_mouse_"]], - }, - ], - extensions: ["colours_sensing", "output_string"], - }); - }, -}; +/** + * "Distance to [Object]" Block Menu. Populated dynamically by scratch-gui. + */ +Blockly.Blocks["sensing_distancetomenu"] = {}; Blockly.Blocks["sensing_askandwait"] = { /** @@ -393,66 +360,15 @@ Blockly.Blocks["sensing_resettimer"] = { }, }; -Blockly.Blocks["sensing_of_object_menu"] = { - /** - * "* of _" object menu. - * @this Blockly.Block - */ - init: function () { - this.jsonInit({ - message0: "%1", - args0: [ - { - type: "field_dropdown", - name: "OBJECT", - options: [ - ["Sprite1", "Sprite1"], - ["Stage", "_stage_"], - ], - }, - ], - category: Categories.sensing, - extensions: ["colours_sensing", "output_string"], - }); - }, -}; +/** + * "* of _" object menu. Populated dynamically by scratch-gui. + */ +Blockly.Blocks["sensing_of_object_menu"] = {}; -Blockly.Blocks["sensing_of"] = { - /** - * Block to report properties of sprites. - * @this Blockly.Block - */ - init: function () { - this.jsonInit({ - message0: Blockly.Msg.SENSING_OF, - args0: [ - { - type: "field_dropdown", - name: "PROPERTY", - options: [ - [Blockly.Msg.SENSING_OF_XPOSITION, "x position"], - [Blockly.Msg.SENSING_OF_YPOSITION, "y position"], - [Blockly.Msg.SENSING_OF_DIRECTION, "direction"], - [Blockly.Msg.SENSING_OF_COSTUMENUMBER, "costume #"], - [Blockly.Msg.SENSING_OF_COSTUMENAME, "costume name"], - [Blockly.Msg.SENSING_OF_SIZE, "size"], - [Blockly.Msg.SENSING_OF_VOLUME, "volume"], - [Blockly.Msg.SENSING_OF_BACKDROPNUMBER, "backdrop #"], - [Blockly.Msg.SENSING_OF_BACKDROPNAME, "backdrop name"], - ], - }, - { - type: "input_value", - name: "OBJECT", - }, - ], - output: true, - category: Categories.sensing, - outputShape: Constants.OUTPUT_SHAPE_ROUND, - extensions: ["colours_sensing"], - }); - }, -}; +/** + * Block to report properties of sprites. Populated dynamically by scratch-gui. + */ +Blockly.Blocks["sensing_of"] = {}; Blockly.Blocks["sensing_current"] = { /** diff --git a/src/blocks/sound.js b/src/blocks/sound.js index 16941408ec..75763e87e6 100644 --- a/src/blocks/sound.js +++ b/src/blocks/sound.js @@ -21,12 +21,10 @@ import * as Blockly from "blockly/core"; import { Categories } from "../categories.js"; -Blockly.Blocks["sound_sounds_menu"] = { - /** - * Sound effects drop-down menu. Populated dynamically by scratch-gui. - * @this Blockly.Block - */ -}; +/** + * Sound effects drop-down menu. Populated dynamically by scratch-gui. + */ +Blockly.Blocks["sound_sounds_menu"] = {}; Blockly.Blocks["sound_play"] = { /** diff --git a/src/blocks/text.js b/src/blocks/text.js index f404ddee19..5e2cc990ba 100644 --- a/src/blocks/text.js +++ b/src/blocks/text.js @@ -23,7 +23,6 @@ * @author fraser@google.com (Neil Fraser) */ import * as Blockly from "blockly/core"; -import { Colours } from "../colours.js"; Blockly.Blocks["text"] = { /** @@ -40,10 +39,7 @@ Blockly.Blocks["text"] = { }, ], output: "String", - colour: Colours.textField, - colourSecondary: Colours.textField, - colourTertiary: Colours.textField, - colourQuaternary: Colours.textField, + extensions: ["colours_textfield"], }); }, }; diff --git a/src/blocks/vertical_extensions.js b/src/blocks/vertical_extensions.js index 474fbd5ace..7bbdc8608e 100644 --- a/src/blocks/vertical_extensions.js +++ b/src/blocks/vertical_extensions.js @@ -26,41 +26,24 @@ * @author fenichel@google.com (Rachel Fenichel) */ import * as Blockly from "blockly/core"; -import { Colours } from "../colours.js"; import { ScratchProcedures } from "../procedures.js"; import * as Constants from "../constants.js"; const VerticalExtensions = {}; /** * Helper function that generates an extension based on a category name. - * The generated function will set primary, secondary, tertiary, and quaternary - * colours based on the category name. + * The generated function will set the block's style based on the category name. * @param {String} category The name of the category to set colours for. * @return {function} An extension function that sets colours based on the given * category. */ VerticalExtensions.colourHelper = function (category) { - var colours = Colours[category]; - if ( - !( - colours && - colours.primary && - colours.secondary && - colours.tertiary && - colours.quaternary - ) - ) { - throw new Error('Could not find colours for category "' + category + '"'); - } /** - * Set the primary, secondary, tertiary, and quaternary colours on this block for - * the given category. + * Set the block style on this block for the given category. * @this {Blockly.Block} */ return function () { - this.setColour(colours.primary); - // this.setColourFromRawValues_(colours.primary, colours.secondary, - // colours.tertiary, colours.quaternary); + this.setStyle(`colours_${category}`); }; }; @@ -68,10 +51,7 @@ VerticalExtensions.colourHelper = function (category) { * Extension to set the colours of a text field, which are all the same. */ VerticalExtensions.COLOUR_TEXTFIELD = function () { - this.setColour(colours.textField); - // this.setColourFromRawValues_(Colours.textField, - // Colours.textField, Colours.textField, - // Colours.textField); + VerticalExtensions.colourHelper("textField").apply(this); }; /** diff --git a/src/colours.js b/src/colours.js index dafdadd244..86b2234485 100644 --- a/src/colours.js +++ b/src/colours.js @@ -19,77 +19,9 @@ */ import * as Blockly from "blockly/core"; -const cssColours = { - // SVG colours: these must be specificed in #RRGGBB style +const Colours = { + // SVG colours: these must be specified in #RRGGBB style // To add an opacity, this must be specified as a separate property (for SVG fill-opacity) - motion: { - primary: "#4C97FF", - secondary: "#4280D7", - tertiary: "#3373CC", - quaternary: "#3373CC", - }, - looks: { - primary: "#9966FF", - secondary: "#855CD6", - tertiary: "#774DCB", - quaternary: "#774DCB", - }, - sounds: { - primary: "#CF63CF", - secondary: "#C94FC9", - tertiary: "#BD42BD", - quaternary: "#BD42BD", - }, - control: { - primary: "#FFAB19", - secondary: "#EC9C13", - tertiary: "#CF8B17", - quaternary: "#CF8B17", - }, - event: { - primary: "#FFBF00", - secondary: "#E6AC00", - tertiary: "#CC9900", - quaternary: "#CC9900", - }, - sensing: { - primary: "#5CB1D6", - secondary: "#47A8D1", - tertiary: "#2E8EB8", - quaternary: "#2E8EB8", - }, - pen: { - primary: "#0fBD8C", - secondary: "#0DA57A", - tertiary: "#0B8E69", - quaternary: "#0B8E69", - }, - operators: { - primary: "#59C059", - secondary: "#46B946", - tertiary: "#389438", - quaternary: "#389438", - }, - data: { - primary: "#FF8C1A", - secondary: "#FF8000", - tertiary: "#DB6E00", - quaternary: "#DB6E00", - }, - // This is not a new category, but rather for differentiation - // between lists and scalar variables. - data_lists: { - primary: "#FF661A", - secondary: "#FF5500", - tertiary: "#E64D00", - quaternary: "#E64D00", - }, - more: { - primary: "#FF6680", - secondary: "#FF4D6A", - tertiary: "#FF3355", - quaternary: "#FF3355", - }, text: "#FFFFFF", workspace: "#F9F9F9", toolboxHover: "#4C97FF", @@ -123,40 +55,6 @@ const cssColours = { menuHover: "rgba(77, 151, 255, .25)", }; -const Colours = { - ...cssColours, - overrideColours: function (colours) { - // Colour overrides provided by the injection - if (colours) { - for (var colourProperty in colours) { - if ( - colours.hasOwnProperty(colourProperty) && - this.hasOwnProperty(colourProperty) - ) { - // If a property is in both colours option and Blockly.Colours, - // set the Blockly.Colours value to the override. - // Override Blockly category color object properties with those - // provided. - var colourPropertyValue = colours[colourProperty]; - if (goog.isObject(colourPropertyValue)) { - for (var colourSequence in colourPropertyValue) { - if ( - colourPropertyValue.hasOwnProperty(colourSequence) && - this[colourProperty].hasOwnProperty(colourSequence) - ) { - this[colourProperty][colourSequence] = - colourPropertyValue[colourSequence]; - } - } - } else { - this[colourProperty] = colourPropertyValue; - } - } - } - } - }, -}; - function varify(coloursObj, prefix = "--colour") { return Object.keys(coloursObj) .map((key) => { @@ -171,7 +69,7 @@ function varify(coloursObj, prefix = "--colour") { } const cssVariables = `:root { - ${varify(cssColours)} + ${varify(Colours)} }`; Blockly.Css.register(cssVariables); diff --git a/src/css.js b/src/css.js index 0b3e39be2e..6074c5c8ed 100644 --- a/src/css.js +++ b/src/css.js @@ -413,19 +413,19 @@ const styles = ` cursor: pointer; } - .scratch-renderer.zelos-theme .blocklyFlyoutLabelText { + .scratch-renderer.scratch-theme .blocklyFlyoutLabelText { font-family: "Helvetica Neue", Helvetica, sans-serif; font-size: 14pt; fill: #575E75; font-weight: bold; } - .scratch-renderer.zelos-theme .blocklyText, - .scratch-renderer.zelos-theme .blocklyHtmlInput { + .scratch-renderer.scratch-theme .blocklyText, + .scratch-renderer.scratch-theme .blocklyHtmlInput { font-weight: 500; } - .scratch-renderer.zelos-theme .blocklyFlyoutButton .blocklyText { + .scratch-renderer.scratch-theme .blocklyFlyoutButton .blocklyText { fill: var(--colour-textFieldText); } @@ -1116,7 +1116,7 @@ const styles = ` transform: rotate(-180deg); } - .scratch-renderer.zelos-theme .blocklyComment .blocklyTextarea { + .scratch-renderer.scratch-theme .blocklyComment .blocklyTextarea { border: none; --commentFillColour: #fef49c; font-size: 12pt; @@ -1125,7 +1125,7 @@ const styles = ` color: #575e75; } - .scratch-renderer.zelos-theme .blocklyCommentText.blocklyText { + .scratch-renderer.scratch-theme .blocklyCommentText.blocklyText { font-weight: 400; } @@ -1159,6 +1159,12 @@ const styles = ` height: 20px; width: 20px; } + + .scratch-renderer.scratch-theme .blocklyDraggable:not(.blocklyDisabled) .blocklyEditableField:not(.blocklyEditing):hover>rect, + .scratch-renderer.scratch-theme .blocklyDraggable:not(.blocklyDisabled) .blocklyEditableField:not(.blocklyEditing):hover>.blocklyPath { + stroke: revert-layer; + stroke-width: 1; + } `; Blockly.Css.register(styles); diff --git a/src/fields/field_dropdown.js b/src/fields/field_dropdown.js new file mode 100644 index 0000000000..bc409c0e39 --- /dev/null +++ b/src/fields/field_dropdown.js @@ -0,0 +1,31 @@ +/** + * @license + * Copyright 2024 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + +import * as Blockly from "blockly/core"; + +class FieldDropdown extends Blockly.FieldDropdown { + showEditor_(event) { + super.showEditor_(event); + const sourceBlock = this.getSourceBlock(); + if (sourceBlock.isShadow()) { + this.originalStyle = sourceBlock.getStyleName(); + sourceBlock.setColour( + sourceBlock.style.colourQuaternary ?? sourceBlock.style.colourTertiary + ); + } + } + + dropdownDispose_() { + super.dropdownDispose_(); + const sourceBlock = this.getSourceBlock(); + if (sourceBlock.isShadow()) { + sourceBlock.setStyle(this.originalStyle); + } + } +} + +Blockly.fieldRegistry.unregister("field_dropdown"); +Blockly.fieldRegistry.register("field_dropdown", FieldDropdown); diff --git a/src/fields/field_variable.js b/src/fields/field_variable.js index d45f846ee8..5e8179414d 100644 --- a/src/fields/field_variable.js +++ b/src/fields/field_variable.js @@ -135,6 +135,22 @@ class FieldVariable extends Blockly.FieldVariable { } super.onItemSelected_(menu, menuItem); } + + showEditor_(event) { + super.showEditor_(event); + const sourceBlock = this.getSourceBlock(); + if (sourceBlock.isShadow()) { + sourceBlock.setColour(sourceBlock.style.colourQuaternary); + } + } + + dropdownDispose_() { + super.dropdownDispose_(); + const sourceBlock = this.getSourceBlock(); + if (sourceBlock.isShadow()) { + sourceBlock.setStyle(`colours_${sourceBlock.type.split("_")[0]}`); + } + } } Blockly.fieldRegistry.unregister("field_variable"); diff --git a/src/index.js b/src/index.js index e8ce1b7c66..fdcb0b28bd 100644 --- a/src/index.js +++ b/src/index.js @@ -34,6 +34,7 @@ import { import { CheckableContinuousFlyout } from "./checkable_continuous_flyout.js"; import { buildGlowFilter, glowStack } from "./glows.js"; import { ScratchContinuousToolbox } from "./scratch_continuous_toolbox.js"; +import { ScratchTheme } from "./scratch_theme.js"; import "./scratch_continuous_category.js"; import "./scratch_comment_icon.js"; import "./scratch_dragger.js"; @@ -47,6 +48,7 @@ import "./events/events_block_comment_delete.js"; import "./events/events_block_comment_move.js"; import "./events/events_block_comment_resize.js"; import "./events/events_scratch_variable_create.js"; +import "./fields/field_dropdown.js"; import "./fields/field_variable.js"; import "./fields/field_variable_getter.js"; import { buildShadowFilter } from "./shadows.js"; @@ -55,7 +57,6 @@ export * from "blockly/core"; export * from "./block_reporting.js"; export * from "./categories.js"; export * from "./procedures.js"; -export * from "./colours.js"; export * from "./fields/field_angle.js"; export * from "./fields/field_colour_slider.js"; export * from "./fields/field_matrix.js"; @@ -72,7 +73,7 @@ export { contextMenuItems }; export function inject(container, options) { Object.assign(options, { renderer: "scratch", - theme: "zelos", + theme: ScratchTheme, plugins: { toolbox: ScratchContinuousToolbox, flyoutsVerticalToolbox: CheckableContinuousFlyout, @@ -80,6 +81,7 @@ export function inject(container, options) { }, }); const workspace = Blockly.inject(container, options); + workspace.getRenderer().getConstants().selectedGlowFilterId = ""; const flyout = workspace.getFlyout(); diff --git a/src/scratch_theme.js b/src/scratch_theme.js new file mode 100644 index 0000000000..2ef5fca698 --- /dev/null +++ b/src/scratch_theme.js @@ -0,0 +1,84 @@ +/** + * @license + * Copyright 2024 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + +import * as Blockly from "blockly/core"; + +const blockStyles = { + colours_motion: { + colourPrimary: "#4C97FF", + colourSecondary: "#4280D7", + colourTertiary: "#3373CC", + colourQuaternary: "#3373CC", + }, + colours_looks: { + colourPrimary: "#9966FF", + colourSecondary: "#855CD6", + colourTertiary: "#774DCB", + colourQuaternary: "#774DCB", + }, + colours_sounds: { + colourPrimary: "#CF63CF", + colourSecondary: "#C94FC9", + colourTertiary: "#BD42BD", + colourQuaternary: "#BD42BD", + }, + colours_control: { + colourPrimary: "#FFAB19", + colourSecondary: "#EC9C13", + colourTertiary: "#CF8B17", + colourQuaternary: "#CF8B17", + }, + colours_event: { + colourPrimary: "#FFBF00", + colourSecondary: "#E6AC00", + colourTertiary: "#CC9900", + colourQuaternary: "#CC9900", + }, + colours_sensing: { + colourPrimary: "#5CB1D6", + colourSecondary: "#47A8D1", + colourTertiary: "#2E8EB8", + colourQuaternary: "#2E8EB8", + }, + colours_pen: { + colourPrimary: "#0fBD8C", + colourSecondary: "#0DA57A", + colourTertiary: "#0B8E69", + colourQuaternary: "#0B8E69", + }, + colours_operators: { + colourPrimary: "#59C059", + colourSecondary: "#46B946", + colourTertiary: "#389438", + colourQuaternary: "#389438", + }, + colours_data: { + colourPrimary: "#FF8C1A", + colourSecondary: "#FF8000", + colourTertiary: "#DB6E00", + colourQuaternary: "#DB6E00", + }, + colours_data_lists: { + colourPrimary: "#FF661A", + colourSecondary: "#FF5500", + colourTertiary: "#E64D00", + colourQuaternary: "#E64D00", + }, + colours_more: { + colourPrimary: "#FF6680", + colourSecondary: "#FF4D6A", + colourTertiary: "#FF3355", + colourQuaternary: "#FF3355", + }, + colours_textfield: { + colourPrimary: "#FFFFFF", + colourSecondary: "#FFFFFF", + colourTertiary: "#FFFFFF", + colourQuaternary: "#FFFFFF", + }, +}; + +export const ScratchTheme = new Blockly.Theme("scratch", blockStyles); From 7b39ac141bf353edf0cc5379289a33dd3a3ecba8 Mon Sep 17 00:00:00 2001 From: Aaron Dodson Date: Tue, 3 Sep 2024 11:59:37 -0700 Subject: [PATCH 081/130] fix: fix wrapping of long category labels (#166) --- src/css.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/css.js b/src/css.js index 6074c5c8ed..305b12db9b 100644 --- a/src/css.js +++ b/src/css.js @@ -833,10 +833,11 @@ const styles = ` cursor: default; font-family: "Helvetica Neue", Helvetica, sans-serif; font-size: .65rem; - padding: 0 3px; + padding: 0; vertical-align: middle; width: 60px; text-align: center; + text-wrap: wrap; } .blocklyTreeSelected .blocklyTreeLabel { From c3f29521cf78af911730276d3db391ef6c3c83dd Mon Sep 17 00:00:00 2001 From: Aaron Dodson Date: Tue, 3 Sep 2024 13:28:00 -0700 Subject: [PATCH 082/130] refactor: use an extension to denote monitor blocks (#167) --- src/blocks/data.js | 4 ++-- src/blocks/looks.js | 9 +++------ src/blocks/motion.js | 9 +++------ src/blocks/sensing.js | 15 +++++---------- src/blocks/sound.js | 4 +--- src/blocks/vertical_extensions.js | 14 ++++++++++++++ src/css.js | 4 ++-- 7 files changed, 30 insertions(+), 29 deletions(-) diff --git a/src/blocks/data.js b/src/blocks/data.js index 933168c09f..372f2e997a 100644 --- a/src/blocks/data.js +++ b/src/blocks/data.js @@ -45,9 +45,9 @@ Blockly.Blocks["data_variable"] = { "contextMenu_getVariableBlock", "colours_data", "output_string", + "monitor_block", ], }); - this.checkboxInFlyout = true; }, }; @@ -171,9 +171,9 @@ Blockly.Blocks["data_listcontents"] = { "contextMenu_getListBlock", "colours_data_lists", "output_string", + "monitor_block", ], }); - this.checkboxInFlyout = true; }, }; diff --git a/src/blocks/looks.js b/src/blocks/looks.js index 023e7d7162..132e166bc3 100644 --- a/src/blocks/looks.js +++ b/src/blocks/looks.js @@ -282,9 +282,8 @@ Blockly.Blocks["looks_size"] = { this.jsonInit({ message0: Blockly.Msg.LOOKS_SIZE, category: Categories.looks, - extensions: ["colours_looks", "output_number"], + extensions: ["colours_looks", "output_number", "monitor_block"], }); - this.checkboxInFlyout = true; }, }; @@ -474,9 +473,8 @@ Blockly.Blocks["looks_backdropnumbername"] = { }, ], category: Categories.looks, - extensions: ["colours_looks", "output_number"], + extensions: ["colours_looks", "output_number", "monitor_block"], }); - this.checkboxInFlyout = true; }, }; @@ -499,9 +497,8 @@ Blockly.Blocks["looks_costumenumbername"] = { }, ], category: Categories.looks, - extensions: ["colours_looks", "output_number"], + extensions: ["colours_looks", "output_number", "monitor_block"], }); - this.checkboxInFlyout = true; }, }; diff --git a/src/blocks/motion.js b/src/blocks/motion.js index 65435172c3..d0a273ab6f 100644 --- a/src/blocks/motion.js +++ b/src/blocks/motion.js @@ -374,9 +374,8 @@ Blockly.Blocks["motion_xposition"] = { this.jsonInit({ message0: Blockly.Msg.MOTION_XPOSITION, category: Categories.motion, - extensions: ["colours_motion", "output_number"], + extensions: ["colours_motion", "output_number", "monitor_block"], }); - this.checkboxInFlyout = true; }, }; @@ -389,9 +388,8 @@ Blockly.Blocks["motion_yposition"] = { this.jsonInit({ message0: Blockly.Msg.MOTION_YPOSITION, category: Categories.motion, - extensions: ["colours_motion", "output_number"], + extensions: ["colours_motion", "output_number", "monitor_block"], }); - this.checkboxInFlyout = true; }, }; @@ -404,9 +402,8 @@ Blockly.Blocks["motion_direction"] = { this.jsonInit({ message0: Blockly.Msg.MOTION_DIRECTION, category: Categories.motion, - extensions: ["colours_motion", "output_number"], + extensions: ["colours_motion", "output_number", "monitor_block"], }); - this.checkboxInFlyout = true; }, }; diff --git a/src/blocks/sensing.js b/src/blocks/sensing.js index 7c8567ad72..87d1757e8f 100644 --- a/src/blocks/sensing.js +++ b/src/blocks/sensing.js @@ -145,9 +145,8 @@ Blockly.Blocks["sensing_answer"] = { this.jsonInit({ message0: Blockly.Msg.SENSING_ANSWER, category: Categories.sensing, - extensions: ["colours_sensing", "output_number"], + extensions: ["colours_sensing", "output_number", "monitor_block"], }); - this.checkboxInFlyout = true; }, }; @@ -309,9 +308,8 @@ Blockly.Blocks["sensing_loudness"] = { this.jsonInit({ message0: Blockly.Msg.SENSING_LOUDNESS, category: Categories.sensing, - extensions: ["colours_sensing", "output_number"], + extensions: ["colours_sensing", "output_number", "monitor_block"], }); - this.checkboxInFlyout = true; }, }; @@ -340,9 +338,8 @@ Blockly.Blocks["sensing_timer"] = { this.jsonInit({ message0: Blockly.Msg.SENSING_TIMER, category: Categories.sensing, - extensions: ["colours_sensing", "output_number"], + extensions: ["colours_sensing", "output_number", "monitor_block"], }); - this.checkboxInFlyout = true; }, }; @@ -394,9 +391,8 @@ Blockly.Blocks["sensing_current"] = { }, ], category: Categories.sensing, - extensions: ["colours_sensing", "output_number"], + extensions: ["colours_sensing", "output_number", "monitor_block"], }); - this.checkboxInFlyout = true; }, }; @@ -423,9 +419,8 @@ Blockly.Blocks["sensing_username"] = { this.jsonInit({ message0: Blockly.Msg.SENSING_USERNAME, category: Categories.sensing, - extensions: ["colours_sensing", "output_number"], + extensions: ["colours_sensing", "output_number", "monitor_block"], }); - this.checkboxInFlyout = true; }, }; diff --git a/src/blocks/sound.js b/src/blocks/sound.js index 75763e87e6..9b3372f0de 100644 --- a/src/blocks/sound.js +++ b/src/blocks/sound.js @@ -199,9 +199,7 @@ Blockly.Blocks["sound_volume"] = { this.jsonInit({ message0: Blockly.Msg.SOUND_VOLUME, category: Categories.sound, - checkboxInFlyout: true, - extensions: ["colours_sounds", "output_number"], + extensions: ["colours_sounds", "output_number", "monitor_block"], }); - this.checkboxInFlyout = true; }, }; diff --git a/src/blocks/vertical_extensions.js b/src/blocks/vertical_extensions.js index 7bbdc8608e..0bc726a722 100644 --- a/src/blocks/vertical_extensions.js +++ b/src/blocks/vertical_extensions.js @@ -143,6 +143,15 @@ VerticalExtensions.OUTPUT_BOOLEAN = function () { this.setOutput(true, "Boolean"); }; +/** + * Extension to make a block a monitor block, capable of reporting its current + * value in a dropdown. These blocks also have an accompanying checkbox in the + * flyout to toggle display of their current value in a chip on the stage. + */ +VerticalExtensions.MONITOR_BLOCK = function () { + this.checkboxInFlyout = true; +}; + /** * Mixin to add a context menu for a procedure definition block. * It adds the "edit" option and removes the "duplicate" option. @@ -288,6 +297,11 @@ VerticalExtensions.registerAll = function () { "scratch_extension", VerticalExtensions.SCRATCH_EXTENSION ); + + Blockly.Extensions.register( + "monitor_block", + VerticalExtensions.MONITOR_BLOCK + ); }; VerticalExtensions.registerAll(); diff --git a/src/css.js b/src/css.js index 305b12db9b..02a28fce2f 100644 --- a/src/css.js +++ b/src/css.js @@ -1004,8 +1004,8 @@ const styles = ` } .checked > .blocklyFlyoutCheckbox { - fill: var(--colour-motion-primary); - stroke: var(--colour-motion-tertiary); + fill: var(--colour-toolboxHover); + stroke: rgba(0,0,0,0.2); } .blocklyFlyoutCheckboxPath { From a47aba6189fbbb825ad24bd05ab3c8ecdc3dc972 Mon Sep 17 00:00:00 2001 From: Aaron Dodson Date: Thu, 5 Sep 2024 13:27:03 -0700 Subject: [PATCH 083/130] fix: fix the flyout width at 250 pixels (#168) --- src/checkable_continuous_flyout.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/checkable_continuous_flyout.js b/src/checkable_continuous_flyout.js index 77e90ea3ad..21098ec2b1 100644 --- a/src/checkable_continuous_flyout.js +++ b/src/checkable_continuous_flyout.js @@ -275,6 +275,10 @@ export class CheckableContinuousFlyout extends ContinuousFlyout { return 0.675; } + getWidth() { + return 250; + } + blockIsRecyclable_(block) { const recyclable = super.blockIsRecyclable_(block); // Exclude blocks with output connections, because they are able to report their current From c9b5c4eb8d204ad1e0be0490300194c58c127a11 Mon Sep 17 00:00:00 2001 From: Aaron Dodson Date: Thu, 5 Sep 2024 15:55:50 -0700 Subject: [PATCH 084/130] refactor: use block styles instead of directly specifying block colors (#171) * fix: fix the highlight colors of dropdown fields * fix: synthesize a selected theme and override CSS variables when setting a theme * fix: drop the colours_ prefix from block style names * fix: fix CSS glitches when switching themes * fix: use the injected theme instead of overriding it * chore: explicitly declare the originalStyle property in dropdown-related fields * chore: add a comment to setTheme --- src/blocks/control.js | 2 +- src/blocks/vertical_extensions.js | 2 +- src/colours.js | 2 +- src/css.js | 42 ++++++++++++---- src/fields/field_dropdown.js | 10 +++- src/fields/field_matrix.js | 27 +++++++++- src/fields/field_variable.js | 13 ++++- src/index.js | 10 ---- src/renderer/constants.js | 33 ++++++++++++ src/scratch_theme.js | 84 ------------------------------- 10 files changed, 114 insertions(+), 111 deletions(-) delete mode 100644 src/scratch_theme.js diff --git a/src/blocks/control.js b/src/blocks/control.js index c7066f813d..0564e9bc65 100644 --- a/src/blocks/control.js +++ b/src/blocks/control.js @@ -197,7 +197,7 @@ Blockly.Blocks["control_stop"] = { this.appendDummyInput() .appendField(Blockly.Msg.CONTROL_STOP) .appendField(stopDropdown, "STOP_OPTION"); - this.setStyle("colours_control"); + this.setStyle("control"); this.setPreviousStatement(true); }, }; diff --git a/src/blocks/vertical_extensions.js b/src/blocks/vertical_extensions.js index 0bc726a722..406d036f2d 100644 --- a/src/blocks/vertical_extensions.js +++ b/src/blocks/vertical_extensions.js @@ -43,7 +43,7 @@ VerticalExtensions.colourHelper = function (category) { * @this {Blockly.Block} */ return function () { - this.setStyle(`colours_${category}`); + this.setStyle(category); }; }; diff --git a/src/colours.js b/src/colours.js index 86b2234485..87a2411487 100644 --- a/src/colours.js +++ b/src/colours.js @@ -52,7 +52,7 @@ const Colours = { numPadText: "white", // Do not use hex here, it cannot be inlined with data-uri SVG valueReportBackground: "#FFFFFF", valueReportBorder: "#AAAAAA", - menuHover: "rgba(77, 151, 255, .25)", + contextualMenuHover: "rgba(77, 151, 255, .25)", }; function varify(coloursObj, prefix = "--colour") { diff --git a/src/css.js b/src/css.js index 02a28fce2f..753fec20b2 100644 --- a/src/css.js +++ b/src/css.js @@ -413,19 +413,32 @@ const styles = ` cursor: pointer; } - .scratch-renderer.scratch-theme .blocklyFlyoutLabelText { + .scratch-renderer.default-theme .blocklyFlyoutLabelText, + .scratch-renderer.high-contrast-theme .blocklyFlyoutLabelText { font-family: "Helvetica Neue", Helvetica, sans-serif; font-size: 14pt; fill: #575E75; font-weight: bold; } - .scratch-renderer.scratch-theme .blocklyText, - .scratch-renderer.scratch-theme .blocklyHtmlInput { + .scratch-renderer.default-theme .blocklyText, + .scratch-renderer.default-theme .blocklyHtmlInput, + .scratch-renderer.high-contrast-theme .blocklyText, + .scratch-renderer.high-contrast-theme .blocklyHtmlInput { font-weight: 500; } - .scratch-renderer.scratch-theme .blocklyFlyoutButton .blocklyText { + .scratch-renderer.high-contrast-theme .blocklyText, + .scratch-renderer.high-contrast-theme .blocklyEditableField .blocklyDropdownText { + fill: #000 !important; + } + + .scratch-renderer.high-contrast-theme .blocklyEditableField image:last-child { + filter: invert(1); + } + + .scratch-renderer.default-theme .blocklyFlyoutButton .blocklyText, + .scratch-renderer.high-contrast-theme .blocklyFlyoutButton .blocklyText { fill: var(--colour-textFieldText); } @@ -990,10 +1003,14 @@ const styles = ` z-index: 20000; /* Arbitrary, but some apps depend on it... */ } - .blocklyWidgetDiv .blocklyMenu .blocklyMenuItem:hover { + .blocklyDropDownDiv .blocklyMenu .blocklyMenuItem:hover { background: var(--colour-menuHover); } + .blocklyWidgetDiv .blocklyMenu .blocklyMenuItem:hover { + background: var(--colour-contextualMenuHover); + } + .blocklyWidgetDiv .blocklyMenu .blocklyMenuItemDisabled.blocklyMenuItem:hover { background: none; } @@ -1117,7 +1134,8 @@ const styles = ` transform: rotate(-180deg); } - .scratch-renderer.scratch-theme .blocklyComment .blocklyTextarea { + .scratch-renderer.default-theme .blocklyComment .blocklyTextarea, + .scratch-renderer.high-contrast-theme .blocklyComment .blocklyTextarea { border: none; --commentFillColour: #fef49c; font-size: 12pt; @@ -1126,7 +1144,8 @@ const styles = ` color: #575e75; } - .scratch-renderer.scratch-theme .blocklyCommentText.blocklyText { + .scratch-renderer.default-theme .blocklyCommentText.blocklyText, + .scratch-renderer.high-contrast-theme .blocklyCommentText.blocklyText { font-weight: 400; } @@ -1146,6 +1165,9 @@ const styles = ` min-height: 32px; padding: 4px 7em 4px 28px; } + .high-contrast-theme.blocklyDropDownDiv .blocklyMenuItem { + color: #000; + } .blocklyToolboxSelected .blocklyTreeLabel { color: var(--colour-toolboxText); } @@ -1161,8 +1183,10 @@ const styles = ` width: 20px; } - .scratch-renderer.scratch-theme .blocklyDraggable:not(.blocklyDisabled) .blocklyEditableField:not(.blocklyEditing):hover>rect, - .scratch-renderer.scratch-theme .blocklyDraggable:not(.blocklyDisabled) .blocklyEditableField:not(.blocklyEditing):hover>.blocklyPath { + .scratch-renderer.default-theme .blocklyDraggable:not(.blocklyDisabled) .blocklyEditableField:not(.blocklyEditing):hover>rect, + .scratch-renderer.default-theme .blocklyDraggable:not(.blocklyDisabled) .blocklyEditableField:not(.blocklyEditing):hover>.blocklyPath, + .scratch-renderer.high-contrast-theme .blocklyDraggable:not(.blocklyDisabled) .blocklyEditableField:not(.blocklyEditing):hover>rect, + .scratch-renderer.high-contrast-theme .blocklyDraggable:not(.blocklyDisabled) .blocklyEditableField:not(.blocklyEditing):hover>.blocklyPath { stroke: revert-layer; stroke-width: 1; } diff --git a/src/fields/field_dropdown.js b/src/fields/field_dropdown.js index bc409c0e39..1a3d553bc3 100644 --- a/src/fields/field_dropdown.js +++ b/src/fields/field_dropdown.js @@ -7,13 +7,19 @@ import * as Blockly from "blockly/core"; class FieldDropdown extends Blockly.FieldDropdown { + originalStyle; + showEditor_(event) { super.showEditor_(event); const sourceBlock = this.getSourceBlock(); + const style = sourceBlock.style; if (sourceBlock.isShadow()) { this.originalStyle = sourceBlock.getStyleName(); - sourceBlock.setColour( - sourceBlock.style.colourQuaternary ?? sourceBlock.style.colourTertiary + sourceBlock.setStyle(`${this.originalStyle}_selected`); + } else if (this.borderRect_) { + this.borderRect_.setAttribute( + "fill", + style.colourQuaternary ?? style.colourTertiary ); } } diff --git a/src/fields/field_matrix.js b/src/fields/field_matrix.js index 71955614ca..0deee6c900 100644 --- a/src/fields/field_matrix.js +++ b/src/fields/field_matrix.js @@ -32,6 +32,8 @@ import * as Blockly from "blockly/core"; * @constructor */ export class FieldMatrix extends Blockly.Field { + originalStyle; + constructor(matrix) { super(matrix); /** @@ -332,7 +334,11 @@ export class FieldMatrix extends Blockly.Field { this.sourceBlock_.getColour(), this.sourceBlock_.getColourTertiary() ); - Blockly.DropDownDiv.showPositionedByBlock(this, this.sourceBlock_); + Blockly.DropDownDiv.showPositionedByBlock( + this, + this.sourceBlock_, + this.dropdownDispose_.bind(this) + ); this.matrixTouchWrapper_ = Blockly.browserEvents.bind( this.matrixStage_, @@ -353,10 +359,29 @@ export class FieldMatrix extends Blockly.Field { this.fillMatrix_ ); + const sourceBlock = this.getSourceBlock(); + const style = sourceBlock.style; + if (sourceBlock.isShadow()) { + this.originalStyle = sourceBlock.getStyleName(); + sourceBlock.setStyle(`${this.originalStyle}_selected`); + } else if (this.borderRect_) { + this.borderRect_.setAttribute( + "fill", + style.colourQuaternary ?? style.colourTertiary + ); + } + // Update the matrix for the current value this.updateMatrix_(); } + dropdownDispose_() { + const sourceBlock = this.getSourceBlock(); + if (sourceBlock.isShadow()) { + sourceBlock.setStyle(this.originalStyle); + } + } + /** * Make an svg object that resembles a 3x3 matrix to be used as a button. * @param {string} fill The color to fill the matrix nodes. diff --git a/src/fields/field_variable.js b/src/fields/field_variable.js index 5e8179414d..521f69fa11 100644 --- a/src/fields/field_variable.js +++ b/src/fields/field_variable.js @@ -28,6 +28,8 @@ import { ScratchMsgs } from "../../msg/scratch_msgs.js"; import { createVariable, renameVariable } from "../variables.js"; class FieldVariable extends Blockly.FieldVariable { + originalStyle; + constructor(varName, validator, variableTypes, defaultType, config) { super(varName, validator, variableTypes, defaultType, config); this.menuGenerator_ = FieldVariable.dropdownCreate; @@ -139,8 +141,15 @@ class FieldVariable extends Blockly.FieldVariable { showEditor_(event) { super.showEditor_(event); const sourceBlock = this.getSourceBlock(); + const style = sourceBlock.style; if (sourceBlock.isShadow()) { - sourceBlock.setColour(sourceBlock.style.colourQuaternary); + this.originalStyle = sourceBlock.getStyleName(); + sourceBlock.setStyle(`${this.originalStyle}_selected`); + } else if (this.borderRect_) { + this.borderRect_.setAttribute( + "fill", + style.colourQuaternary ?? style.colourTertiary + ); } } @@ -148,7 +157,7 @@ class FieldVariable extends Blockly.FieldVariable { super.dropdownDispose_(); const sourceBlock = this.getSourceBlock(); if (sourceBlock.isShadow()) { - sourceBlock.setStyle(`colours_${sourceBlock.type.split("_")[0]}`); + sourceBlock.setStyle(this.originalStyle); } } } diff --git a/src/index.js b/src/index.js index fdcb0b28bd..84055bfe20 100644 --- a/src/index.js +++ b/src/index.js @@ -34,7 +34,6 @@ import { import { CheckableContinuousFlyout } from "./checkable_continuous_flyout.js"; import { buildGlowFilter, glowStack } from "./glows.js"; import { ScratchContinuousToolbox } from "./scratch_continuous_toolbox.js"; -import { ScratchTheme } from "./scratch_theme.js"; import "./scratch_continuous_category.js"; import "./scratch_comment_icon.js"; import "./scratch_dragger.js"; @@ -73,7 +72,6 @@ export { contextMenuItems }; export function inject(container, options) { Object.assign(options, { renderer: "scratch", - theme: ScratchTheme, plugins: { toolbox: ScratchContinuousToolbox, flyoutsVerticalToolbox: CheckableContinuousFlyout, @@ -82,14 +80,6 @@ export function inject(container, options) { }); const workspace = Blockly.inject(container, options); - workspace.getRenderer().getConstants().selectedGlowFilterId = ""; - - const flyout = workspace.getFlyout(); - if (flyout) { - flyout.getWorkspace().getRenderer().getConstants().selectedGlowFilterId = - ""; - } - buildGlowFilter(workspace); buildShadowFilter(workspace); diff --git a/src/renderer/constants.js b/src/renderer/constants.js index dc821221c6..b7ea725a5d 100644 --- a/src/renderer/constants.js +++ b/src/renderer/constants.js @@ -5,7 +5,40 @@ */ import * as Blockly from "blockly/core"; +import { cssVarify } from "../colours.js"; export class ConstantProvider extends Blockly.zelos.ConstantProvider { REPLACEMENT_GLOW_COLOUR = "#ffffff"; + + /** + * Sets the visual theme used to render the workspace. + * This method also synthesizes a "selected" theme, used to color blocks with + * dropdown menus when the menu is active. Additionally, if the theme's block + * styles contain any raw color values, corresponding CSS variables will be + * created/overridden so that those colors can be dynamically referenced in + * stylesheets. + * @param {!Blockly.Theme} The new theme to apply. + */ + setTheme(theme) { + const root = document.querySelector(":root"); + for (const [key, colour] of Object.entries(theme.blockStyles)) { + if (typeof colour === "string") { + const varKey = `--colour-${key}`; + root.style.setProperty(varKey, colour); + } else { + theme.setBlockStyle(`${key}_selected`, { + colourPrimary: colour.colourQuaternary ?? colour.colourTertiary, + colourSecondary: colour.colourQuaternary ?? colour.colourTertiary, + colourTertiary: colour.colourQuaternary ?? colour.colourTertiary, + colourQuaternary: colour.colourQuaternary ?? colour.colourTertiary, + }); + } + } + super.setTheme(theme); + } + + createDom(svg, tagName, selector) { + super.createDom(svg, tagName, selector); + this.selectedGlowFilterId = ""; + } } diff --git a/src/scratch_theme.js b/src/scratch_theme.js deleted file mode 100644 index 2ef5fca698..0000000000 --- a/src/scratch_theme.js +++ /dev/null @@ -1,84 +0,0 @@ -/** - * @license - * Copyright 2024 Google LLC - * SPDX-License-Identifier: Apache-2.0 - */ - -import * as Blockly from "blockly/core"; - -const blockStyles = { - colours_motion: { - colourPrimary: "#4C97FF", - colourSecondary: "#4280D7", - colourTertiary: "#3373CC", - colourQuaternary: "#3373CC", - }, - colours_looks: { - colourPrimary: "#9966FF", - colourSecondary: "#855CD6", - colourTertiary: "#774DCB", - colourQuaternary: "#774DCB", - }, - colours_sounds: { - colourPrimary: "#CF63CF", - colourSecondary: "#C94FC9", - colourTertiary: "#BD42BD", - colourQuaternary: "#BD42BD", - }, - colours_control: { - colourPrimary: "#FFAB19", - colourSecondary: "#EC9C13", - colourTertiary: "#CF8B17", - colourQuaternary: "#CF8B17", - }, - colours_event: { - colourPrimary: "#FFBF00", - colourSecondary: "#E6AC00", - colourTertiary: "#CC9900", - colourQuaternary: "#CC9900", - }, - colours_sensing: { - colourPrimary: "#5CB1D6", - colourSecondary: "#47A8D1", - colourTertiary: "#2E8EB8", - colourQuaternary: "#2E8EB8", - }, - colours_pen: { - colourPrimary: "#0fBD8C", - colourSecondary: "#0DA57A", - colourTertiary: "#0B8E69", - colourQuaternary: "#0B8E69", - }, - colours_operators: { - colourPrimary: "#59C059", - colourSecondary: "#46B946", - colourTertiary: "#389438", - colourQuaternary: "#389438", - }, - colours_data: { - colourPrimary: "#FF8C1A", - colourSecondary: "#FF8000", - colourTertiary: "#DB6E00", - colourQuaternary: "#DB6E00", - }, - colours_data_lists: { - colourPrimary: "#FF661A", - colourSecondary: "#FF5500", - colourTertiary: "#E64D00", - colourQuaternary: "#E64D00", - }, - colours_more: { - colourPrimary: "#FF6680", - colourSecondary: "#FF4D6A", - colourTertiary: "#FF3355", - colourQuaternary: "#FF3355", - }, - colours_textfield: { - colourPrimary: "#FFFFFF", - colourSecondary: "#FFFFFF", - colourTertiary: "#FFFFFF", - colourQuaternary: "#FFFFFF", - }, -}; - -export const ScratchTheme = new Blockly.Theme("scratch", blockStyles); From 2e98ff15a149b0ff44e30e7023b36d1605030311 Mon Sep 17 00:00:00 2001 From: Aaron Dodson Date: Mon, 9 Sep 2024 15:48:41 -0700 Subject: [PATCH 085/130] fix: fix bug that prevented showing the contextual menu on blocks (#176) --- msg/scratch_msgs.js | 160 ++++++++++++++++++++++---------------------- 1 file changed, 80 insertions(+), 80 deletions(-) diff --git a/msg/scratch_msgs.js b/msg/scratch_msgs.js index 9312dc206a..794f9ac537 100644 --- a/msg/scratch_msgs.js +++ b/msg/scratch_msgs.js @@ -266,7 +266,7 @@ ScratchMsgs.locales["ab"] = "CATEGORY_OPERATORS": "Аоператорқәа", "CATEGORY_VARIABLES": "Аҽеиҭакқәа", "CATEGORY_MYBLOCKS": "Сара сблокқәа", - "DUPLICATE": "Адубликат", + "DUPLICATE_BLOCK": "Адубликат", "DELETE": "Ианыхтәуп", "ADD_COMMENT": "Иацҵатәуп акомментари", "REMOVE_COMMENT": "Ианыхтәуп акомментари", @@ -553,7 +553,7 @@ ScratchMsgs.locales["af"] = "CATEGORY_OPERATORS": "Operateurs", "CATEGORY_VARIABLES": "Veranderlikes", "CATEGORY_MYBLOCKS": "My Blokke", - "DUPLICATE": "Dupliseer", + "DUPLICATE_BLOCK": "Dupliseer", "DELETE": "Skrap", "ADD_COMMENT": "Voeg Kommentaar By", "REMOVE_COMMENT": "Verwyder Kommentaar", @@ -840,7 +840,7 @@ ScratchMsgs.locales["ar"] = "CATEGORY_OPERATORS": "العمليات", "CATEGORY_VARIABLES": "المتغيرات", "CATEGORY_MYBLOCKS": "لبناتي", - "DUPLICATE": "مضاعفة", + "DUPLICATE_BLOCK": "مضاعفة", "DELETE": "حذف", "ADD_COMMENT": "إضافة تعليق", "REMOVE_COMMENT": "حذف التعليق", @@ -1127,7 +1127,7 @@ ScratchMsgs.locales["am"] = "CATEGORY_OPERATORS": "ስሌቶች", "CATEGORY_VARIABLES": "ተለዋዋጮች", "CATEGORY_MYBLOCKS": "የኔ ጥምሮች", - "DUPLICATE": "ቅጂ አድርገህ ገልብጥ", + "DUPLICATE_BLOCK": "ቅጂ አድርገህ ገልብጥ", "DELETE": "አጥፋ", "ADD_COMMENT": "አስተያየት ጨምር", "REMOVE_COMMENT": "አስተያየት አውጣ", @@ -1414,7 +1414,7 @@ ScratchMsgs.locales["an"] = "CATEGORY_OPERATORS": "Operadors", "CATEGORY_VARIABLES": "Variables", "CATEGORY_MYBLOCKS": "Los míos bloques", - "DUPLICATE": "Duplicar", + "DUPLICATE_BLOCK": "Duplicar", "DELETE": "Borrar", "ADD_COMMENT": "Anyadir comentario", "REMOVE_COMMENT": "Eliminar comentario", @@ -1701,7 +1701,7 @@ ScratchMsgs.locales["ast"] = "CATEGORY_OPERATORS": "Operadores", "CATEGORY_VARIABLES": "Variables", "CATEGORY_MYBLOCKS": "Los Mios Bloques", - "DUPLICATE": "Duplicar", + "DUPLICATE_BLOCK": "Duplicar", "DELETE": "Esborrar", "ADD_COMMENT": "Amestar comentariu", "REMOVE_COMMENT": "Esborrar Comentariu", @@ -1988,7 +1988,7 @@ ScratchMsgs.locales["az"] = "CATEGORY_OPERATORS": "Operatorlar", "CATEGORY_VARIABLES": "Dəyişənlər", "CATEGORY_MYBLOCKS": "Mənim Bloklarım", - "DUPLICATE": "Dublikatın yarat", + "DUPLICATE_BLOCK": "Dublikatın yarat", "DELETE": "Sil", "ADD_COMMENT": "Şərh əlavə et", "REMOVE_COMMENT": "Şərhi sil", @@ -2275,7 +2275,7 @@ ScratchMsgs.locales["id"] = "CATEGORY_OPERATORS": "Operator", "CATEGORY_VARIABLES": "Variabel", "CATEGORY_MYBLOCKS": "Balok Saya", - "DUPLICATE": "Gandakan", + "DUPLICATE_BLOCK": "Gandakan", "DELETE": "Hapus", "ADD_COMMENT": "Tambahkan Komentar", "REMOVE_COMMENT": "Hapus Komentar", @@ -2562,7 +2562,7 @@ ScratchMsgs.locales["bn"] = "CATEGORY_OPERATORS": "অপারেটর", "CATEGORY_VARIABLES": "ভ্যারিয়েবল", "CATEGORY_MYBLOCKS": "আমার ব্লকগুলো", - "DUPLICATE": "অনুরূপ", + "DUPLICATE_BLOCK": "অনুরূপ", "DELETE": "অপসারণ", "ADD_COMMENT": "মন্তব্য যোগ কর", "REMOVE_COMMENT": "মন্তব্য অপসারণ কর", @@ -2849,7 +2849,7 @@ ScratchMsgs.locales["be"] = "CATEGORY_OPERATORS": "Аператары", "CATEGORY_VARIABLES": "Зменныя", "CATEGORY_MYBLOCKS": "Уласныя блокі", - "DUPLICATE": "Падвоіць", + "DUPLICATE_BLOCK": "Падвоіць", "DELETE": "Выдаліць", "ADD_COMMENT": "Дадаць каментарый", "REMOVE_COMMENT": "Выдаліць каментарый", @@ -3136,7 +3136,7 @@ ScratchMsgs.locales["bg"] = "CATEGORY_OPERATORS": "Оператори", "CATEGORY_VARIABLES": "Променливи", "CATEGORY_MYBLOCKS": "Моите Блокове", - "DUPLICATE": "Дублиране", + "DUPLICATE_BLOCK": "Дублиране", "DELETE": "Изтриване", "ADD_COMMENT": "Добави Коментар", "REMOVE_COMMENT": "Премахни Коментар", @@ -3423,7 +3423,7 @@ ScratchMsgs.locales["ca"] = "CATEGORY_OPERATORS": "Operadors", "CATEGORY_VARIABLES": "Variables", "CATEGORY_MYBLOCKS": "Els meus blocs", - "DUPLICATE": "Duplica", + "DUPLICATE_BLOCK": "Duplica", "DELETE": "Elimina", "ADD_COMMENT": "Afegeix un comentari", "REMOVE_COMMENT": "Elimina el comentari", @@ -3710,7 +3710,7 @@ ScratchMsgs.locales["cs"] = "CATEGORY_OPERATORS": "Operátory", "CATEGORY_VARIABLES": "Proměnné", "CATEGORY_MYBLOCKS": "Moje bloky", - "DUPLICATE": "Kopírovat", + "DUPLICATE_BLOCK": "Kopírovat", "DELETE": "Odstranit", "ADD_COMMENT": "Přidat poznámku", "REMOVE_COMMENT": "Odstranit poznámku", @@ -3997,7 +3997,7 @@ ScratchMsgs.locales["cy"] = "CATEGORY_OPERATORS": "Gweithredwyr", "CATEGORY_VARIABLES": "Newidynnau", "CATEGORY_MYBLOCKS": "Fy Mlociau", - "DUPLICATE": "Dyblygu", + "DUPLICATE_BLOCK": "Dyblygu", "DELETE": "Dileu", "ADD_COMMENT": "Ychwanegu Sylw", "REMOVE_COMMENT": "Tynnu Sylw", @@ -4284,7 +4284,7 @@ ScratchMsgs.locales["da"] = "CATEGORY_OPERATORS": "Operatorer", "CATEGORY_VARIABLES": "Variabler", "CATEGORY_MYBLOCKS": "Mine brikker", - "DUPLICATE": "Kopiér", + "DUPLICATE_BLOCK": "Kopiér", "DELETE": "Slet", "ADD_COMMENT": "Tilføj kommentar", "REMOVE_COMMENT": "Slet kommentar", @@ -4571,7 +4571,7 @@ ScratchMsgs.locales["de"] = "CATEGORY_OPERATORS": "Operatoren", "CATEGORY_VARIABLES": "Variablen", "CATEGORY_MYBLOCKS": "Meine Blöcke", - "DUPLICATE": "Duplizieren", + "DUPLICATE_BLOCK": "Duplizieren", "DELETE": "Löschen", "ADD_COMMENT": "Kommentar hinzufügen", "REMOVE_COMMENT": "Kommentar entfernen", @@ -4858,7 +4858,7 @@ ScratchMsgs.locales["et"] = "CATEGORY_OPERATORS": "Tehted", "CATEGORY_VARIABLES": "Muutujad", "CATEGORY_MYBLOCKS": "Minu Plokid", - "DUPLICATE": "Paljunda", + "DUPLICATE_BLOCK": "Paljunda", "DELETE": "Kustuta", "ADD_COMMENT": "Lisa kommentaar", "REMOVE_COMMENT": "Eemalda kommentaar", @@ -5145,7 +5145,7 @@ ScratchMsgs.locales["el"] = "CATEGORY_OPERATORS": "Τελεστές", "CATEGORY_VARIABLES": "Μεταβλητές", "CATEGORY_MYBLOCKS": "Οι Εντολές μου", - "DUPLICATE": "Διπλασιασμός", + "DUPLICATE_BLOCK": "Διπλασιασμός", "DELETE": "Διαγραφή", "ADD_COMMENT": "Προσθήκη σχολίου", "REMOVE_COMMENT": "Αφαίρεση σχολίου", @@ -5432,7 +5432,7 @@ ScratchMsgs.locales["en"] = "CATEGORY_OPERATORS": "Operators", "CATEGORY_VARIABLES": "Variables", "CATEGORY_MYBLOCKS": "My Blocks", - "DUPLICATE": "Duplicate", + "DUPLICATE_BLOCK": "Duplicate", "DELETE": "Delete", "ADD_COMMENT": "Add Comment", "REMOVE_COMMENT": "Remove Comment", @@ -5719,7 +5719,7 @@ ScratchMsgs.locales["es"] = "CATEGORY_OPERATORS": "Operadores", "CATEGORY_VARIABLES": "Variables", "CATEGORY_MYBLOCKS": "Mis bloques", - "DUPLICATE": "Duplicar", + "DUPLICATE_BLOCK": "Duplicar", "DELETE": "Eliminar", "ADD_COMMENT": "Añadir comentario", "REMOVE_COMMENT": "Eliminar comentario", @@ -6006,7 +6006,7 @@ ScratchMsgs.locales["es-419"] = "CATEGORY_OPERATORS": "Operadores", "CATEGORY_VARIABLES": "Variables", "CATEGORY_MYBLOCKS": "Mis Bloques", - "DUPLICATE": "Duplicar", + "DUPLICATE_BLOCK": "Duplicar", "DELETE": "Eliminar", "ADD_COMMENT": "Agregar comentario", "REMOVE_COMMENT": "Eliminar comentario", @@ -6293,7 +6293,7 @@ ScratchMsgs.locales["eo"] = "CATEGORY_OPERATORS": "Operatoroj", "CATEGORY_VARIABLES": "Variabloj", "CATEGORY_MYBLOCKS": "Miaj Blokoj", - "DUPLICATE": "Krei kopion", + "DUPLICATE_BLOCK": "Krei kopion", "DELETE": "Forigi", "ADD_COMMENT": "Aldoni komenton", "REMOVE_COMMENT": "Forigi komenton", @@ -6580,7 +6580,7 @@ ScratchMsgs.locales["eu"] = "CATEGORY_OPERATORS": "Eragileak", "CATEGORY_VARIABLES": "Aldagaiak", "CATEGORY_MYBLOCKS": "Nire blokeak", - "DUPLICATE": "Bikoiztu", + "DUPLICATE_BLOCK": "Bikoiztu", "DELETE": "Ezabatu", "ADD_COMMENT": "Gehitu iruzkina", "REMOVE_COMMENT": "Kendu iruzkina", @@ -6867,7 +6867,7 @@ ScratchMsgs.locales["fa"] = "CATEGORY_OPERATORS": "عملگرها", "CATEGORY_VARIABLES": "متغیرها", "CATEGORY_MYBLOCKS": "قطعه‌های من", - "DUPLICATE": "تکثیر", + "DUPLICATE_BLOCK": "تکثیر", "DELETE": "حذف", "ADD_COMMENT": "افزودن یادداشت", "REMOVE_COMMENT": "حذف یادداشت", @@ -7154,7 +7154,7 @@ ScratchMsgs.locales["fil"] = "CATEGORY_OPERATORS": "Mga Operator", "CATEGORY_VARIABLES": "Mga Variable", "CATEGORY_MYBLOCKS": "Mga Block Ko", - "DUPLICATE": "Doblehin", + "DUPLICATE_BLOCK": "Doblehin", "DELETE": "Burahin", "ADD_COMMENT": "Magkomento", "REMOVE_COMMENT": "Tanggalin ang Komento", @@ -7441,7 +7441,7 @@ ScratchMsgs.locales["fr"] = "CATEGORY_OPERATORS": "Opérateurs", "CATEGORY_VARIABLES": "Variables", "CATEGORY_MYBLOCKS": "Mes Blocs", - "DUPLICATE": "Dupliquer", + "DUPLICATE_BLOCK": "Dupliquer", "DELETE": "Supprimer", "ADD_COMMENT": "Ajouter un commentaire", "REMOVE_COMMENT": "Retirer le commentaire", @@ -7728,7 +7728,7 @@ ScratchMsgs.locales["fy"] = "CATEGORY_OPERATORS": "Bestjoerders", "CATEGORY_VARIABLES": "Fariabelen", "CATEGORY_MYBLOCKS": "Myn Blokken", - "DUPLICATE": "Duplisearje", + "DUPLICATE_BLOCK": "Duplisearje", "DELETE": "Wiskje", "ADD_COMMENT": "Kommentaar tafoegje", "REMOVE_COMMENT": "Kommentaar fuortsmite", @@ -8015,7 +8015,7 @@ ScratchMsgs.locales["ga"] = "CATEGORY_OPERATORS": "Oibreoirí", "CATEGORY_VARIABLES": "Athróga", "CATEGORY_MYBLOCKS": "Mo Chuid Blocanna", - "DUPLICATE": "Cóipeáil", + "DUPLICATE_BLOCK": "Cóipeáil", "DELETE": "Scrios", "ADD_COMMENT": "Cuir Nóta Tráchta Leis", "REMOVE_COMMENT": "Bain an Nóta Tráchta", @@ -8302,7 +8302,7 @@ ScratchMsgs.locales["gd"] = "CATEGORY_OPERATORS": "Gnìomharaiche", "CATEGORY_VARIABLES": "Caochladairean", "CATEGORY_MYBLOCKS": "Bloca agamsa", - "DUPLICATE": "Dùblaich", + "DUPLICATE_BLOCK": "Dùblaich", "DELETE": "Sguab às", "ADD_COMMENT": "Cuir beachd ris", "REMOVE_COMMENT": "Thoir am beachd air falbh", @@ -8589,7 +8589,7 @@ ScratchMsgs.locales["gl"] = "CATEGORY_OPERATORS": "Operadores", "CATEGORY_VARIABLES": "Variábeis", "CATEGORY_MYBLOCKS": "Os meus bloques", - "DUPLICATE": "Duplicar", + "DUPLICATE_BLOCK": "Duplicar", "DELETE": "Eliminar", "ADD_COMMENT": "Engadir comentario", "REMOVE_COMMENT": "Retirar comentario", @@ -8876,7 +8876,7 @@ ScratchMsgs.locales["ko"] = "CATEGORY_OPERATORS": "연산", "CATEGORY_VARIABLES": "변수", "CATEGORY_MYBLOCKS": "내 블록", - "DUPLICATE": "복사하기", + "DUPLICATE_BLOCK": "복사하기", "DELETE": "삭제하기", "ADD_COMMENT": "주석 넣기", "REMOVE_COMMENT": "주석 지우기", @@ -9163,7 +9163,7 @@ ScratchMsgs.locales["ha"] = "CATEGORY_OPERATORS": "ma'alaƙanta", "CATEGORY_VARIABLES": "abubuwa masu canzawa", "CATEGORY_MYBLOCKS": "tubalai na", - "DUPLICATE": "kwafa", + "DUPLICATE_BLOCK": "kwafa", "DELETE": "goge", "ADD_COMMENT": "ƙara tsokaci ", "REMOVE_COMMENT": "cire tsokaci", @@ -9450,7 +9450,7 @@ ScratchMsgs.locales["hy"] = "CATEGORY_OPERATORS": "Հաշվարկ", "CATEGORY_VARIABLES": "Փոփոխա­­կան", "CATEGORY_MYBLOCKS": "Մասնիկ", - "DUPLICATE": "Կրկնօրինակել", + "DUPLICATE_BLOCK": "Կրկնօրինակել", "DELETE": "Ջնջել", "ADD_COMMENT": "Ավելացնել մեկնաբանություն", "REMOVE_COMMENT": "Ջնջել մեկնաբանությունը", @@ -9737,7 +9737,7 @@ ScratchMsgs.locales["he"] = "CATEGORY_OPERATORS": "מפעילים", "CATEGORY_VARIABLES": "משתנים", "CATEGORY_MYBLOCKS": "הלבנים שלי", - "DUPLICATE": "שכפל", + "DUPLICATE_BLOCK": "שכפל", "DELETE": "מחק", "ADD_COMMENT": "הוספת תגובה", "REMOVE_COMMENT": "מחק תגובה", @@ -10024,7 +10024,7 @@ ScratchMsgs.locales["hi"] = "CATEGORY_OPERATORS": "ऑपरेटर्स", "CATEGORY_VARIABLES": "चर वस्तुएँ", "CATEGORY_MYBLOCKS": "मेरे खण्ड", - "DUPLICATE": "प्रतिरुप", + "DUPLICATE_BLOCK": "प्रतिरुप", "DELETE": "मिटाये", "ADD_COMMENT": "टिप्पणी दे", "REMOVE_COMMENT": "टिप्पणी मिटाये", @@ -10311,7 +10311,7 @@ ScratchMsgs.locales["hr"] = "CATEGORY_OPERATORS": "Operacije", "CATEGORY_VARIABLES": "Varijable", "CATEGORY_MYBLOCKS": "Moji Blokovi", - "DUPLICATE": "Dupliciraj", + "DUPLICATE_BLOCK": "Dupliciraj", "DELETE": "Izbriši", "ADD_COMMENT": "Dodaj komentar", "REMOVE_COMMENT": "Ukloni komentar", @@ -10598,7 +10598,7 @@ ScratchMsgs.locales["xh"] = "CATEGORY_OPERATORS": "ababhexeshi", "CATEGORY_VARIABLES": "iiveriyebhl", "CATEGORY_MYBLOCKS": "Ibhloko zam", - "DUPLICATE": "ukukhuphela", + "DUPLICATE_BLOCK": "ukukhuphela", "DELETE": "cima", "ADD_COMMENT": "faka uluvo", "REMOVE_COMMENT": "Susa uluvo", @@ -10885,7 +10885,7 @@ ScratchMsgs.locales["zu"] = "CATEGORY_OPERATORS": "Abahambisayo", "CATEGORY_VARIABLES": "okuguqukayo", "CATEGORY_MYBLOCKS": "Amabhulokisi ami", - "DUPLICATE": "Fanisa", + "DUPLICATE_BLOCK": "Fanisa", "DELETE": "Cima", "ADD_COMMENT": "engeza ukuphawula", "REMOVE_COMMENT": "Susa ukuphawula", @@ -11172,7 +11172,7 @@ ScratchMsgs.locales["is"] = "CATEGORY_OPERATORS": "Virkjar", "CATEGORY_VARIABLES": "Breytur", "CATEGORY_MYBLOCKS": "Mínir kubbar", - "DUPLICATE": "Tvöfalda", + "DUPLICATE_BLOCK": "Tvöfalda", "DELETE": "Eyða", "ADD_COMMENT": "Bæta við athugasemd", "REMOVE_COMMENT": "Fjarlægja athugasemd", @@ -11459,7 +11459,7 @@ ScratchMsgs.locales["it"] = "CATEGORY_OPERATORS": "Operatori", "CATEGORY_VARIABLES": "Variabili", "CATEGORY_MYBLOCKS": "I Miei Blocchi", - "DUPLICATE": "Duplica", + "DUPLICATE_BLOCK": "Duplica", "DELETE": "Cancella", "ADD_COMMENT": "Aggiungi commento", "REMOVE_COMMENT": "Rimuovi commento", @@ -11746,7 +11746,7 @@ ScratchMsgs.locales["ka"] = "CATEGORY_OPERATORS": "ოპერატორები", "CATEGORY_VARIABLES": "ცვლადები", "CATEGORY_MYBLOCKS": "ჩემი ბლოკები", - "DUPLICATE": "დუბლირება", + "DUPLICATE_BLOCK": "დუბლირება", "DELETE": "წაშლა", "ADD_COMMENT": "დაამატე კომენტარი", "REMOVE_COMMENT": "წაშალე კომენტარი", @@ -12033,7 +12033,7 @@ ScratchMsgs.locales["kk"] = "CATEGORY_OPERATORS": "Операторлар", "CATEGORY_VARIABLES": "айнымалылар", "CATEGORY_MYBLOCKS": "Менің блоктарым", - "DUPLICATE": "Көшірмесін жасау", + "DUPLICATE_BLOCK": "Көшірмесін жасау", "DELETE": "Жою", "ADD_COMMENT": "Комментарий жазу", "REMOVE_COMMENT": "Комментарийді өшіру", @@ -12320,7 +12320,7 @@ ScratchMsgs.locales["qu"] = "CATEGORY_OPERATORS": "Llamkaq", "CATEGORY_VARIABLES": "hukniraq", "CATEGORY_MYBLOCKS": "champaykuna", - "DUPLICATE": "iskachay", + "DUPLICATE_BLOCK": "iskachay", "DELETE": "Pichay", "ADD_COMMENT": "yapay parlarisqaykita", "REMOVE_COMMENT": "parlasqaykita kitay", @@ -12607,7 +12607,7 @@ ScratchMsgs.locales["sw"] = "CATEGORY_OPERATORS": "Opereta", "CATEGORY_VARIABLES": "Vibadilika", "CATEGORY_MYBLOCKS": "Bloku Zangu", - "DUPLICATE": "Toa Nakala Nyingine", + "DUPLICATE_BLOCK": "Toa Nakala Nyingine", "DELETE": "Futa", "ADD_COMMENT": "Ongeza Maoni", "REMOVE_COMMENT": "Futa Maoni", @@ -12894,7 +12894,7 @@ ScratchMsgs.locales["ht"] = "CATEGORY_OPERATORS": "Operatè", "CATEGORY_VARIABLES": "Varyab ", "CATEGORY_MYBLOCKS": "Blòk mwen yo", - "DUPLICATE": "Fè marasa", + "DUPLICATE_BLOCK": "Fè marasa", "DELETE": "Efase", "ADD_COMMENT": "Ajoute remak", "REMOVE_COMMENT": "Retire remak", @@ -13181,7 +13181,7 @@ ScratchMsgs.locales["ku"] = "CATEGORY_OPERATORS": "Operator", "CATEGORY_VARIABLES": "Guherok", "CATEGORY_MYBLOCKS": "Blokên Min", - "DUPLICATE": "Dubare", + "DUPLICATE_BLOCK": "Dubare", "DELETE": "Jê bibe", "ADD_COMMENT": "Şîrove tevlî bike", "REMOVE_COMMENT": "Şîroveyê Rake", @@ -13468,7 +13468,7 @@ ScratchMsgs.locales["ckb"] = "CATEGORY_OPERATORS": "كرده‌هێماکان", "CATEGORY_VARIABLES": "گۆڕاوەکان", "CATEGORY_MYBLOCKS": "بلۆکەکانم", - "DUPLICATE": "هاوشێوەکردنەوە", + "DUPLICATE_BLOCK": "هاوشێوەکردنەوە", "DELETE": "سڕینەوە", "ADD_COMMENT": "زیادکردنی لێدوان", "REMOVE_COMMENT": "لابردنی لێدوان", @@ -13755,7 +13755,7 @@ ScratchMsgs.locales["lv"] = "CATEGORY_OPERATORS": "Operatori", "CATEGORY_VARIABLES": "Mainīgie", "CATEGORY_MYBLOCKS": "Mani bloki", - "DUPLICATE": "Dublēt", + "DUPLICATE_BLOCK": "Dublēt", "DELETE": "Dzēst", "ADD_COMMENT": "Pievienot komentāru", "REMOVE_COMMENT": "Noņemt komentāru", @@ -14042,7 +14042,7 @@ ScratchMsgs.locales["lt"] = "CATEGORY_OPERATORS": "Matematika", "CATEGORY_VARIABLES": "Kintamieji", "CATEGORY_MYBLOCKS": "Mano Komandos", - "DUPLICATE": "Kurti kopiją", + "DUPLICATE_BLOCK": "Kurti kopiją", "DELETE": "Ištrinti", "ADD_COMMENT": "Pridėti komentarą", "REMOVE_COMMENT": "Pašalinti komentarą", @@ -14329,7 +14329,7 @@ ScratchMsgs.locales["hu"] = "CATEGORY_OPERATORS": "Műveletek", "CATEGORY_VARIABLES": "Változók", "CATEGORY_MYBLOCKS": "Blokkjaim", - "DUPLICATE": "Duplikálás", + "DUPLICATE_BLOCK": "Duplikálás", "DELETE": "Törlés", "ADD_COMMENT": "Megjegyzés", "REMOVE_COMMENT": "Megjegyzés eltávolítása", @@ -14616,7 +14616,7 @@ ScratchMsgs.locales["mi"] = "CATEGORY_OPERATORS": "Tohutūmahi", "CATEGORY_VARIABLES": "Ngā Taurangi", "CATEGORY_MYBLOCKS": "Aku Paraka", - "DUPLICATE": "Tāruatia", + "DUPLICATE_BLOCK": "Tāruatia", "DELETE": "Mukua", "ADD_COMMENT": "Tāpiri Tākupu", "REMOVE_COMMENT": "Mukua te Tākupu", @@ -14903,7 +14903,7 @@ ScratchMsgs.locales["mn"] = "CATEGORY_OPERATORS": "Тоолохуй", "CATEGORY_VARIABLES": "Хувьсагч", "CATEGORY_MYBLOCKS": "Миний блокууд", - "DUPLICATE": "Хувилах", + "DUPLICATE_BLOCK": "Хувилах", "DELETE": "Устгах", "ADD_COMMENT": "Тайлбар нэмэх", "REMOVE_COMMENT": "Тайлбар устгах", @@ -15190,7 +15190,7 @@ ScratchMsgs.locales["nl"] = "CATEGORY_OPERATORS": "Functies", "CATEGORY_VARIABLES": "Variabelen", "CATEGORY_MYBLOCKS": "Mijn blokken", - "DUPLICATE": "Kopie maken", + "DUPLICATE_BLOCK": "Kopie maken", "DELETE": "Verwijderen", "ADD_COMMENT": "Commentaar toevoegen", "REMOVE_COMMENT": "Commentaar verwijderen", @@ -15477,7 +15477,7 @@ ScratchMsgs.locales["ja"] = "CATEGORY_OPERATORS": "演算", "CATEGORY_VARIABLES": "変数", "CATEGORY_MYBLOCKS": "ブロック定義", - "DUPLICATE": "複製", + "DUPLICATE_BLOCK": "複製", "DELETE": "削除", "ADD_COMMENT": "コメントを追加", "REMOVE_COMMENT": "コメントを削除", @@ -15764,7 +15764,7 @@ ScratchMsgs.locales["ja-Hira"] = "CATEGORY_OPERATORS": "えんざん", "CATEGORY_VARIABLES": "へんすう", "CATEGORY_MYBLOCKS": "ブロックていぎ", - "DUPLICATE": "ふくせい", + "DUPLICATE_BLOCK": "ふくせい", "DELETE": "さくじょ", "ADD_COMMENT": "コメントをついか", "REMOVE_COMMENT": "コメントをさくじょ", @@ -16051,7 +16051,7 @@ ScratchMsgs.locales["nb"] = "CATEGORY_OPERATORS": "Operatorer", "CATEGORY_VARIABLES": "Variabler", "CATEGORY_MYBLOCKS": "Mine klosser", - "DUPLICATE": "Lag en kopi", + "DUPLICATE_BLOCK": "Lag en kopi", "DELETE": "Slett", "ADD_COMMENT": "Skriv en kommentar", "REMOVE_COMMENT": "Fjern kommentar", @@ -16338,7 +16338,7 @@ ScratchMsgs.locales["nn"] = "CATEGORY_OPERATORS": "Operatorar", "CATEGORY_VARIABLES": "Variablar", "CATEGORY_MYBLOCKS": "Mine klossar", - "DUPLICATE": "Lag ein kopi", + "DUPLICATE_BLOCK": "Lag ein kopi", "DELETE": "Slett", "ADD_COMMENT": "Skriv kommentar", "REMOVE_COMMENT": "Fjern kommentar", @@ -16625,7 +16625,7 @@ ScratchMsgs.locales["oc"] = "CATEGORY_OPERATORS": "Operators", "CATEGORY_VARIABLES": "Variablas", "CATEGORY_MYBLOCKS": "Mos Blòcs", - "DUPLICATE": "Desdoblar", + "DUPLICATE_BLOCK": "Desdoblar", "DELETE": "Suprimir", "ADD_COMMENT": "Apondre Comentari", "REMOVE_COMMENT": "Suprimir Comentari", @@ -16912,7 +16912,7 @@ ScratchMsgs.locales["or"] = "CATEGORY_OPERATORS": "ଅପରେଟର ଗୁଡିକ", "CATEGORY_VARIABLES": "ଭେରିଏବଲ୍ ଗୁଡିକ", "CATEGORY_MYBLOCKS": "ମୋ ବ୍ଲକ ଗୁଡି଼କ", - "DUPLICATE": "ପ୍ରତିରୂପ", + "DUPLICATE_BLOCK": "ପ୍ରତିରୂପ", "DELETE": "ଲିଭାଅ", "ADD_COMMENT": "ଟିପ୍ପଣୀ ଦିଅ", "REMOVE_COMMENT": "ଟିପ୍ପଣୀ ଲିଭାଅ", @@ -17199,7 +17199,7 @@ ScratchMsgs.locales["uz"] = "CATEGORY_OPERATORS": "Amallar", "CATEGORY_VARIABLES": "O'zgaruvchi", "CATEGORY_MYBLOCKS": "Mening bloklarim", - "DUPLICATE": "Nusxalash", + "DUPLICATE_BLOCK": "Nusxalash", "DELETE": "O'chirish", "ADD_COMMENT": "Izoh qo'shish", "REMOVE_COMMENT": "Izohni o'chirish", @@ -17486,7 +17486,7 @@ ScratchMsgs.locales["th"] = "CATEGORY_OPERATORS": "ตัวดำเนินการ", "CATEGORY_VARIABLES": "ตัวแปร", "CATEGORY_MYBLOCKS": "บล็อกของฉัน", - "DUPLICATE": "ทำซ้ำ", + "DUPLICATE_BLOCK": "ทำซ้ำ", "DELETE": "ลบ", "ADD_COMMENT": "เพิ่มคำอธิบาย", "REMOVE_COMMENT": "ลบคำอธิบาย", @@ -17773,7 +17773,7 @@ ScratchMsgs.locales["km"] = "CATEGORY_OPERATORS": "ប្រមាណវិធី", "CATEGORY_VARIABLES": "អថេរ", "CATEGORY_MYBLOCKS": "ប្លុកខ្ញុំ", - "DUPLICATE": "ចម្លង", + "DUPLICATE_BLOCK": "ចម្លង", "DELETE": "លុប", "ADD_COMMENT": "ដាក់មតិ", "REMOVE_COMMENT": "លុបមតិ", @@ -18060,7 +18060,7 @@ ScratchMsgs.locales["pl"] = "CATEGORY_OPERATORS": "Wyrażenia", "CATEGORY_VARIABLES": "Zmienne", "CATEGORY_MYBLOCKS": "Moje bloki", - "DUPLICATE": "Duplikuj", + "DUPLICATE_BLOCK": "Duplikuj", "DELETE": "Usuń", "ADD_COMMENT": "Dodaj komentarz", "REMOVE_COMMENT": "Usuń komentarz", @@ -18347,7 +18347,7 @@ ScratchMsgs.locales["pt"] = "CATEGORY_OPERATORS": "Operadores", "CATEGORY_VARIABLES": "Variáveis", "CATEGORY_MYBLOCKS": "Os Meus Blocos", - "DUPLICATE": "Duplicar", + "DUPLICATE_BLOCK": "Duplicar", "DELETE": "Remover", "ADD_COMMENT": "Adicionar Comentário", "REMOVE_COMMENT": "Remover Comentário", @@ -18634,7 +18634,7 @@ ScratchMsgs.locales["pt-br"] = "CATEGORY_OPERATORS": "Operadores", "CATEGORY_VARIABLES": "Variáveis", "CATEGORY_MYBLOCKS": "Meus Blocos", - "DUPLICATE": "Duplicar", + "DUPLICATE_BLOCK": "Duplicar", "DELETE": "Apagar", "ADD_COMMENT": "Comentar", "REMOVE_COMMENT": "Remover Comentário", @@ -18921,7 +18921,7 @@ ScratchMsgs.locales["rap"] = "CATEGORY_OPERATORS": "operadores", "CATEGORY_VARIABLES": "variables", "CATEGORY_MYBLOCKS": "taʾaku avhata poto roa mekera", - "DUPLICATE": "haka rahi", + "DUPLICATE_BLOCK": "haka rahi", "DELETE": "haka kore", "ADD_COMMENT": "hahaʾo te vanāŋa", "REMOVE_COMMENT": "haka kore te vanaŋa", @@ -19208,7 +19208,7 @@ ScratchMsgs.locales["ro"] = "CATEGORY_OPERATORS": "Operatori", "CATEGORY_VARIABLES": "Variabile", "CATEGORY_MYBLOCKS": "Blocurile mele", - "DUPLICATE": "Duplică", + "DUPLICATE_BLOCK": "Duplică", "DELETE": "Șterge", "ADD_COMMENT": "Adaugă comentariu", "REMOVE_COMMENT": "Șterge comentariul", @@ -19495,7 +19495,7 @@ ScratchMsgs.locales["ru"] = "CATEGORY_OPERATORS": "Операторы", "CATEGORY_VARIABLES": "Переменные", "CATEGORY_MYBLOCKS": "Другие блоки", - "DUPLICATE": "Дублировать", + "DUPLICATE_BLOCK": "Дублировать", "DELETE": "Удалить", "ADD_COMMENT": "Добавить комментарий", "REMOVE_COMMENT": "Удалить комментарий", @@ -19782,7 +19782,7 @@ ScratchMsgs.locales["nso"] = "CATEGORY_OPERATORS": "Bašomiši", "CATEGORY_VARIABLES": "Diphetošo", "CATEGORY_MYBLOCKS": "Dipoloko tša Ka", - "DUPLICATE": "Pedifatša", + "DUPLICATE_BLOCK": "Pedifatša", "DELETE": "Phumula", "ADD_COMMENT": "Tlatša Tshwayotshwayo", "REMOVE_COMMENT": "Tloša Tshwayotshwayo", @@ -20069,7 +20069,7 @@ ScratchMsgs.locales["tn"] = "CATEGORY_OPERATORS": "Badiri", "CATEGORY_VARIABLES": "Dipharologano", "CATEGORY_MYBLOCKS": "Diboloko tsa me", - "DUPLICATE": "Gatisa", + "DUPLICATE_BLOCK": "Gatisa", "DELETE": "Phimola", "ADD_COMMENT": "Tsenya kakgelo", "REMOVE_COMMENT": "Tlosa kakgelo", @@ -20356,7 +20356,7 @@ ScratchMsgs.locales["sk"] = "CATEGORY_OPERATORS": "Operácie", "CATEGORY_VARIABLES": "Premenné", "CATEGORY_MYBLOCKS": "Nové bloky", - "DUPLICATE": "duplikuj", + "DUPLICATE_BLOCK": "duplikuj", "DELETE": "zruš", "ADD_COMMENT": "pridaj komentár", "REMOVE_COMMENT": "zruš komentár", @@ -20643,7 +20643,7 @@ ScratchMsgs.locales["sl"] = "CATEGORY_OPERATORS": "Operatorji", "CATEGORY_VARIABLES": "Spremenljivke", "CATEGORY_MYBLOCKS": "Moji bloki", - "DUPLICATE": "Podvoji", + "DUPLICATE_BLOCK": "Podvoji", "DELETE": "Izbriši", "ADD_COMMENT": "Dodaj komentar", "REMOVE_COMMENT": "Odstrani komentar", @@ -20930,7 +20930,7 @@ ScratchMsgs.locales["sr"] = "CATEGORY_OPERATORS": "Оператори", "CATEGORY_VARIABLES": "Променљиве", "CATEGORY_MYBLOCKS": "Моји блокови", - "DUPLICATE": "Умножи", + "DUPLICATE_BLOCK": "Умножи", "DELETE": "Обриши", "ADD_COMMENT": "Додај коментар", "REMOVE_COMMENT": "Уклони коментар", @@ -21217,7 +21217,7 @@ ScratchMsgs.locales["fi"] = "CATEGORY_OPERATORS": "Toiminnot", "CATEGORY_VARIABLES": "Muuttujat", "CATEGORY_MYBLOCKS": "Lohkoni", - "DUPLICATE": "Kopioi", + "DUPLICATE_BLOCK": "Kopioi", "DELETE": "Poista", "ADD_COMMENT": "Lisää kommentti", "REMOVE_COMMENT": "Poista kommentti", @@ -21504,7 +21504,7 @@ ScratchMsgs.locales["sv"] = "CATEGORY_OPERATORS": "Operatorer", "CATEGORY_VARIABLES": "Variabler", "CATEGORY_MYBLOCKS": "Mina block", - "DUPLICATE": "Kopiera", + "DUPLICATE_BLOCK": "Kopiera", "DELETE": "Radera", "ADD_COMMENT": "Lägg till kommentar", "REMOVE_COMMENT": "Ta bort kommentar", @@ -21791,7 +21791,7 @@ ScratchMsgs.locales["vi"] = "CATEGORY_OPERATORS": "Các phép toán", "CATEGORY_VARIABLES": "Các biến số", "CATEGORY_MYBLOCKS": "Khối của tôi", - "DUPLICATE": "Nhân bản", + "DUPLICATE_BLOCK": "Nhân bản", "DELETE": "Xóa", "ADD_COMMENT": "Thêm chú thích", "REMOVE_COMMENT": "Xóa chú thích", @@ -22078,7 +22078,7 @@ ScratchMsgs.locales["tr"] = "CATEGORY_OPERATORS": "Operatörler", "CATEGORY_VARIABLES": "Değişkenler", "CATEGORY_MYBLOCKS": "Bloklarım", - "DUPLICATE": "Çoğalt", + "DUPLICATE_BLOCK": "Çoğalt", "DELETE": "Sil", "ADD_COMMENT": "Yorum Ekle", "REMOVE_COMMENT": "Yorumu Sil", @@ -22365,7 +22365,7 @@ ScratchMsgs.locales["uk"] = "CATEGORY_OPERATORS": "Оператори", "CATEGORY_VARIABLES": "Змінні", "CATEGORY_MYBLOCKS": "Мої блоки", - "DUPLICATE": "Дублювати", + "DUPLICATE_BLOCK": "Дублювати", "DELETE": "Вилучити", "ADD_COMMENT": "Додати коментар", "REMOVE_COMMENT": "Вилучити коментар", @@ -22652,7 +22652,7 @@ ScratchMsgs.locales["zh-cn"] = "CATEGORY_OPERATORS": "运算", "CATEGORY_VARIABLES": "变量", "CATEGORY_MYBLOCKS": "自制积木", - "DUPLICATE": "复制", + "DUPLICATE_BLOCK": "复制", "DELETE": "删除", "ADD_COMMENT": "添加注释", "REMOVE_COMMENT": "删除注释", @@ -22939,7 +22939,7 @@ ScratchMsgs.locales["zh-tw"] = "CATEGORY_OPERATORS": "運算", "CATEGORY_VARIABLES": "變數", "CATEGORY_MYBLOCKS": "函式積木", - "DUPLICATE": "複製", + "DUPLICATE_BLOCK": "複製", "DELETE": "刪除", "ADD_COMMENT": "添加註解", "REMOVE_COMMENT": "移除註解", From dbb79ea005d8133a98b6259ddd85a46ac79ff265 Mon Sep 17 00:00:00 2001 From: Aaron Dodson Date: Tue, 10 Sep 2024 08:38:40 -0700 Subject: [PATCH 086/130] refactor: add and use explicit field registration methods (#172) * refactor: add and use explicit field registration methods * chore: add comment to field registration methods --- src/fields/field_angle.js | 7 ++++- src/fields/field_colour_slider.js | 7 ++++- src/fields/field_dropdown.js | 9 +++++-- src/fields/field_matrix.js | 9 +++++-- src/fields/field_note.js | 7 ++++- src/fields/field_number.js | 9 +++++-- src/fields/field_textinput_removable.js | 13 +++++++--- src/fields/field_variable.js | 9 +++++-- src/fields/field_variable_getter.js | 9 +++++-- src/fields/field_vertical_separator.js | 13 +++++++--- src/index.js | 34 ++++++++++++++++++------- 11 files changed, 96 insertions(+), 30 deletions(-) diff --git a/src/fields/field_angle.js b/src/fields/field_angle.js index c0dc321cd3..b33a36c0eb 100644 --- a/src/fields/field_angle.js +++ b/src/fields/field_angle.js @@ -423,4 +423,9 @@ class FieldAngle extends Blockly.FieldNumber { } } -Blockly.fieldRegistry.register("field_angle", FieldAngle); +/** + * Register the field and any dependencies. + */ +export function registerFieldAngle() { + Blockly.fieldRegistry.register("field_angle", FieldAngle); +} diff --git a/src/fields/field_colour_slider.js b/src/fields/field_colour_slider.js index b70b1ea4f6..89c292b222 100644 --- a/src/fields/field_colour_slider.js +++ b/src/fields/field_colour_slider.js @@ -380,4 +380,9 @@ export class FieldColourSlider extends FieldColour { } } -Blockly.fieldRegistry.register("field_colour_slider", FieldColourSlider); +/** + * Register the field and any dependencies. + */ +export function registerFieldColourSlider() { + Blockly.fieldRegistry.register("field_colour_slider", FieldColourSlider); +} diff --git a/src/fields/field_dropdown.js b/src/fields/field_dropdown.js index 1a3d553bc3..ff8869fb82 100644 --- a/src/fields/field_dropdown.js +++ b/src/fields/field_dropdown.js @@ -33,5 +33,10 @@ class FieldDropdown extends Blockly.FieldDropdown { } } -Blockly.fieldRegistry.unregister("field_dropdown"); -Blockly.fieldRegistry.register("field_dropdown", FieldDropdown); +/** + * Register the field and any dependencies. + */ +export function registerFieldDropdown() { + Blockly.fieldRegistry.unregister("field_dropdown"); + Blockly.fieldRegistry.register("field_dropdown", FieldDropdown); +} diff --git a/src/fields/field_matrix.js b/src/fields/field_matrix.js index 0deee6c900..1a242585d7 100644 --- a/src/fields/field_matrix.js +++ b/src/fields/field_matrix.js @@ -31,7 +31,7 @@ import * as Blockly from "blockly/core"; * @extends {Blockly.Field} * @constructor */ -export class FieldMatrix extends Blockly.Field { +class FieldMatrix extends Blockly.Field { originalStyle; constructor(matrix) { @@ -626,4 +626,9 @@ export class FieldMatrix extends Blockly.Field { } } -Blockly.fieldRegistry.register("field_matrix", FieldMatrix); +/** + * Register the field and any dependencies. + */ +export function registerFieldMatrix() { + Blockly.fieldRegistry.register("field_matrix", FieldMatrix); +} diff --git a/src/fields/field_note.js b/src/fields/field_note.js index 20de842164..63da4b4f0c 100644 --- a/src/fields/field_note.js +++ b/src/fields/field_note.js @@ -929,4 +929,9 @@ export class FieldNote extends Blockly.FieldTextInput { } } -Blockly.fieldRegistry.register("field_note", FieldNote); +/** + * Register the field and any dependencies. + */ +export function registerFieldNote() { + Blockly.fieldRegistry.register("field_note", FieldNote); +} diff --git a/src/fields/field_number.js b/src/fields/field_number.js index c44c8de250..546543f172 100644 --- a/src/fields/field_number.js +++ b/src/fields/field_number.js @@ -371,5 +371,10 @@ class FieldNumberPicker extends Blockly.FieldNumber { FieldNumberPicker.prototype.DEFAULT_VALUE = ""; -Blockly.fieldRegistry.unregister("field_number"); -Blockly.fieldRegistry.register("field_number", FieldNumberPicker); +/** + * Register the field and any dependencies. + */ +export function registerFieldNumber() { + Blockly.fieldRegistry.unregister("field_number"); + Blockly.fieldRegistry.register("field_number", FieldNumberPicker); +} diff --git a/src/fields/field_textinput_removable.js b/src/fields/field_textinput_removable.js index 27bafa3feb..a5e9f23c06 100644 --- a/src/fields/field_textinput_removable.js +++ b/src/fields/field_textinput_removable.js @@ -93,7 +93,12 @@ export class FieldTextInputRemovable extends Blockly.FieldTextInput { } } -Blockly.fieldRegistry.register( - "field_input_removable", - FieldTextInputRemovable -); +/** + * Register the field and any dependencies. + */ +export function registerFieldTextInputRemovable() { + Blockly.fieldRegistry.register( + "field_input_removable", + FieldTextInputRemovable + ); +} diff --git a/src/fields/field_variable.js b/src/fields/field_variable.js index 521f69fa11..d3219e35f8 100644 --- a/src/fields/field_variable.js +++ b/src/fields/field_variable.js @@ -162,5 +162,10 @@ class FieldVariable extends Blockly.FieldVariable { } } -Blockly.fieldRegistry.unregister("field_variable"); -Blockly.fieldRegistry.register("field_variable", FieldVariable); +/** + * Register the field and any dependencies. + */ +export function registerFieldVariable() { + Blockly.fieldRegistry.unregister("field_variable"); + Blockly.fieldRegistry.register("field_variable", FieldVariable); +} diff --git a/src/fields/field_variable_getter.js b/src/fields/field_variable_getter.js index a7a56e3d0d..75157c3612 100644 --- a/src/fields/field_variable_getter.js +++ b/src/fields/field_variable_getter.js @@ -29,7 +29,7 @@ import * as Blockly from "blockly/core"; * Class for a variable getter field. * @param {string} allowedVariableType The type of variables this field can display. */ -export class FieldVariableGetter extends Blockly.FieldLabel { +class FieldVariableGetter extends Blockly.FieldLabel { constructor(allowedVariableType = "") { super(Blockly.Field.SKIP_SETUP); this.SERIALIZABLE = true; @@ -101,4 +101,9 @@ export class FieldVariableGetter extends Blockly.FieldLabel { } } -Blockly.fieldRegistry.register("field_variable_getter", FieldVariableGetter); +/** + * Register the field and any dependencies. + */ +export function registerFieldVariableGetter() { + Blockly.fieldRegistry.register("field_variable_getter", FieldVariableGetter); +} diff --git a/src/fields/field_vertical_separator.js b/src/fields/field_vertical_separator.js index ae252094ed..c7087642e0 100644 --- a/src/fields/field_vertical_separator.js +++ b/src/fields/field_vertical_separator.js @@ -128,7 +128,12 @@ class FieldVerticalSeparator extends Blockly.Field { } } -Blockly.fieldRegistry.register( - "field_vertical_separator", - FieldVerticalSeparator -); +/** + * Register the field and any dependencies. + */ +export function registerFieldVerticalSeparator() { + Blockly.fieldRegistry.register( + "field_vertical_separator", + FieldVerticalSeparator + ); +} diff --git a/src/index.js b/src/index.js index 84055bfe20..e3ddc88a6b 100644 --- a/src/index.js +++ b/src/index.js @@ -23,7 +23,6 @@ import "./blocks/sound.js"; import * as scratchBlocksUtils from "./scratch_blocks_utils.js"; import * as ScratchVariables from "./variables.js"; import "./css.js"; -import "./fields/field_vertical_separator.js"; import "./renderer/renderer.js"; import * as contextMenuItems from "./context_menu_items.js"; import { @@ -47,20 +46,25 @@ import "./events/events_block_comment_delete.js"; import "./events/events_block_comment_move.js"; import "./events/events_block_comment_resize.js"; import "./events/events_scratch_variable_create.js"; -import "./fields/field_dropdown.js"; -import "./fields/field_variable.js"; -import "./fields/field_variable_getter.js"; import { buildShadowFilter } from "./shadows.js"; +import { registerFieldAngle } from "./fields/field_angle.js"; +import { + registerFieldColourSlider, + FieldColourSlider, +} from "./fields/field_colour_slider.js"; +import { registerFieldDropdown } from "./fields/field_dropdown.js"; +import { registerFieldMatrix } from "./fields/field_matrix.js"; +import { registerFieldNote, FieldNote } from "./fields/field_note.js"; +import { registerFieldNumber } from "./fields/field_number.js"; +import { registerFieldTextInputRemovable } from "./fields/field_textinput_removable.js"; +import { registerFieldVariableGetter } from "./fields/field_variable_getter.js"; +import { registerFieldVariable } from "./fields/field_variable.js"; +import { registerFieldVerticalSeparator } from "./fields/field_vertical_separator.js"; export * from "blockly/core"; export * from "./block_reporting.js"; export * from "./categories.js"; export * from "./procedures.js"; -export * from "./fields/field_angle.js"; -export * from "./fields/field_colour_slider.js"; -export * from "./fields/field_matrix.js"; -export * from "./fields/field_note.js"; -export * from "./fields/field_number.js"; export * from "../msg/scratch_msgs.js"; export * from "./constants.js"; export { glowStack }; @@ -68,8 +72,20 @@ export { scratchBlocksUtils }; export { CheckableContinuousFlyout }; export { ScratchVariables }; export { contextMenuItems }; +export { FieldColourSlider, FieldNote }; export function inject(container, options) { + registerFieldAngle(); + registerFieldColourSlider(); + registerFieldDropdown(); + registerFieldMatrix(); + registerFieldNote(); + registerFieldNumber(); + registerFieldTextInputRemovable(); + registerFieldVariableGetter(); + registerFieldVariable(); + registerFieldVerticalSeparator(); + Object.assign(options, { renderer: "scratch", plugins: { From 59896d2f55e12f5f28bb8bc615f4b5eb186e0ae6 Mon Sep 17 00:00:00 2001 From: Aaron Dodson Date: Thu, 12 Sep 2024 09:41:46 -0700 Subject: [PATCH 087/130] fix: fix the colors of the angle picker dropdown (#179) --- src/css.js | 2 -- src/fields/field_angle.js | 4 +++- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/css.js b/src/css.js index 753fec20b2..4833a7e353 100644 --- a/src/css.js +++ b/src/css.js @@ -694,9 +694,7 @@ const styles = ` } .blocklyAngleCircle { - stroke: var(--colour-motion-tertiary); stroke-width: 1; - fill: var(--colour-motion-secondary); } .blocklyAngleCenterPoint { diff --git a/src/fields/field_angle.js b/src/fields/field_angle.js index b33a36c0eb..0264c721eb 100644 --- a/src/fields/field_angle.js +++ b/src/fields/field_angle.js @@ -158,6 +158,8 @@ class FieldAngle extends Blockly.FieldNumber { cx: this.HALF, cy: this.HALF, r: this.RADIUS, + fill: this.getSourceBlock().getParent().getColourSecondary(), + stroke: this.getSourceBlock().getParent().getColourTertiary(), class: "blocklyAngleCircle", }, svg @@ -248,7 +250,7 @@ class FieldAngle extends Blockly.FieldNumber { Blockly.DropDownDiv.setColour( this.getSourceBlock().getParent().getColour(), - this.getSourceBlock().getColourTertiary() + this.getSourceBlock().getParent().getColourTertiary() ); Blockly.DropDownDiv.showPositionedByBlock(this, this.getSourceBlock()); From 303611a5475b4c5914d14c7fa04915d0cb0a0d03 Mon Sep 17 00:00:00 2001 From: Aaron Dodson Date: Mon, 16 Sep 2024 09:49:09 -0700 Subject: [PATCH 088/130] fix: show connection highlights for boolean inputs (#181) --- src/renderer/constants.js | 1 + src/renderer/renderer.js | 5 ++++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/renderer/constants.js b/src/renderer/constants.js index b7ea725a5d..d6a54753e8 100644 --- a/src/renderer/constants.js +++ b/src/renderer/constants.js @@ -9,6 +9,7 @@ import { cssVarify } from "../colours.js"; export class ConstantProvider extends Blockly.zelos.ConstantProvider { REPLACEMENT_GLOW_COLOUR = "#ffffff"; + SELECTED_GLOW_COLOUR = "#ffffff"; /** * Sets the visual theme used to render the workspace. diff --git a/src/renderer/renderer.js b/src/renderer/renderer.js index d142a10a37..88e7e24708 100644 --- a/src/renderer/renderer.js +++ b/src/renderer/renderer.js @@ -23,7 +23,10 @@ export class ScratchRenderer extends Blockly.zelos.Renderer { } shouldHighlightConnection(connection) { - return false; + return ( + connection.type === Blockly.ConnectionType.INPUT_VALUE && + connection.getCheck()?.includes("Boolean") + ); } } From e3dbad1feb19c5e72ac66ba9aa9e6f47580a414b Mon Sep 17 00:00:00 2001 From: Aaron Dodson Date: Tue, 17 Sep 2024 08:24:46 -0700 Subject: [PATCH 089/130] fix: correctly align extension block icons (#182) --- src/renderer/render_info.js | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/renderer/render_info.js b/src/renderer/render_info.js index 6ec561e6a6..8e7a674b3b 100644 --- a/src/renderer/render_info.js +++ b/src/renderer/render_info.js @@ -79,6 +79,15 @@ export class RenderInfo extends Blockly.zelos.RenderInfo { getElemCenterline_(row, elem) { if (this.isBowlerHatBlock() && Blockly.blockRendering.Types.isField(elem)) { return row.yPos + elem.height; + } else if ( + this.block_.isScratchExtension && + Blockly.blockRendering.Types.isField(elem) && + elem.field instanceof Blockly.FieldImage && + elem.field === this.block_.inputList[0].fieldRow[0] && + this.block_.previousConnection + ) { + // Vertically center the icon on extension blocks. + return super.getElemCenterline_(row, elem) + this.constants_.GRID_UNIT; } return super.getElemCenterline_(row, elem); } From 6c9d3a6026f67fd4a173c718d7a2ba66b69922f6 Mon Sep 17 00:00:00 2001 From: Aaron Dodson Date: Wed, 18 Sep 2024 12:12:21 -0700 Subject: [PATCH 090/130] fix: allow focusing fields in the flyout on mobile (#184) --- src/checkable_continuous_flyout.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/checkable_continuous_flyout.js b/src/checkable_continuous_flyout.js index 21098ec2b1..fb076aabc0 100644 --- a/src/checkable_continuous_flyout.js +++ b/src/checkable_continuous_flyout.js @@ -58,6 +58,7 @@ export class CheckableContinuousFlyout extends ContinuousFlyout { 2 * CheckableContinuousFlyout.CHECKBOX_MARGIN; constructor(workspaceOptions) { + workspaceOptions.modalInputs = false; super(workspaceOptions); this.tabWidth_ = -2; this.MARGIN = 12; From 6d1453082c3ed220c0ff09bf5b785a49df9f4312 Mon Sep 17 00:00:00 2001 From: Aaron Dodson Date: Wed, 18 Sep 2024 12:33:25 -0700 Subject: [PATCH 091/130] fix: fix positioning of categories when scrolling via the toolbox (#186) * fix: fix positioning of categories when scrolling via the toolbox * refactor: use GRID_UNIT for calculating flyout alignment --- src/checkable_continuous_flyout.js | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/checkable_continuous_flyout.js b/src/checkable_continuous_flyout.js index fb076aabc0..9d75cd53be 100644 --- a/src/checkable_continuous_flyout.js +++ b/src/checkable_continuous_flyout.js @@ -104,6 +104,26 @@ export class CheckableContinuousFlyout extends ContinuousFlyout { this.checkboxes_.clear(); } + layout_(contents, gaps) { + super.layout_(contents, gaps); + // We want large gaps between categories (see GAP_Y), but don't want those + // counted as part of the category for purposes of scrolling to show the + // category, so we reset/adjust the label gaps used for the scroll position + // calculation here. + this.labelGaps.fill( + this.getWorkspace().getRenderer().getConstants().GRID_UNIT + ); + } + + calculateBottomPadding(contentMetrics, viewMetrics) { + // Since we're messing with the alignment by munging the label gaps, we also + // need to adjust the bottom padding. + return ( + super.calculateBottomPadding(contentMetrics, viewMetrics) - + this.getWorkspace().getRenderer().getConstants().GRID_UNIT * 4 + ); + } + addBlockListeners_(root, block, rect) { if (block.checkboxInFlyout) { const coordinates = block.getRelativeToSurfaceXY(); From 37e0f10f4a59e1bb32734b955b7f2f17e4f2fca0 Mon Sep 17 00:00:00 2001 From: Aaron Dodson Date: Wed, 2 Oct 2024 09:21:53 -0700 Subject: [PATCH 092/130] fix: fix bug that prevented modal dialogs from appearing on mobile (#183) --- src/data_category.js | 11 ++++++++++- src/procedures.js | 9 ++++++++- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/src/data_category.js b/src/data_category.js index 303300e929..7e104cf2ef 100644 --- a/src/data_category.js +++ b/src/data_category.js @@ -426,7 +426,16 @@ function addCreateButton(xmlList, workspace, type) { } button.setAttribute("text", msg); button.setAttribute("callbackKey", callbackKey); - workspace.registerButtonCallback(callbackKey, callback); + workspace.registerButtonCallback(callbackKey, (b) => { + // Run the callback after a delay to avoid it getting captured by the React + // modal in scratch-gui and being registered as a click on the scrim that + // dismisses the dialog. + requestAnimationFrame(() => { + setTimeout(() => { + callback(b); + }); + }); + }); xmlList.push(button); } diff --git a/src/procedures.js b/src/procedures.js index 1ce112e0a2..3f59f52318 100644 --- a/src/procedures.js +++ b/src/procedures.js @@ -105,7 +105,14 @@ function addCreateButton_(workspace, xmlList) { var msg = Blockly.Msg.NEW_PROCEDURE; var callbackKey = "CREATE_PROCEDURE"; var callback = function () { - createProcedureDefCallback(workspace); + // Run the callback after a delay to avoid it getting captured by the React + // modal in scratch-gui and being registered as a click on the scrim that + // dismisses the dialog. + requestAnimationFrame(() => { + setTimeout(() => { + createProcedureDefCallback(workspace); + }); + }); }; button.setAttribute("text", msg); button.setAttribute("callbackKey", callbackKey); From 73d978e6c98d546774398e4d48faa7c181fdac11 Mon Sep 17 00:00:00 2001 From: Aaron Dodson Date: Wed, 2 Oct 2024 10:19:53 -0700 Subject: [PATCH 093/130] fix: fix color of block reporter dropdown text (#205) --- src/css.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/css.js b/src/css.js index 4833a7e353..6ce911cd98 100644 --- a/src/css.js +++ b/src/css.js @@ -235,6 +235,7 @@ const styles = ` text-align: center; font-family: "Helvetica Neue", Helvetica, sans-serif; font-size: .8em; + color: var(--colour-textFieldText); } .blocklyResizeSE { From 07016799832530cf851c14be484158e58bdaa9dd Mon Sep 17 00:00:00 2001 From: Aaron Dodson Date: Thu, 3 Oct 2024 11:41:25 -0700 Subject: [PATCH 094/130] feat: add a block inflater that supports recycling (#207) * feat: add a block inflater that supports recycling * chore: update JSDoc --- src/index.js | 2 + src/recyclable_block_flyout_inflater.js | 174 ++++++++++++++++++++++++ 2 files changed, 176 insertions(+) create mode 100644 src/recyclable_block_flyout_inflater.js diff --git a/src/index.js b/src/index.js index e3ddc88a6b..839501e855 100644 --- a/src/index.js +++ b/src/index.js @@ -60,6 +60,7 @@ import { registerFieldTextInputRemovable } from "./fields/field_textinput_remova import { registerFieldVariableGetter } from "./fields/field_variable_getter.js"; import { registerFieldVariable } from "./fields/field_variable.js"; import { registerFieldVerticalSeparator } from "./fields/field_vertical_separator.js"; +import { registerRecyclableBlockFlyoutInflater } from "./recyclable_block_flyout_inflater.js"; export * from "blockly/core"; export * from "./block_reporting.js"; @@ -85,6 +86,7 @@ export function inject(container, options) { registerFieldVariableGetter(); registerFieldVariable(); registerFieldVerticalSeparator(); + registerRecyclableBlockFlyoutInflater(); Object.assign(options, { renderer: "scratch", diff --git a/src/recyclable_block_flyout_inflater.js b/src/recyclable_block_flyout_inflater.js new file mode 100644 index 0000000000..06a3062057 --- /dev/null +++ b/src/recyclable_block_flyout_inflater.js @@ -0,0 +1,174 @@ +/** + * @license + * Copyright 2024 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + +import * as Blockly from "blockly/core"; + +/** + * A block inflater that caches and reuses blocks to improve performance. + */ +export class RecyclableBlockFlyoutInflater extends Blockly.BlockFlyoutInflater { + /** + * Whether or not block recycling is enabled. + * @type {boolean} + */ + recyclingEnabled = true; + + /** + * Map from block type to block instance. + * @type {Map} + */ + recycledBlocks = new Map(); + + /** + * Toggles whether or not recycling is enabled. + * + * @param {boolean} enabled True if recycling should be enabled. + */ + setRecyclingEnabled(enabled) { + this.recyclingEnabled = enabled; + } + + /** + * Creates a new block from the given block definition. + * + * @param {!Object} blockDefinition The definition to create a block from. + * @returns {!Blockly.BlockSvg} The newly created block. + */ + createBlock(blockDefinition) { + const blockType = this.getTypeFromDefinition(blockDefinition); + return ( + this.getRecycledBlock(blockType) ?? + super.createBlock(blockDefinition, this.flyoutWorkspace) + ); + } + + /** + * Returns the type of a block from an XML or JSON block definition. + * + * @param blockDefinition {!Object} The block definition to parse. + * @returns {string} The block type. + */ + getTypeFromDefinition(blockDefinition) { + if (blockDefinition["blockxml"]) { + const xml = + typeof blockDefinition["blockxml"] === "string" + ? Blockly.utils.xml.textToDom(blockDefinition["blockxml"]) + : blockDefinition["blockxml"]; + return xml.getAttribute("type"); + } else { + return blockDefinition["type"]; + } + } + + /** + * Puts a previously created block into the recycle bin and moves it to the + * top of the workspace. Used during large workspace swaps to limit the number + * of new DOM elements we need to create. + * + * @param {!Blockly.BlockSvg} block The block to recycle. + */ + recycleBlock(block) { + const xy = block.getRelativeToSurfaceXY(); + block.moveBy(-xy.x, -xy.y); + this.recycledBlocks.set(block.type, block); + } + + /** + * Returns a block from the cache of recycled blocks with the given type, or + * undefined if one cannot be found. + * + * @param {string} blockType The type of the block to try to recycle. + * @returns {?Blockly.BlockSvg} The recycled block, or undefined if + * one could not be recycled. + */ + getRecycledBlock(blockType) { + const block = this.recycledBlocks.get(blockType); + this.recycledBlocks.delete(blockType); + return block; + } + + /** + * Returns whether the given block can be recycled or not. + * + * @param {!Blockly.BlockSvg} block The block to check for recyclability. + * @returns {boolean} True if the block can be recycled. False otherwise. + */ + blockIsRecyclable(block) { + if (!this.recyclingEnabled) { + return false; + } + + // If the block needs to parse mutations, never recycle. + if (block.mutationToDom && block.domToMutation) { + return false; + } + + if (!block.isEnabled()) { + return false; + } + + for (const input of block.inputList) { + for (const field of input.fieldRow) { + // No variables. + if (field.referencesVariables()) { + return false; + } + if (field instanceof Blockly.FieldDropdown) { + if (field.isOptionListDynamic()) { + return false; + } + } + } + // Check children. + if (input.connection) { + const targetBlock = + /** @type {Blockly.BlockSvg} */ + (input.connection.targetBlock()); + if (targetBlock && !this.blockIsRecyclable(targetBlock)) { + return false; + } + } + } + return true; + } + + /** + * Disposes of the provided block. + * + * @param {!Blockly.BlockSvg} element The block to dispose of. + */ + disposeElement(element) { + if (this.blockIsRecyclable(element)) { + this.removeListeners(element.id); + this.recycleBlock(element); + } else { + super.disposeElement(element); + } + } + + /** + * Clears the cache of recycled blocks. + */ + emptyRecycledBlocks() { + this.recycledBlocks + .values() + .forEach((block) => block.dispose(false, false)); + this.recycledBlocks.clear(); + } +} + +/** + * Registers the recyclable block flyout inflater, replacing the standard + * block flyout inflater. + */ +export function registerRecyclableBlockFlyoutInflater() { + Blockly.registry.unregister(Blockly.registry.Type.FLYOUT_INFLATER, "block"); + Blockly.registry.register( + Blockly.registry.Type.FLYOUT_INFLATER, + "block", + RecyclableBlockFlyoutInflater + ); +} From 39b2162db62973860c904f0b78f1d7f27abebc99 Mon Sep 17 00:00:00 2001 From: Aaron Dodson Date: Thu, 3 Oct 2024 11:44:15 -0700 Subject: [PATCH 095/130] feat: add bubbles/icons for block flyout checkboxes (#208) * feat: add bubbles/icons for block flyout checkboxes * chore: update JSDoc * refactor: rename to FlyoutCheckboxIcon * chore: rename the checkbox_icon.js file --- src/blocks/vertical_extensions.js | 2 + src/checkbox_bubble.js | 282 ++++++++++++++++++++++++++++++ src/css.js | 2 +- src/flyout_checkbox_icon.js | 88 ++++++++++ src/index.js | 2 + 5 files changed, 375 insertions(+), 1 deletion(-) create mode 100644 src/checkbox_bubble.js create mode 100644 src/flyout_checkbox_icon.js diff --git a/src/blocks/vertical_extensions.js b/src/blocks/vertical_extensions.js index 406d036f2d..bbdc75c396 100644 --- a/src/blocks/vertical_extensions.js +++ b/src/blocks/vertical_extensions.js @@ -28,6 +28,7 @@ import * as Blockly from "blockly/core"; import { ScratchProcedures } from "../procedures.js"; import * as Constants from "../constants.js"; +import { FlyoutCheckboxIcon } from "../flyout_checkbox_icon.js"; const VerticalExtensions = {}; /** @@ -149,6 +150,7 @@ VerticalExtensions.OUTPUT_BOOLEAN = function () { * flyout to toggle display of their current value in a chip on the stage. */ VerticalExtensions.MONITOR_BLOCK = function () { + this.addIcon(new FlyoutCheckboxIcon(this)); this.checkboxInFlyout = true; }; diff --git a/src/checkbox_bubble.js b/src/checkbox_bubble.js new file mode 100644 index 0000000000..e00d41f31f --- /dev/null +++ b/src/checkbox_bubble.js @@ -0,0 +1,282 @@ +/** + * @license + * Copyright 2024 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + +import * as Blockly from "blockly/core"; + +/** + * A checkbox shown next to reporter blocks in the flyout. + * @implements {Blockly.IBubble} + * @implements {Blockly.IRenderedElement} + */ +export class CheckboxBubble { + /** + * Size of a checkbox next to a variable reporter. + * @type {number} + * @const + */ + static CHECKBOX_SIZE = 25; + + /** + * Amount of touchable padding around reporter checkboxes. + * @type {number} + * @const + */ + static CHECKBOX_TOUCH_PADDING = 12; + + /** + * SVG path data for checkmark in checkbox. + * @type {string} + * @const + */ + static CHECKMARK_PATH = + "M" + + CheckboxBubble.CHECKBOX_SIZE / 4 + + " " + + CheckboxBubble.CHECKBOX_SIZE / 2 + + "L" + + (5 * CheckboxBubble.CHECKBOX_SIZE) / 12 + + " " + + (2 * CheckboxBubble.CHECKBOX_SIZE) / 3 + + "L" + + (3 * CheckboxBubble.CHECKBOX_SIZE) / 4 + + " " + + CheckboxBubble.CHECKBOX_SIZE / 3; + + /** + * Size of the checkbox corner radius + * @type {number} + * @const + */ + static CHECKBOX_CORNER_RADIUS = 5; + + /** + * @type {number} + * @const + */ + static CHECKBOX_MARGIN = 12; + + /** + * Total additional width of a row that contains a checkbox. + * @type {number} + * @const + */ + static CHECKBOX_SPACE_X = + CheckboxBubble.CHECKBOX_SIZE + 2 * CheckboxBubble.CHECKBOX_MARGIN; + + /** + * Root SVG element for this bubble. + * @type {!SVGGElement} + */ + svgRoot; + + /** + * Identifier for click handler, to allow unregistering during disposal. + * @type {!Blockly.browserEvents.Data} + */ + clickListener; + + /** + * Whether or not this bubble is displayed as checked. Note that the source of + * truth is the Scratch VM. + * @type {boolean} + */ + checked = false; + + /** + * The location of this bubble in workspace coordinates. + * @type {!Blockly.utils.Coordinate} + */ + location = new Blockly.utils.Coordinate(0, 0); + + /** + * Creates a new flyout checkbox bubble. + * + * @param {!Blockly.BlockSvg} sourceBlock The block this bubble should be + * associated with. + */ + constructor(sourceBlock) { + this.sourceBlock = sourceBlock; + this.svgRoot = Blockly.utils.dom.createSvgElement( + Blockly.utils.Svg.G, + {}, + this.sourceBlock.workspace.getBubbleCanvas() + ); + + const touchMargin = CheckboxBubble.CHECKBOX_TOUCH_PADDING; + const checkboxGroup = Blockly.utils.dom.createSvgElement( + "g", + { + fill: "transparent", + }, + null + ); + Blockly.utils.dom.createSvgElement( + "rect", + { + class: "blocklyFlyoutCheckbox", + height: CheckboxBubble.CHECKBOX_SIZE, + width: CheckboxBubble.CHECKBOX_SIZE, + rx: CheckboxBubble.CHECKBOX_CORNER_RADIUS, + ry: CheckboxBubble.CHECKBOX_CORNER_RADIUS, + }, + checkboxGroup + ); + Blockly.utils.dom.createSvgElement( + "path", + { + class: "blocklyFlyoutCheckboxPath", + d: CheckboxBubble.CHECKMARK_PATH, + }, + checkboxGroup + ); + Blockly.utils.dom.createSvgElement( + "rect", + { + class: "blocklyTouchTargetBackground", + x: -touchMargin + "px", + y: -touchMargin + "px", + height: CheckboxBubble.CHECKBOX_SIZE + 2 * touchMargin, + width: CheckboxBubble.CHECKBOX_SIZE + 2 * touchMargin, + }, + checkboxGroup + ); + this.setChecked(this.isChecked(this.sourceBlock.id)); + + this.svgRoot.prepend(checkboxGroup); + + this.clickListener = Blockly.browserEvents.bind( + this.svgRoot, + "mousedown", + null, + (event) => { + this.setChecked(!this.checked); + event.stopPropagation(); + event.preventDefault(); + } + ); + this.updateLocation(); + } + + /** + * Sets whether or not this bubble should be displayed in the checked state. + * + * @param {boolean} checked True if this bubble should be checked. + */ + setChecked(checked) { + if (checked === this.checked) return; + + this.checked = checked; + if (this.checked) { + Blockly.utils.dom.addClass(this.svgRoot, "checked"); + } else { + Blockly.utils.dom.removeClass(this.svgRoot, "checked"); + } + + Blockly.Events.fire( + new Blockly.Events.BlockChange( + this.sourceBlock, + "checkbox", + null, + !this.checked, + this.checked + ) + ); + } + + /** + * Returns whether or not the specified block has its checkbox checked. + * + * This method is patched by scratch-gui to query the VM state. + * + * @param {string} blockId The ID of the block in question. + * @returns {boolean} True if the block's checkbox should be checked. + */ + isChecked(blockId) { + return false; + } + + /** + * Returns whether this bubble is movable by the user. + * + * @returns {boolean} Always returns false. + */ + isMovable() { + return false; + } + + /** + * Returns the root SVG element for this bubble. + * + * @returns {!SVGGElement} The root SVG element. + */ + getSvgRoot() { + return this.svgRoot; + } + + /** + * Recalculates this bubble's location, keeping it adjacent to its block. + */ + updateLocation() { + const blockLocation = this.sourceBlock.getRelativeToSurfaceXY(); + const blockBounds = this.sourceBlock.getHeightWidth(); + const x = this.sourceBlock.workspace.RTL + ? blockLocation.x + blockBounds.width + CheckboxBubble.CHECKBOX_MARGIN + : blockLocation.x - + CheckboxBubble.CHECKBOX_MARGIN - + CheckboxBubble.CHECKBOX_SIZE; + const y = + blockLocation.y + (blockBounds.height - CheckboxBubble.CHECKBOX_SIZE) / 2; + this.moveTo(x, y); + } + + /** + * Moves this bubble to the specified location. + * + * @param {number} x The location on the X axis to move to. + * @param {number} y The location on the Y axis to move to. + */ + moveTo(x, y) { + this.location.x = x; + this.location.y = y; + this.svgRoot.setAttribute("transform", `translate(${x}, ${y})`); + } + + /** + * Returns this bubble's location in workspace coordinates. + * + * @returns {!Blockly.utils.Coordinate} The bubble's location. + */ + getRelativeToSurfaceXY() { + return this.location; + } + + /** + * Disposes of this checkbox bubble. + */ + dispose() { + Blockly.utils.dom.removeNode(this.svgRoot); + Blockly.browserEvents.unbind(this.clickListener); + } + + // These methods are required by the interfaces, but intentionally have no + // implementation, largely because this bubble's location is fixed relative + // to its block and is not draggable by the user. + showContextMenu() {} + + setDragging(dragging) {} + + startDrag(event) {} + + drag(newLocation, event) {} + + moveDuringDrag(newLocation) {} + + endDrag() {} + + revertDrag() {} + + setDeleteStyle(enable) {} +} diff --git a/src/css.js b/src/css.js index 6ce911cd98..4fab79936e 100644 --- a/src/css.js +++ b/src/css.js @@ -1019,7 +1019,7 @@ const styles = ` stroke: #c8c8c8; } - .checked > .blocklyFlyoutCheckbox { + .checked .blocklyFlyoutCheckbox { fill: var(--colour-toolboxHover); stroke: rgba(0,0,0,0.2); } diff --git a/src/flyout_checkbox_icon.js b/src/flyout_checkbox_icon.js new file mode 100644 index 0000000000..68c285fb5c --- /dev/null +++ b/src/flyout_checkbox_icon.js @@ -0,0 +1,88 @@ +/** + * @license + * Copyright 2024 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + +import * as Blockly from "blockly/core"; +import { CheckboxBubble } from "./checkbox_bubble.js"; + +/** + * Invisible icon that exists solely to host the corresponding checkbox bubble. + * @implements {Blockly.IIcon} + * @implements {Blockly.IHasBubble} + */ +export class FlyoutCheckboxIcon { + sourceBlock; + checkboxBubble; + type = new Blockly.icons.IconType("checkbox"); + + constructor(sourceBlock) { + this.sourceBlock = sourceBlock; + if (this.sourceBlock.workspace.isFlyout) { + this.checkboxBubble = new CheckboxBubble(this.sourceBlock); + } + } + + getType() { + return this.type; + } + + getWeight() { + return -1; + } + + getSize() { + // Awful hack to cancel out the default padding added to icons. + return new Blockly.utils.Size(-8, 0); + } + + isShownWhenCollapsed() { + return false; + } + + isClickableInFlyout() { + return false; + } + + bubbleIsVisible() { + return this.sourceBlock.workspace.isFlyout; + } + + onLocationChange(blockOrigin) { + this.checkboxBubble?.updateLocation(); + } + + setChecked(checked) { + this.checkboxBubble?.setChecked(checked); + } + + dispose() { + this.checkboxBubble?.dispose(); + } + + // These methods are required by the interfaces, but intentionally have no + // implementation, largely because this icon has no visual representation. + applyColour() {} + + hideForInsertionMarker() {} + + updateEditable() {} + + updateCollapsed() {} + + setOffsetInBlock() {} + + onClick() {} + + async setBubbleVisible(visible) {} + + initView(pointerDownListener) {} +} + +Blockly.registry.register( + Blockly.registry.Type.ICON, + "checkbox", + FlyoutCheckboxIcon, + true +); diff --git a/src/index.js b/src/index.js index 839501e855..5f768c9b34 100644 --- a/src/index.js +++ b/src/index.js @@ -39,6 +39,7 @@ import "./scratch_dragger.js"; import "./scratch_variable_map.js"; import "./scratch_variable_model.js"; import "./scratch_connection_checker.js"; +import "./flyout_checkbox_icon.js"; import "./events/events_block_comment_change.js"; import "./events/events_block_comment_collapse.js"; import "./events/events_block_comment_create.js"; @@ -74,6 +75,7 @@ export { CheckableContinuousFlyout }; export { ScratchVariables }; export { contextMenuItems }; export { FieldColourSlider, FieldNote }; +export { CheckboxBubble } from "./checkbox_bubble.js"; export function inject(container, options) { registerFieldAngle(); From 7ce9991b6f1b6a504847097ebd098f0ec1e50e52 Mon Sep 17 00:00:00 2001 From: Aaron Dodson Date: Mon, 7 Oct 2024 12:54:54 -0700 Subject: [PATCH 096/130] fix: update the flyout for compatibility with the new flyout API (#209) * fix: update the flyout for compatibility with the new flyout API * chore: add comments to methods that should be removed in the future --- src/checkable_continuous_flyout.js | 340 ++++++------------------ src/recyclable_block_flyout_inflater.js | 20 ++ 2 files changed, 98 insertions(+), 262 deletions(-) diff --git a/src/checkable_continuous_flyout.js b/src/checkable_continuous_flyout.js index 9d75cd53be..81a83fdd96 100644 --- a/src/checkable_continuous_flyout.js +++ b/src/checkable_continuous_flyout.js @@ -1,92 +1,47 @@ +/** + * @license + * Copyright 2024 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + import * as Blockly from "blockly/core"; import { ContinuousFlyout } from "@blockly/continuous-toolbox"; +import { RecyclableBlockFlyoutInflater } from "./recyclable_block_flyout_inflater.js"; export class CheckableContinuousFlyout extends ContinuousFlyout { /** - * Size of a checkbox next to a variable reporter. - * @type {number} - * @const - */ - static CHECKBOX_SIZE = 25; - - /** - * Amount of touchable padding around reporter checkboxes. - * @type {number} - * @const - */ - static CHECKBOX_TOUCH_PADDING = 12; - - /** - * SVG path data for checkmark in checkbox. - * @type {string} - * @const - */ - static CHECKMARK_PATH = - "M" + - CheckableContinuousFlyout.CHECKBOX_SIZE / 4 + - " " + - CheckableContinuousFlyout.CHECKBOX_SIZE / 2 + - "L" + - (5 * CheckableContinuousFlyout.CHECKBOX_SIZE) / 12 + - " " + - (2 * CheckableContinuousFlyout.CHECKBOX_SIZE) / 3 + - "L" + - (3 * CheckableContinuousFlyout.CHECKBOX_SIZE) / 4 + - " " + - CheckableContinuousFlyout.CHECKBOX_SIZE / 3; - - /** - * Size of the checkbox corner radius - * @type {number} - * @const + * Creates a new CheckableContinuousFlyout. + * + * @param {!Blockly.Options} workspaceOptions Configuration options for the + * flyout workspace. */ - static CHECKBOX_CORNER_RADIUS = 5; - - /** - * @type {number} - * @const - */ - static CHECKBOX_MARGIN = ContinuousFlyout.prototype.MARGIN; - - /** - * Total additional width of a row that contains a checkbox. - * @type {number} - * @const - */ - static CHECKBOX_SPACE_X = - CheckableContinuousFlyout.CHECKBOX_SIZE + - 2 * CheckableContinuousFlyout.CHECKBOX_MARGIN; - constructor(workspaceOptions) { workspaceOptions.modalInputs = false; super(workspaceOptions); this.tabWidth_ = -2; this.MARGIN = 12; this.GAP_Y = 12; - CheckableContinuousFlyout.CHECKBOX_MARGIN = this.MARGIN; - - /** - * Map of checkboxes that correspond to monitored blocks. - * Each element is an object containing the SVG for the checkbox, a boolean - * for its checked state, and the block the checkbox is associated with. - * @type {!Object.} - * @private - */ - this.checkboxes_ = new Map(); - } - - initFlyoutButton_(button, x, y) { - if (button.isLabel()) { - button.height = 40; - } - super.initFlyoutButton_(button, x, y); } + /** + * Displays the given contents in the flyout. + * + * @param {!Object} flyoutDef The new contents to show in the flyout. + */ show(flyoutDef) { - this.clearOldCheckboxes(); super.show(flyoutDef); + const inflater = this.getInflaterForType("block"); + if (inflater instanceof RecyclableBlockFlyoutInflater) { + inflater.emptyRecycledBlocks(); + } } + /** + * Serializes a block to JSON in order to copy it to the main workspace. + * + * @param {!Blockly.BlockSvg} block The block to serialize. + * @returns {!Object} A JSON representation of the block. + */ serializeBlock(block) { const json = super.serializeBlock(block); // Delete the serialized block's ID so that a new one is generated when it is @@ -97,214 +52,75 @@ export class CheckableContinuousFlyout extends ContinuousFlyout { return json; } - clearOldCheckboxes() { - for (const checkbox of this.checkboxes_.values()) { - checkbox.svgRoot.remove(); - } - this.checkboxes_.clear(); - } - - layout_(contents, gaps) { - super.layout_(contents, gaps); - // We want large gaps between categories (see GAP_Y), but don't want those - // counted as part of the category for purposes of scrolling to show the - // category, so we reset/adjust the label gaps used for the scroll position - // calculation here. - this.labelGaps.fill( - this.getWorkspace().getRenderer().getConstants().GRID_UNIT - ); - } - - calculateBottomPadding(contentMetrics, viewMetrics) { - // Since we're messing with the alignment by munging the label gaps, we also - // need to adjust the bottom padding. - return ( - super.calculateBottomPadding(contentMetrics, viewMetrics) - - this.getWorkspace().getRenderer().getConstants().GRID_UNIT * 4 - ); + /** + * Set the state of a checkbox by block ID. + * @param {string} blockId ID of the block whose checkbox should be set + * @param {boolean} value Value to set the checkbox to. + * @public + */ + setCheckboxState(blockId, value) { + this.getWorkspace() + .getBlockById(blockId) + ?.getIcon("checkbox") + ?.setChecked(value); } - addBlockListeners_(root, block, rect) { - if (block.checkboxInFlyout) { - const coordinates = block.getRelativeToSurfaceXY(); - const checkbox = this.createCheckbox_( - block, - coordinates.x, - coordinates.y, - block.getHeightWidth() - ); - let moveX = coordinates.x; - if (this.RTL) { - moveX -= - CheckableContinuousFlyout.CHECKBOX_SIZE + - CheckableContinuousFlyout.CHECKBOX_MARGIN; - } else { - moveX += - CheckableContinuousFlyout.CHECKBOX_SIZE + - CheckableContinuousFlyout.CHECKBOX_MARGIN; - } - block.moveBy(moveX, 0); - this.listeners.push( - Blockly.browserEvents.bind( - checkbox.svgRoot, - "mousedown", - null, - this.checkboxClicked_(checkbox) - ) - ); - } - super.addBlockListeners_(root, block, rect); + getFlyoutScale() { + return 0.675; } - /** - * Respond to a click on a checkbox in the flyout. - * @param {!Object} checkboxObj An object containing the svg element of the - * checkbox, a boolean for the state of the checkbox, and the block the - * checkbox is associated with. - * @return {!Function} Function to call when checkbox is clicked. - * @private - */ - checkboxClicked_(checkboxObj) { - return function (e) { - this.setCheckboxState(checkboxObj.block.id, !checkboxObj.clicked); - // This event has been handled. No need to bubble up to the document. - e.stopPropagation(); - e.preventDefault(); - }.bind(this); + getWidth() { + return 250; } /** - * Create and place a checkbox corresponding to the given block. - * @param {!Blockly.Block} block The block to associate the checkbox to. - * @param {number} cursorX The x position of the cursor during this layout pass. - * @param {number} cursorY The y position of the cursor during this layout pass. - * @param {!{height: number, width: number}} blockHW The height and width of the - * block. - * @private + * Sets whether or not block recycling is enabled in the flyout. + * + * @param {boolean} enabled True if recycling should be enabled. */ - createCheckbox_(block, cursorX, cursorY, blockHW) { - var checkboxState = this.getCheckboxState(block.id); - var svgRoot = block.getSvgRoot(); - var extraSpace = - CheckableContinuousFlyout.CHECKBOX_SIZE + - CheckableContinuousFlyout.CHECKBOX_MARGIN; - var xOffset = this.RTL - ? this.getWidth() / this.workspace_.scale - extraSpace - : cursorX; - var yOffset = - cursorY + - blockHW.height / 2 - - CheckableContinuousFlyout.CHECKBOX_SIZE / 2; - var touchMargin = CheckableContinuousFlyout.CHECKBOX_TOUCH_PADDING; - var checkboxGroup = Blockly.utils.dom.createSvgElement( - "g", - { - transform: `translate(${xOffset}, ${yOffset})`, - fill: "transparent", - }, - null - ); - Blockly.utils.dom.createSvgElement( - "rect", - { - class: "blocklyFlyoutCheckbox", - height: CheckableContinuousFlyout.CHECKBOX_SIZE, - width: CheckableContinuousFlyout.CHECKBOX_SIZE, - rx: CheckableContinuousFlyout.CHECKBOX_CORNER_RADIUS, - ry: CheckableContinuousFlyout.CHECKBOX_CORNER_RADIUS, - }, - checkboxGroup - ); - Blockly.utils.dom.createSvgElement( - "path", - { - class: "blocklyFlyoutCheckboxPath", - d: CheckableContinuousFlyout.CHECKMARK_PATH, - }, - checkboxGroup - ); - Blockly.utils.dom.createSvgElement( - "rect", - { - class: "blocklyTouchTargetBackground", - x: -touchMargin + "px", - y: -touchMargin + "px", - height: CheckableContinuousFlyout.CHECKBOX_SIZE + 2 * touchMargin, - width: CheckableContinuousFlyout.CHECKBOX_SIZE + 2 * touchMargin, - }, - checkboxGroup - ); - var checkboxObj = { - svgRoot: checkboxGroup, - clicked: checkboxState, - block: block, - }; - - if (checkboxState) { - Blockly.utils.dom.addClass(checkboxObj.svgRoot, "checked"); + setRecyclingEnabled(enabled) { + const inflater = this.getInflaterForType("block"); + if (inflater instanceof RecyclableBlockFlyoutInflater) { + inflater.setRecyclingEnabled(enabled); } - - this.workspace_.getCanvas().insertBefore(checkboxGroup, svgRoot); - this.checkboxes_.set(block.id, checkboxObj); - return checkboxObj; } /** - * Set the state of a checkbox by block ID. - * @param {string} blockId ID of the block whose checkbox should be set - * @param {boolean} value Value to set the checkbox to. - * @public + * Records scroll position for each category in the toolbox. + * The scroll position is determined by the coordinates of each category's + * label after the entire flyout has been rendered. + * @package */ - setCheckboxState(blockId, value) { - var checkboxObj = this.checkboxes_.get(blockId); - if (!checkboxObj || checkboxObj.clicked === value) { - return; - } - - var oldValue = checkboxObj.clicked; - checkboxObj.clicked = value; - - if (checkboxObj.clicked) { - Blockly.utils.dom.addClass(checkboxObj.svgRoot, "checked"); - } else { - Blockly.utils.dom.removeClass(checkboxObj.svgRoot, "checked"); - } - - Blockly.Events.fire( - new Blockly.Events.BlockChange( - checkboxObj.block, - "checkbox", - null, - oldValue, - value + recordScrollPositions() { + // TODO(#211) Remove this once the continuous toolbox has been updated. + this.scrollPositions = []; + const categoryLabels = this.getContents() + .filter( + (item) => + item.type === "label" && + item.element.isLabel() && + this.getParentToolbox_().getCategoryByName( + item.element.getButtonText() + ) ) - ); + .map((item) => item.element); + for (const [index, label] of categoryLabels.entries()) { + this.scrollPositions.push({ + name: label.getButtonText(), + position: label.getPosition(), + }); + } } /** - * Gets the checkbox state for a block - * @param {string} blockId The ID of the block in question. - * @return {boolean} Whether the block is checked. - * @public + * Positions the contents of the flyout. + * + * @param {!Blockly.FlyoutItem[]} The flyout items to position. */ - getCheckboxState() { - // Patched by scratch-gui in src/lib/blocks.js. - return false; - } - - getFlyoutScale() { - return 0.675; - } - - getWidth() { - return 250; - } - - blockIsRecyclable_(block) { - const recyclable = super.blockIsRecyclable_(block); - // Exclude blocks with output connections, because they are able to report their current - // value in a popover and recycling them interacts poorly with the VM's maintenance of its - // state. - return recyclable && !block.outputConnection; + layout_(contents) { + // TODO(#211) Remove this once the continuous toolbox has been updated. + // Bypass the continuous flyout's layout method until the plugin is + // updated for the new flyout API. + Blockly.VerticalFlyout.prototype.layout_.call(this, contents); } } diff --git a/src/recyclable_block_flyout_inflater.js b/src/recyclable_block_flyout_inflater.js index 06a3062057..c3add1b3ce 100644 --- a/src/recyclable_block_flyout_inflater.js +++ b/src/recyclable_block_flyout_inflater.js @@ -5,6 +5,7 @@ */ import * as Blockly from "blockly/core"; +import { CheckboxBubble } from "./checkbox_bubble.js"; /** * A block inflater that caches and reuses blocks to improve performance. @@ -22,6 +23,25 @@ export class RecyclableBlockFlyoutInflater extends Blockly.BlockFlyoutInflater { */ recycledBlocks = new Map(); + /** + * Creates a block on the flyout workspace from the given block definition. + * + * @param {!Object} state A JSON representation of a block to load. + * @param {!Blockly.WorkspaceSvg} flyoutWorkspace The flyout's workspace. + * @returns {!Blockly.BlockSvg} The newly created block. + */ + load(state, flyoutWorkspace) { + const block = super.load(state, flyoutWorkspace); + if (block.checkboxInFlyout) { + block.moveBy( + CheckboxBubble.CHECKBOX_SIZE + CheckboxBubble.CHECKBOX_MARGIN, + 0 + ); + } + + return block; + } + /** * Toggles whether or not recycling is enabled. * From c3ee958a5b5b8cf1ae375f82b5dce88a81ee62dd Mon Sep 17 00:00:00 2001 From: Aaron Dodson Date: Mon, 14 Oct 2024 08:18:18 -0700 Subject: [PATCH 097/130] fix: fix bug that caused the number/string input in the custom block editor to have square corners (#213) --- src/fields/field_textinput_removable.js | 37 +++++++++++++------------ 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/src/fields/field_textinput_removable.js b/src/fields/field_textinput_removable.js index a5e9f23c06..4ea60d19d7 100644 --- a/src/fields/field_textinput_removable.js +++ b/src/fields/field_textinput_removable.js @@ -40,26 +40,29 @@ import * as Blockly from "blockly/core"; export class FieldTextInputRemovable extends Blockly.FieldTextInput { /** * Show the inline free-text editor on top of the text with the remove button. - * @private */ showEditor_() { - super.showEditor_(); + // Wait for our parent block to render so we can examine its metrics to + // calculate rounded corners on the editor as needed. + Blockly.renderManagement.finishQueuedRenders().then(() => { + super.showEditor_(); - const div = Blockly.WidgetDiv.getDiv(); - div.className += " removableTextInput"; - const removeButton = document.createElement("img"); - removeButton.className = "blocklyTextRemoveIcon"; - removeButton.setAttribute( - "src", - this.sourceBlock_.workspace.options.pathToMedia + "icons/remove.svg" - ); - this.removeButtonMouseWrapper_ = Blockly.browserEvents.bind( - removeButton, - "mousedown", - this, - this.removeCallback_ - ); - div.appendChild(removeButton); + const div = Blockly.WidgetDiv.getDiv(); + div.className += " removableTextInput"; + const removeButton = document.createElement("img"); + removeButton.className = "blocklyTextRemoveIcon"; + removeButton.setAttribute( + "src", + this.sourceBlock_.workspace.options.pathToMedia + "icons/remove.svg" + ); + this.removeButtonMouseWrapper_ = Blockly.browserEvents.bind( + removeButton, + "mousedown", + this, + this.removeCallback_ + ); + div.appendChild(removeButton); + }); } /** From 3ae22356f5ee9ed5da55b744657a033e43ad1ce0 Mon Sep 17 00:00:00 2001 From: Aaron Dodson Date: Mon, 14 Oct 2024 08:18:35 -0700 Subject: [PATCH 098/130] fix: make FieldNumber a subclass of FieldTextInput (#214) --- src/fields/field_number.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fields/field_number.js b/src/fields/field_number.js index 546543f172..8f829434eb 100644 --- a/src/fields/field_number.js +++ b/src/fields/field_number.js @@ -45,7 +45,7 @@ import { Colours } from "../colours.js"; * @extends {Blockly.FieldTextInput} * @constructor */ -class FieldNumberPicker extends Blockly.FieldNumber { +class FieldNumberPicker extends Blockly.FieldTextInput { /** * Fixed width of the num-pad drop-down, in px. * @type {number} From 0d78559f7aa4e355c3c5d053b67c492f3899e665 Mon Sep 17 00:00:00 2001 From: Aaron Dodson Date: Mon, 14 Oct 2024 08:20:49 -0700 Subject: [PATCH 099/130] chore: delete the old fork of Blockly (#218) --- core/block.js | 1837 ------------------ core/block_animations.js | 107 - core/block_drag_surface.js | 299 --- core/block_dragger.js | 421 ---- core/block_events.js | 531 ----- core/block_render_svg_horizontal.js | 890 --------- core/block_render_svg_vertical.js | 1732 ----------------- core/block_svg.js | 1316 ------------- core/blockly.js | 622 ------ core/blocks.js | 37 - core/bubble.js | 664 ------- core/bubble_dragger.js | 285 --- core/comment.js | 293 --- core/comment_events.js | 539 ----- core/connection.js | 766 -------- core/connection_db.js | 300 --- core/constants.js | 387 ---- core/contextmenu.js | 519 ----- core/dragged_connection_manager.js | 260 --- core/dropdowndiv.js | 408 ---- core/events.js | 429 ---- core/events_abstract.js | 113 -- core/extensions.js | 450 ----- core/field.js | 807 -------- core/field_checkbox.js | 133 -- core/field_colour.js | 253 --- core/field_date.js | 353 ---- core/field_dropdown.js | 483 ----- core/field_iconmenu.js | 309 --- core/field_image.js | 193 -- core/field_label.js | 136 -- core/field_label_serializable.js | 125 -- core/field_numberdropdown.js | 77 - core/field_textdropdown.js | 164 -- core/field_textinput.js | 675 ------- core/flyout_base.js | 923 --------- core/flyout_button.js | 322 --- core/flyout_dragger.js | 83 - core/flyout_extension_category_header.js | 159 -- core/flyout_horizontal.js | 475 ----- core/flyout_vertical.js | 770 -------- core/generator.js | 426 ---- core/gesture.js | 1011 ---------- core/grid.js | 227 --- core/icon.js | 205 -- core/inject.js | 491 ----- core/input.js | 285 --- core/insertion_marker_manager.js | 678 ------- core/msg.js | 62 - core/mutator.js | 426 ---- core/names.js | 198 -- core/options.js | 244 --- core/rendered_connection.js | 417 ---- core/scratch_block_comment.js | 653 ------- core/scratch_bubble.js | 696 ------- core/scratch_events.js | 131 -- core/scratch_msgs.js | 85 - core/scrollbar.js | 875 --------- core/toolbox.js | 801 -------- core/tooltip.js | 337 ---- core/touch.js | 226 --- core/trashcan.js | 343 ---- core/ui_events.js | 91 - core/ui_menu_utils.js | 68 - core/utils.js | 948 --------- core/variable_events.js | 259 --- core/variable_map.js | 415 ---- core/variable_model.js | 116 -- core/warning.js | 199 -- core/widgetdiv.js | 344 ---- core/workspace.js | 673 ------- core/workspace_audio.js | 170 -- core/workspace_comment.js | 432 ----- core/workspace_comment_render_svg.js | 723 ------- core/workspace_comment_svg.js | 611 ------ core/workspace_drag_surface_svg.js | 195 -- core/workspace_dragger.js | 132 -- core/workspace_svg.js | 2267 ---------------------- core/xml.js | 919 --------- core/zoom_controls.js | 301 --- 80 files changed, 37325 deletions(-) delete mode 100644 core/block.js delete mode 100644 core/block_animations.js delete mode 100644 core/block_drag_surface.js delete mode 100644 core/block_dragger.js delete mode 100644 core/block_events.js delete mode 100644 core/block_render_svg_horizontal.js delete mode 100644 core/block_render_svg_vertical.js delete mode 100644 core/block_svg.js delete mode 100644 core/blockly.js delete mode 100644 core/blocks.js delete mode 100644 core/bubble.js delete mode 100644 core/bubble_dragger.js delete mode 100644 core/comment.js delete mode 100644 core/comment_events.js delete mode 100644 core/connection.js delete mode 100644 core/connection_db.js delete mode 100644 core/constants.js delete mode 100644 core/contextmenu.js delete mode 100644 core/dragged_connection_manager.js delete mode 100644 core/dropdowndiv.js delete mode 100644 core/events.js delete mode 100644 core/events_abstract.js delete mode 100644 core/extensions.js delete mode 100644 core/field.js delete mode 100644 core/field_checkbox.js delete mode 100644 core/field_colour.js delete mode 100644 core/field_date.js delete mode 100644 core/field_dropdown.js delete mode 100644 core/field_iconmenu.js delete mode 100644 core/field_image.js delete mode 100644 core/field_label.js delete mode 100644 core/field_label_serializable.js delete mode 100644 core/field_numberdropdown.js delete mode 100644 core/field_textdropdown.js delete mode 100644 core/field_textinput.js delete mode 100644 core/flyout_base.js delete mode 100644 core/flyout_button.js delete mode 100644 core/flyout_dragger.js delete mode 100644 core/flyout_extension_category_header.js delete mode 100644 core/flyout_horizontal.js delete mode 100644 core/flyout_vertical.js delete mode 100644 core/generator.js delete mode 100644 core/gesture.js delete mode 100644 core/grid.js delete mode 100644 core/icon.js delete mode 100644 core/inject.js delete mode 100644 core/input.js delete mode 100644 core/insertion_marker_manager.js delete mode 100644 core/msg.js delete mode 100644 core/mutator.js delete mode 100644 core/names.js delete mode 100644 core/options.js delete mode 100644 core/rendered_connection.js delete mode 100644 core/scratch_block_comment.js delete mode 100644 core/scratch_bubble.js delete mode 100644 core/scratch_events.js delete mode 100644 core/scratch_msgs.js delete mode 100644 core/scrollbar.js delete mode 100644 core/toolbox.js delete mode 100644 core/tooltip.js delete mode 100644 core/touch.js delete mode 100644 core/trashcan.js delete mode 100644 core/ui_events.js delete mode 100644 core/ui_menu_utils.js delete mode 100644 core/utils.js delete mode 100644 core/variable_events.js delete mode 100644 core/variable_map.js delete mode 100644 core/variable_model.js delete mode 100644 core/warning.js delete mode 100644 core/widgetdiv.js delete mode 100644 core/workspace.js delete mode 100644 core/workspace_audio.js delete mode 100644 core/workspace_comment.js delete mode 100644 core/workspace_comment_render_svg.js delete mode 100644 core/workspace_comment_svg.js delete mode 100644 core/workspace_drag_surface_svg.js delete mode 100644 core/workspace_dragger.js delete mode 100644 core/workspace_svg.js delete mode 100644 core/xml.js delete mode 100644 core/zoom_controls.js diff --git a/core/block.js b/core/block.js deleted file mode 100644 index 176cbcc586..0000000000 --- a/core/block.js +++ /dev/null @@ -1,1837 +0,0 @@ -/** - * @license - * Visual Blocks Editor - * - * Copyright 2011 Google Inc. - * https://developers.google.com/blockly/ - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @fileoverview The class representing one block. - * @author fraser@google.com (Neil Fraser) - */ -'use strict'; - -goog.provide('Blockly.Block'); - -goog.require('Blockly.Blocks'); -goog.require('Blockly.Colours'); -goog.require('Blockly.Comment'); -goog.require('Blockly.ScratchBlockComment'); -goog.require('Blockly.Connection'); -goog.require('Blockly.Events.BlockChange'); -goog.require('Blockly.Events.BlockCreate'); -goog.require('Blockly.Events.BlockDelete'); -goog.require('Blockly.Events.BlockMove'); -goog.require('Blockly.Extensions'); -goog.require('Blockly.FieldLabelSerializable'); -goog.require('Blockly.FieldVariableGetter'); -goog.require('Blockly.Input'); -goog.require('Blockly.Mutator'); -goog.require('Blockly.Warning'); -goog.require('Blockly.Workspace'); -goog.require('Blockly.Xml'); -goog.require('goog.array'); -goog.require('goog.asserts'); -goog.require('goog.math.Coordinate'); -goog.require('goog.string'); - - -/** - * Class for one block. - * Not normally called directly, workspace.newBlock() is preferred. - * @param {!Blockly.Workspace} workspace The block's workspace. - * @param {?string} prototypeName Name of the language object containing - * type-specific functions for this block. - * @param {string=} opt_id Optional ID. Use this ID if provided, otherwise - * create a new ID. If the ID conflicts with an in-use ID, a new one will - * be generated. - * @constructor - */ -Blockly.Block = function(workspace, prototypeName, opt_id) { - var flyoutWorkspace = workspace && workspace.getFlyout && workspace.getFlyout() ? - workspace.getFlyout().getWorkspace() : null; - /** @type {string} */ - this.id = (opt_id && !workspace.getBlockById(opt_id) && - (!flyoutWorkspace || !flyoutWorkspace.getBlockById(opt_id))) ? - opt_id : Blockly.utils.genUid(); - workspace.blockDB_[this.id] = this; - /** @type {Blockly.Connection} */ - this.outputConnection = null; - /** @type {Blockly.Connection} */ - this.nextConnection = null; - /** @type {Blockly.Connection} */ - this.previousConnection = null; - /** @type {!Array.} */ - this.inputList = []; - /** @type {boolean|undefined} */ - this.inputsInline = true; - /** @type {boolean} */ - this.disabled = false; - /** @type {string|!Function} */ - this.tooltip = ''; - /** @type {boolean} */ - this.contextMenu = true; - - /** - * @type {Blockly.Block} - * @protected - */ - this.parentBlock_ = null; - - /** - * @type {!Array.} - * @protected - */ - this.childBlocks_ = []; - - /** - * @type {boolean} - * @private - */ - this.deletable_ = true; - - /** - * @type {boolean} - * @private - */ - this.movable_ = true; - - /** - * @type {boolean} - * @private - */ - this.editable_ = true; - - /** - * @type {boolean} - * @private - */ - this.isShadow_ = false; - - /** - * @type {boolean} - * @protected - */ - this.collapsed_ = false; - - /** - * @type {boolean} - * @private - */ - this.checkboxInFlyout_ = false; - - /** @type {string|Blockly.Comment} */ - this.comment = null; - - /** - * @type {?number} - * @private - */ - this.outputShape_ = null; - - /** - * @type {?string} - * @private - */ - this.category_ = null; - - /** - * The block's position in workspace units. (0, 0) is at the workspace's - * origin; scale does not change this value. - * @type {!goog.math.Coordinate} - * @private - */ - this.xy_ = new goog.math.Coordinate(0, 0); - - /** @type {!Blockly.Workspace} */ - this.workspace = workspace; - /** @type {boolean} */ - this.isInFlyout = workspace.isFlyout; - /** @type {boolean} */ - this.isInMutator = workspace.isMutator; - - /** @type {boolean} */ - this.RTL = workspace.RTL; - - /** @type {boolean} */ - this.isInsertionMarker_ = false; - - // Copy the type-specific functions and data from the prototype. - if (prototypeName) { - /** @type {string} */ - this.type = prototypeName; - var prototype = Blockly.Blocks[prototypeName]; - goog.asserts.assertObject(prototype, - 'Error: Unknown block type "%s".', prototypeName); - goog.mixin(this, prototype); - } - - workspace.addTopBlock(this); - - // Call an initialization function, if it exists. - if (goog.isFunction(this.init)) { - this.init(); - } - // Record initial inline state. - /** @type {boolean|undefined} */ - this.inputsInlineDefault = this.inputsInline; - - // Fire a create event. - if (Blockly.Events.isEnabled()) { - var existingGroup = Blockly.Events.getGroup(); - if (!existingGroup) { - Blockly.Events.setGroup(true); - } - try { - Blockly.Events.fire(new Blockly.Events.BlockCreate(this)); - } finally { - if (!existingGroup) { - Blockly.Events.setGroup(false); - } - } - - } - // Bind an onchange function, if it exists. - if (goog.isFunction(this.onchange)) { - this.setOnChange(this.onchange); - } -}; - -/** - * Optional text data that round-trips beween blocks and XML. - * Has no effect. May be used by 3rd parties for meta information. - * @type {?string} - */ -Blockly.Block.prototype.data = null; - -/** - * Colour of the block in '#RRGGBB' format. - * @type {string} - * @private - */ -Blockly.Block.prototype.colour_ = '#FF0000'; - -/** - * Secondary colour of the block in '#RRGGBB' format. - * @type {string} - * @private - */ -Blockly.Block.prototype.colourSecondary_ = '#FF0000'; - -/** - * Tertiary colour of the block in '#RRGGBB' format. - * @type {string} - * @private - */ -Blockly.Block.prototype.colourTertiary_ = '#FF0000'; - -/** - * Quaternary colour of the block in '#RRGGBB' format. - * @type {string} - * @private - */ -Blockly.Block.prototype.colourQuaternary = '#FF0000'; - -/** - * Fill colour used to override default shadow colour behaviour. - * @type {string} - * @private - */ -Blockly.Block.prototype.shadowColour_ = null; - -/** - * Dispose of this block. - * @param {boolean} healStack If true, then try to heal any gap by connecting - * the next statement with the previous statement. Otherwise, dispose of - * all children of this block. - */ -Blockly.Block.prototype.dispose = function(healStack) { - if (!this.workspace) { - // Already deleted. - return; - } - // Terminate onchange event calls. - if (this.onchangeWrapper_) { - this.workspace.removeChangeListener(this.onchangeWrapper_); - } - this.unplug(healStack); - if (Blockly.Events.isEnabled()) { - Blockly.Events.fire(new Blockly.Events.BlockDelete(this)); - } - Blockly.Events.disable(); - - try { - // This block is now at the top of the workspace. - // Remove this block from the workspace's list of top-most blocks. - if (this.workspace) { - this.workspace.removeTopBlock(this); - // Remove from block database. - delete this.workspace.blockDB_[this.id]; - this.workspace = null; - } - - // Just deleting this block from the DOM would result in a memory leak as - // well as corruption of the connection database. Therefore we must - // methodically step through the blocks and carefully disassemble them. - - if (Blockly.selected == this) { - Blockly.selected = null; - } - - // First, dispose of all my children. - for (var i = this.childBlocks_.length - 1; i >= 0; i--) { - this.childBlocks_[i].dispose(false); - } - // Then dispose of myself. - // Dispose of all inputs and their fields. - for (var i = 0, input; input = this.inputList[i]; i++) { - input.dispose(); - } - this.inputList.length = 0; - // Dispose of any remaining connections (next/previous/output). - var connections = this.getConnections_(true); - for (var i = 0; i < connections.length; i++) { - var connection = connections[i]; - if (connection.isConnected()) { - connection.disconnect(); - } - connections[i].dispose(); - } - } finally { - Blockly.Events.enable(); - } -}; - -/** - * Call initModel on all fields on the block. - * May be called more than once. - * Either initModel or initSvg must be called after creating a block and before - * the first interaction with it. Interactions include UI actions - * (e.g. clicking and dragging) and firing events (e.g. create, delete, and - * change). - * @public - */ -Blockly.Block.prototype.initModel = function() { - for (var i = 0, input; input = this.inputList[i]; i++) { - for (var j = 0, field; field = input.fieldRow[j]; j++) { - if (field.initModel) { - field.initModel(); - } - } - } -}; - -/** - * Unplug this block from its superior block. If this block is a statement, - * optionally reconnect the block underneath with the block on top. - * @param {boolean=} opt_healStack Disconnect child statement and reconnect - * stack. Defaults to false. - */ -Blockly.Block.prototype.unplug = function(opt_healStack) { - if (this.outputConnection) { - if (this.outputConnection.isConnected()) { - // Disconnect from any superior block. - this.outputConnection.disconnect(); - } - } else { - if (this.previousConnection) { - var previousTarget = null; - if (this.previousConnection.isConnected()) { - // Remember the connection that any next statements need to connect to. - previousTarget = this.previousConnection.targetConnection; - // Detach this block from the parent's tree. - this.previousConnection.disconnect(); - } - } - var nextBlock = this.getNextBlock(); - if (opt_healStack && nextBlock) { - // Disconnect the next statement. - var nextTarget = this.nextConnection.targetConnection; - nextTarget.disconnect(); - if (previousTarget && previousTarget.checkType_(nextTarget)) { - // Attach the next statement to the previous statement. - previousTarget.connect(nextTarget); - } - } - } -}; - -/** - * Returns all connections originating from this block. - * @return {!Array.} Array of connections. - * @private - */ -Blockly.Block.prototype.getConnections_ = function() { - var myConnections = []; - if (this.outputConnection) { - myConnections.push(this.outputConnection); - } - if (this.previousConnection) { - myConnections.push(this.previousConnection); - } - if (this.nextConnection) { - myConnections.push(this.nextConnection); - } - for (var i = 0, input; input = this.inputList[i]; i++) { - if (input.connection) { - myConnections.push(input.connection); - } - } - return myConnections; -}; - -/** - * Walks down a stack of blocks and finds the last next connection on the stack. - * @return {Blockly.Connection} The last next connection on the stack, or null. - * @package - */ -Blockly.Block.prototype.lastConnectionInStack = function() { - var nextConnection = this.nextConnection; - while (nextConnection) { - var nextBlock = nextConnection.targetBlock(); - if (!nextBlock) { - // Found a next connection with nothing on the other side. - return nextConnection; - } - nextConnection = nextBlock.nextConnection; - } - // Ran out of next connections. - return null; -}; - -/** - * Bump unconnected blocks out of alignment. Two blocks which aren't actually - * connected should not coincidentally line up on screen. - * @protected - */ -Blockly.Block.prototype.bumpNeighbours_ = function() { - console.warn('Not expected to reach this bumpNeighbours_ function. The ' + - 'BlockSvg function for bumpNeighbours_ was expected to be called instead.'); -}; - -/** - * Return the parent block or null if this block is at the top level. - * @return {Blockly.Block} The block that holds the current block. - */ -Blockly.Block.prototype.getParent = function() { - // Look at the DOM to see if we are nested in another block. - return this.parentBlock_; -}; - -/** - * Return the input that connects to the specified block. - * @param {!Blockly.Block} block A block connected to an input on this block. - * @return {Blockly.Input} The input that connects to the specified block. - */ -Blockly.Block.prototype.getInputWithBlock = function(block) { - for (var i = 0, input; input = this.inputList[i]; i++) { - if (input.connection && input.connection.targetBlock() == block) { - return input; - } - } - return null; -}; - -/** - * Return the input that contains the specified connection - * @param {!Blockly.Connection} conn A connection on this block. - * @return {Blockly.Input} The input that contains the specified connection. - */ -Blockly.Block.prototype.getInputWithConnection = function(conn) { - for (var i = 0, input; input = this.inputList[i]; i++) { - if (input.connection == conn) { - return input; - } - } - return null; -}; - -/** - * Return the parent block that surrounds the current block, or null if this - * block has no surrounding block. A parent block might just be the previous - * statement, whereas the surrounding block is an if statement, while loop, etc. - * @return {Blockly.Block} The block that surrounds the current block. - */ -Blockly.Block.prototype.getSurroundParent = function() { - var block = this; - do { - var prevBlock = block; - block = block.getParent(); - if (!block) { - // Ran off the top. - return null; - } - } while (block.getNextBlock() == prevBlock); - // This block is an enclosing parent, not just a statement in a stack. - return block; -}; - -/** - * Return the next statement block directly connected to this block. - * @return {Blockly.Block} The next statement block or null. - */ -Blockly.Block.prototype.getNextBlock = function() { - return this.nextConnection && this.nextConnection.targetBlock(); -}; - -/** - * Return the previous statement block directly connected to this block. - * @return {Blockly.Block} The previous statement block or null. - */ -Blockly.Block.prototype.getPreviousBlock = function() { - return this.previousConnection && this.previousConnection.targetBlock(); -}; - -/** - * Return the connection on the first statement input on this block, or null if - * there are none. - * @return {Blockly.Connection} The first statement connection or null. - */ -Blockly.Block.prototype.getFirstStatementConnection = function() { - for (var i = 0, input; input = this.inputList[i]; i++) { - if (input.connection && input.connection.type == Blockly.NEXT_STATEMENT) { - return input.connection; - } - } - return null; -}; - -/** - * Return the top-most block in this block's tree. - * This will return itself if this block is at the top level. - * @return {!Blockly.Block} The root block. - */ -Blockly.Block.prototype.getRootBlock = function() { - var rootBlock; - var block = this; - do { - rootBlock = block; - block = rootBlock.parentBlock_; - } while (block); - return rootBlock; -}; - -/** - * Find all the blocks that are directly nested inside this one. - * Includes value and statement inputs, as well as any following statement. - * Excludes any connection on an output tab or any preceding statement. - * Blocks are optionally sorted by position; top to bottom. - * @param {boolean} ordered Sort the list if true. - * @return {!Array.} Array of blocks. - */ -Blockly.Block.prototype.getChildren = function(ordered) { - if (!ordered) { - return this.childBlocks_; - } - var blocks = []; - for (var i = 0, input; input = this.inputList[i]; i++) { - if (input.connection) { - var child = input.connection.targetBlock(); - if (child) { - blocks.push(child); - } - } - } - var next = this.getNextBlock(); - if (next) { - blocks.push(next); - } - return blocks; -}; - -/** - * Set parent of this block to be a new block or null. - * @param {Blockly.Block} newParent New parent block. - */ -Blockly.Block.prototype.setParent = function(newParent) { - if (newParent == this.parentBlock_) { - return; - } - if (this.parentBlock_) { - // Remove this block from the old parent's child list. - goog.array.remove(this.parentBlock_.childBlocks_, this); - - // Disconnect from superior blocks. - if (this.previousConnection && this.previousConnection.isConnected()) { - throw 'Still connected to previous block.'; - } - if (this.outputConnection && this.outputConnection.isConnected()) { - throw 'Still connected to parent block.'; - } - this.parentBlock_ = null; - // This block hasn't actually moved on-screen, so there's no need to update - // its connection locations. - } else { - // Remove this block from the workspace's list of top-most blocks. - this.workspace.removeTopBlock(this); - } - - this.parentBlock_ = newParent; - if (newParent) { - // Add this block to the new parent's child list. - newParent.childBlocks_.push(this); - } else { - this.workspace.addTopBlock(this); - } -}; - -/** - * Find all the blocks that are directly or indirectly nested inside this one. - * Includes this block in the list. - * Includes value and statement inputs, as well as any following statements. - * Excludes any connection on an output tab or any preceding statements. - * Blocks are optionally sorted by position, top to bottom. - * @param {boolean} ordered Sort the list if true. - * @param {boolean=} opt_ignoreShadows If set, don't include shadow blocks. - * @return {!Array.} Flattened array of blocks. - */ -Blockly.Block.prototype.getDescendants = function(ordered, opt_ignoreShadows) { - var blocks = [this]; - var childBlocks = this.getChildren(ordered); - for (var child, i = 0; child = childBlocks[i]; i++) { - if (!opt_ignoreShadows || !child.isShadow_) { - blocks.push.apply( - blocks, child.getDescendants(ordered, opt_ignoreShadows)); - } - } - return blocks; -}; - -/** - * Get whether this block is deletable or not. - * @return {boolean} True if deletable. - */ -Blockly.Block.prototype.isDeletable = function() { - return this.deletable_ && !this.isShadow_ && - !(this.workspace && this.workspace.options.readOnly); -}; - -/** - * Set whether this block is deletable or not. - * @param {boolean} deletable True if deletable. - */ -Blockly.Block.prototype.setDeletable = function(deletable) { - this.deletable_ = deletable; -}; - -/** - * Get whether this block is movable or not. - * @return {boolean} True if movable. - */ -Blockly.Block.prototype.isMovable = function() { - return this.movable_ && !this.isShadow_ && - !(this.workspace && this.workspace.options.readOnly); -}; - -/** - * Set whether this block is movable or not. - * @param {boolean} movable True if movable. - */ -Blockly.Block.prototype.setMovable = function(movable) { - this.movable_ = movable; -}; - -/** - * Get whether this block is a shadow block or not. - * @return {boolean} True if a shadow. - */ -Blockly.Block.prototype.isShadow = function() { - return this.isShadow_; -}; - -/** - * Set whether this block is a shadow block or not. - * @param {boolean} shadow True if a shadow. - */ -Blockly.Block.prototype.setShadow = function(shadow) { - this.isShadow_ = shadow; -}; - -/** - * Get whether this block is an insertion marker block or not. - * @return {boolean} True if an insertion marker. - */ -Blockly.Block.prototype.isInsertionMarker = function() { - return this.isInsertionMarker_; -}; - -/** - * Set whether this block is an insertion marker block or not. - * @param {boolean} insertionMarker True if an insertion marker. - */ -Blockly.Block.prototype.setInsertionMarker = function(insertionMarker) { - if (this.isInsertionMarker_ == insertionMarker) { - return; // No change. - } - this.isInsertionMarker_ = insertionMarker; - // TODO: handle removing insertion marker status. - if (this.isInsertionMarker_) { - this.setColour(Blockly.Colours.insertionMarker); - this.setOpacity(Blockly.Colours.insertionMarkerOpacity); - Blockly.utils.addClass(/** @type {!Element} */ (this.svgGroup_), - 'blocklyInsertionMarker'); - } -}; - -/** - * Get whether this block is editable or not. - * @return {boolean} True if editable. - */ -Blockly.Block.prototype.isEditable = function() { - return this.editable_ && !(this.workspace && this.workspace.options.readOnly); -}; - -/** - * Set whether this block is editable or not. - * @param {boolean} editable True if editable. - */ -Blockly.Block.prototype.setEditable = function(editable) { - this.editable_ = editable; - for (var i = 0, input; input = this.inputList[i]; i++) { - for (var j = 0, field; field = input.fieldRow[j]; j++) { - field.updateEditable(); - } - } -}; - -/** - * Set whether the connections are hidden (not tracked in a database) or not. - * Recursively walk down all child blocks (except collapsed blocks). - * @param {boolean} hidden True if connections are hidden. - */ -Blockly.Block.prototype.setConnectionsHidden = function(hidden) { - if (!hidden && this.isCollapsed()) { - if (this.outputConnection) { - this.outputConnection.setHidden(hidden); - } - if (this.previousConnection) { - this.previousConnection.setHidden(hidden); - } - if (this.nextConnection) { - this.nextConnection.setHidden(hidden); - var child = this.nextConnection.targetBlock(); - if (child) { - child.setConnectionsHidden(hidden); - } - } - } else { - var myConnections = this.getConnections_(true); - for (var i = 0, connection; connection = myConnections[i]; i++) { - connection.setHidden(hidden); - if (connection.isSuperior()) { - var child = connection.targetBlock(); - if (child) { - child.setConnectionsHidden(hidden); - } - } - } - } -}; - -/** - * Find the connection on this block that corresponds to the given connection - * on the other block. - * Used to match connections between a block and its insertion marker. - * @param {!Blockly.Block} otherBlock The other block to match against. - * @param {!Blockly.Connection} conn The other connection to match. - * @return {Blockly.Connection} the matching connection on this block, or null. - */ -Blockly.Block.prototype.getMatchingConnection = function(otherBlock, conn) { - var connections = this.getConnections_(true); - var otherConnections = otherBlock.getConnections_(true); - if (connections.length != otherConnections.length) { - throw "Connection lists did not match in length."; - } - for (var i = 0; i < otherConnections.length; i++) { - if (otherConnections[i] == conn) { - return connections[i]; - } - } - return null; -}; - -/** - * Set the URL of this block's help page. - * @param {string|Function} url URL string for block help, or function that - * returns a URL. Null for no help. - */ -Blockly.Block.prototype.setHelpUrl = function(url) { - this.helpUrl = url; -}; - -/** - * Change the tooltip text for a block. - * @param {string|!Function} newTip Text for tooltip or a parent element to - * link to for its tooltip. May be a function that returns a string. - */ -Blockly.Block.prototype.setTooltip = function(newTip) { - this.tooltip = newTip; -}; - -/** - * Get the colour of a block. - * @return {string} #RRGGBB string. - */ -Blockly.Block.prototype.getColour = function() { - return this.colour_; -}; - -/** - * Get the secondary colour of a block. - * @return {string} #RRGGBB string. - */ -Blockly.Block.prototype.getColourSecondary = function() { - return this.colourSecondary_; -}; - -/** - * Get the tertiary colour of a block. - * @return {string} #RRGGBB string. - */ -Blockly.Block.prototype.getColourTertiary = function() { - return this.colourTertiary_; -}; - -/** - * Get the quaternary colour of a block. - * @return {string} #RRGGBB string. - */ -Blockly.Block.prototype.getColourQuaternary = function() { - return this.colourQuaternary_; -}; - -/** - * Get the shadow colour of a block. - * @return {string} #RRGGBB string. - */ -Blockly.Block.prototype.getShadowColour = function() { - return this.shadowColour_; -}; - -/** - * Set the shadow colour of a block. - * @param {number|string} colour HSV hue value, or #RRGGBB string. - */ -Blockly.Block.prototype.setShadowColour = function(colour) { - this.shadowColour_ = this.makeColour_(colour); - if (this.rendered) { - this.updateColour(); - } -}; - -/** - * Clear the shadow colour of a block. - */ -Blockly.Block.prototype.clearShadowColour = function() { - this.shadowColour_ = null; - if (this.rendered) { - this.updateColour(); - } -}; - -/** -* Create an #RRGGBB string colour from a colour HSV hue value or #RRGGBB string. -* @param {number|string} colour HSV hue value, or #RRGGBB string. -* @return {string} #RRGGBB string. -* @private -*/ -Blockly.Block.prototype.makeColour_ = function(colour) { - var hue = Number(colour); - if (!isNaN(hue)) { - return Blockly.hueToRgb(hue); - } else if (goog.isString(colour) && colour.match(/^#[0-9a-fA-F]{6}$/)) { - return colour; - } else { - throw 'Invalid colour: ' + colour; - } -}; - -/** - * Change the colour of a block, and optional secondary/teriarty colours. - * @param {number|string} colour HSV hue value, or #RRGGBB string. - * @param {number|string} colourSecondary HSV hue value, or #RRGGBB string. - * @param {number|string} colourTertiary HSV hue value, or #RRGGBB string. - * @param {number|string} colourQuaternary HSV hue value, or #RRGGBB string. - */ -Blockly.Block.prototype.setColour = function(colour, colourSecondary, colourTertiary, - colourQuaternary) { - this.colour_ = this.makeColour_(colour); - if (colourSecondary !== undefined) { - this.colourSecondary_ = this.makeColour_(colourSecondary); - } else { - this.colourSecondary_ = goog.color.rgbArrayToHex( - goog.color.darken(goog.color.hexToRgb(this.colour_), 0.1)); - } - if (colourTertiary !== undefined) { - this.colourTertiary_ = this.makeColour_(colourTertiary); - } else { - this.colourTertiary_ = goog.color.rgbArrayToHex( - goog.color.darken(goog.color.hexToRgb(this.colour_), 0.2)); - } - if (colourQuaternary !== undefined) { - this.colourQuaternary_ = this.makeColour_(colourQuaternary); - } else { - this.colourQuaternary_ = this.colourTertiary_; - } - if (this.rendered) { - this.updateColour(); - } -}; - -/** - * Sets a callback function to use whenever the block's parent workspace - * changes, replacing any prior onchange handler. This is usually only called - * from the constructor, the block type initializer function, or an extension - * initializer function. - * @param {function(Blockly.Events.Abstract)} onchangeFn The callback to call - * when the block's workspace changes. - * @throws {Error} if onchangeFn is not falsey or a function. - */ -Blockly.Block.prototype.setOnChange = function(onchangeFn) { - if (onchangeFn && !goog.isFunction(onchangeFn)) { - throw new Error("onchange must be a function."); - } - if (this.onchangeWrapper_) { - this.workspace.removeChangeListener(this.onchangeWrapper_); - } - this.onchange = onchangeFn; - if (this.onchange) { - this.onchangeWrapper_ = onchangeFn.bind(this); - this.workspace.addChangeListener(this.onchangeWrapper_); - } -}; - -/** - * Returns the named field from a block. - * @param {string} name The name of the field. - * @return {Blockly.Field} Named field, or null if field does not exist. - */ -Blockly.Block.prototype.getField = function(name) { - for (var i = 0, input; input = this.inputList[i]; i++) { - for (var j = 0, field; field = input.fieldRow[j]; j++) { - if (field.name === name) { - return field; - } - } - } - return null; -}; - -/** - * Return all variables referenced by this block. - * @return {!Array.} List of variable names. - * @package - */ -Blockly.Block.prototype.getVars = function() { - var vars = []; - for (var i = 0, input; input = this.inputList[i]; i++) { - for (var j = 0, field; field = input.fieldRow[j]; j++) { - if (field.referencesVariables()) { - vars.push(field.getValue()); - } - } - } - return vars; -}; - -/** - * Return all variables referenced by this block. - * @return {!Array.} List of variable models. - * @package - */ -Blockly.Block.prototype.getVarModels = function() { - var vars = []; - for (var i = 0, input; input = this.inputList[i]; i++) { - for (var j = 0, field; field = input.fieldRow[j]; j++) { - if (field.referencesVariables()) { - var model = this.workspace.getVariableById(field.getValue()); - // Check if the variable actually exists (and isn't just a potential - // variable). - if (model) { - vars.push(model); - } - } - } - } - return vars; -}; - -/** - * Notification that a variable is renaming but keeping the same ID. If the - * variable is in use on this block, rerender to show the new name. - * @param {!Blockly.VariableModel} variable The variable being renamed. - * @package - */ -Blockly.Block.prototype.updateVarName = function(variable) { - for (var i = 0, input; input = this.inputList[i]; i++) { - for (var j = 0, field; field = input.fieldRow[j]; j++) { - if (field.referencesVariables() && - variable.getId() == field.getValue()) { - field.setText(variable.name); - } - } - } -}; - -/** - * Notification that a variable is renaming. - * If the ID matches one of this block's variables, rename it. - * @param {string} oldId ID of variable to rename. - * @param {string} newId ID of new variable. May be the same as oldId, but with - * an updated name. - */ -Blockly.Block.prototype.renameVarById = function(oldId, newId) { - for (var i = 0, input; input = this.inputList[i]; i++) { - for (var j = 0, field; field = input.fieldRow[j]; j++) { - if (field.referencesVariables() && - oldId == field.getValue()) { - field.setValue(newId); - } - } - } -}; - -/** - * Returns the language-neutral value from the field of a block. - * @param {string} name The name of the field. - * @return {?string} Value from the field or null if field does not exist. - */ -Blockly.Block.prototype.getFieldValue = function(name) { - var field = this.getField(name); - if (field) { - return field.getValue(); - } - return null; -}; - -/** - * Change the field value for a block (e.g. 'CHOOSE' or 'REMOVE'). - * @param {string} newValue Value to be the new field. - * @param {string} name The name of the field. - */ -Blockly.Block.prototype.setFieldValue = function(newValue, name) { - var field = this.getField(name); - goog.asserts.assertObject(field, 'Field "%s" not found.', name); - field.setValue(newValue); -}; - -/** - * Set whether this block can chain onto the bottom of another block. - * @param {boolean} newBoolean True if there can be a previous statement. - * @param {(string|Array.|null)=} opt_check Statement type or - * list of statement types. Null/undefined if any type could be connected. - */ -Blockly.Block.prototype.setPreviousStatement = function(newBoolean, opt_check) { - if (newBoolean) { - if (opt_check === undefined) { - opt_check = null; - } - if (!this.previousConnection) { - goog.asserts.assert(!this.outputConnection, - 'Remove output connection prior to adding previous connection.'); - this.previousConnection = - this.makeConnection_(Blockly.PREVIOUS_STATEMENT); - } - this.previousConnection.setCheck(opt_check); - } else { - if (this.previousConnection) { - goog.asserts.assert(!this.previousConnection.isConnected(), - 'Must disconnect previous statement before removing connection.'); - this.previousConnection.dispose(); - this.previousConnection = null; - } - } -}; - -/** - * Set whether another block can chain onto the bottom of this block. - * @param {boolean} newBoolean True if there can be a next statement. - * @param {(string|Array.|null)=} opt_check Statement type or - * list of statement types. Null/undefined if any type could be connected. - */ -Blockly.Block.prototype.setNextStatement = function(newBoolean, opt_check) { - if (newBoolean) { - if (opt_check === undefined) { - opt_check = null; - } - if (!this.nextConnection) { - this.nextConnection = this.makeConnection_(Blockly.NEXT_STATEMENT); - } - this.nextConnection.setCheck(opt_check); - } else { - if (this.nextConnection) { - goog.asserts.assert(!this.nextConnection.isConnected(), - 'Must disconnect next statement before removing connection.'); - this.nextConnection.dispose(); - this.nextConnection = null; - } - } -}; - -/** - * Set whether this block returns a value. - * @param {boolean} newBoolean True if there is an output. - * @param {(string|Array.|null)=} opt_check Returned type or list - * of returned types. Null or undefined if any type could be returned - * (e.g. variable get). - */ -Blockly.Block.prototype.setOutput = function(newBoolean, opt_check) { - if (newBoolean) { - if (opt_check === undefined) { - opt_check = null; - } - if (!this.outputConnection) { - goog.asserts.assert(!this.previousConnection, - 'Remove previous connection prior to adding output connection.'); - this.outputConnection = this.makeConnection_(Blockly.OUTPUT_VALUE); - } - this.outputConnection.setCheck(opt_check); - } else { - if (this.outputConnection) { - goog.asserts.assert(!this.outputConnection.isConnected(), - 'Must disconnect output value before removing connection.'); - this.outputConnection.dispose(); - this.outputConnection = null; - } - } -}; - -/** - * Set whether value inputs are arranged horizontally or vertically. - * @param {boolean} newBoolean True if inputs are horizontal. - */ -Blockly.Block.prototype.setInputsInline = function(newBoolean) { - if (this.inputsInline != newBoolean) { - Blockly.Events.fire(new Blockly.Events.BlockChange( - this, 'inline', null, this.inputsInline, newBoolean)); - this.inputsInline = newBoolean; - } -}; - -/** - * Get whether value inputs are arranged horizontally or vertically. - * @return {boolean} True if inputs are horizontal. - */ -Blockly.Block.prototype.getInputsInline = function() { - if (this.inputsInline != undefined) { - // Set explicitly. - return this.inputsInline; - } - // Not defined explicitly. Figure out what would look best. - for (var i = 1; i < this.inputList.length; i++) { - if (this.inputList[i - 1].type == Blockly.DUMMY_INPUT && - this.inputList[i].type == Blockly.DUMMY_INPUT) { - // Two dummy inputs in a row. Don't inline them. - return false; - } - } - for (var i = 1; i < this.inputList.length; i++) { - if (this.inputList[i - 1].type == Blockly.INPUT_VALUE && - this.inputList[i].type == Blockly.DUMMY_INPUT) { - // Dummy input after a value input. Inline them. - return true; - } - } - return false; -}; - -/** - * Set whether the block is disabled or not. - * @param {boolean} disabled True if disabled. - */ -Blockly.Block.prototype.setDisabled = function(disabled) { - if (this.disabled != disabled) { - Blockly.Events.fire(new Blockly.Events.BlockChange( - this, 'disabled', null, this.disabled, disabled)); - this.disabled = disabled; - } -}; - -/** - * Get whether the block is disabled or not due to parents. - * The block's own disabled property is not considered. - * @return {boolean} True if disabled. - */ -Blockly.Block.prototype.getInheritedDisabled = function() { - var ancestor = this.getSurroundParent(); - while (ancestor) { - if (ancestor.disabled) { - return true; - } - ancestor = ancestor.getSurroundParent(); - } - // Ran off the top. - return false; -}; - -/** - * Get whether the block is collapsed or not. - * @return {boolean} True if collapsed. - */ -Blockly.Block.prototype.isCollapsed = function() { - return this.collapsed_; -}; - -/** - * Set whether the block is collapsed or not. - * @param {boolean} collapsed True if collapsed. - */ -Blockly.Block.prototype.setCollapsed = function(collapsed) { - if (this.collapsed_ != collapsed) { - Blockly.Events.fire(new Blockly.Events.BlockChange( - this, 'collapsed', null, this.collapsed_, collapsed)); - this.collapsed_ = collapsed; - } -}; - -/** - * Create a human-readable text representation of this block and any children. - * @param {number=} opt_maxLength Truncate the string to this length. - * @param {string=} opt_emptyToken The placeholder string used to denote an - * empty field. If not specified, '?' is used. - * @return {string} Text of block. - */ -Blockly.Block.prototype.toString = function(opt_maxLength, opt_emptyToken) { - var text = []; - var emptyFieldPlaceholder = opt_emptyToken || '?'; - if (this.collapsed_) { - text.push(this.getInput('_TEMP_COLLAPSED_INPUT').fieldRow[0].text_); - } else { - for (var i = 0, input; input = this.inputList[i]; i++) { - for (var j = 0, field; field = input.fieldRow[j]; j++) { - if (field instanceof Blockly.FieldDropdown && !field.getValue()) { - text.push(emptyFieldPlaceholder); - } else { - text.push(field.getText()); - } - } - if (input.connection) { - var child = input.connection.targetBlock(); - if (child) { - text.push(child.toString(undefined, opt_emptyToken)); - } else { - text.push(emptyFieldPlaceholder); - } - } - } - } - text = goog.string.trim(text.join(' ')) || '???'; - if (opt_maxLength) { - // TODO: Improve truncation so that text from this block is given priority. - // E.g. "1+2+3+4+5+6+7+8+9=0" should be "...6+7+8+9=0", not "1+2+3+4+5...". - // E.g. "1+2+3+4+5=6+7+8+9+0" should be "...4+5=6+7...". - text = goog.string.truncate(text, opt_maxLength); - } - return text; -}; - -/** - * Shortcut for appending a value input row. - * @param {string} name Language-neutral identifier which may used to find this - * input again. Should be unique to this block. - * @return {!Blockly.Input} The input object created. - */ -Blockly.Block.prototype.appendValueInput = function(name) { - return this.appendInput_(Blockly.INPUT_VALUE, name); -}; - -/** - * Shortcut for appending a statement input row. - * @param {string} name Language-neutral identifier which may used to find this - * input again. Should be unique to this block. - * @return {!Blockly.Input} The input object created. - */ -Blockly.Block.prototype.appendStatementInput = function(name) { - return this.appendInput_(Blockly.NEXT_STATEMENT, name); -}; - -/** - * Shortcut for appending a dummy input row. - * @param {string=} opt_name Language-neutral identifier which may used to find - * this input again. Should be unique to this block. - * @return {!Blockly.Input} The input object created. - */ -Blockly.Block.prototype.appendDummyInput = function(opt_name) { - return this.appendInput_(Blockly.DUMMY_INPUT, opt_name || ''); -}; - -/** - * Initialize this block using a cross-platform, internationalization-friendly - * JSON description. - * @param {!Object} json Structured data describing the block. - */ -Blockly.Block.prototype.jsonInit = function(json) { - var warningPrefix = json['type'] ? 'Block "' + json['type'] + '": ' : ''; - - // Validate inputs. - goog.asserts.assert( - json['output'] == undefined || json['previousStatement'] == undefined, - warningPrefix + 'Must not have both an output and a previousStatement.'); - - // Set basic properties of block. - if (json['colour'] !== undefined) { - this.setColourFromJson_(json); - } - - // Interpolate the message blocks. - var i = 0; - while (json['message' + i] !== undefined) { - this.interpolate_(json['message' + i], json['args' + i] || [], - json['lastDummyAlign' + i]); - i++; - } - - if (json['inputsInline'] !== undefined) { - this.setInputsInline(json['inputsInline']); - } - // Set output and previous/next connections. - if (json['output'] !== undefined) { - this.setOutput(true, json['output']); - } - if (json['previousStatement'] !== undefined) { - this.setPreviousStatement(true, json['previousStatement']); - } - if (json['nextStatement'] !== undefined) { - this.setNextStatement(true, json['nextStatement']); - } - if (json['tooltip'] !== undefined) { - var rawValue = json['tooltip']; - var localizedText = Blockly.utils.replaceMessageReferences(rawValue); - this.setTooltip(localizedText); - } - if (json['enableContextMenu'] !== undefined) { - var rawValue = json['enableContextMenu']; - this.contextMenu = !!rawValue; - } - if (json['helpUrl'] !== undefined) { - var rawValue = json['helpUrl']; - var localizedValue = Blockly.utils.replaceMessageReferences(rawValue); - this.setHelpUrl(localizedValue); - } - if (goog.isString(json['extensions'])) { - console.warn('JSON attribute \'extensions\' should be an array of ' + - 'strings. Found raw string in JSON for \'' + json['type'] + '\' block.'); - json['extensions'] = [json['extensions']]; // Correct and continue. - } - - // Add the mutator to the block - if (json['mutator'] !== undefined) { - Blockly.Extensions.apply(json['mutator'], this, true); - } - - if (Array.isArray(json['extensions'])) { - var extensionNames = json['extensions']; - for (var i = 0; i < extensionNames.length; ++i) { - var extensionName = extensionNames[i]; - Blockly.Extensions.apply(extensionName, this, false); - } - } - if (json['outputShape'] !== undefined) { - this.setOutputShape(json['outputShape']); - } - if (json['checkboxInFlyout'] !== undefined) { - this.setCheckboxInFlyout(json['checkboxInFlyout']); - } - if (json['category'] !== undefined) { - this.setCategory(json['category']); - } -}; - -/** - * Add key/values from mixinObj to this block object. By default, this method - * will check that the keys in mixinObj will not overwrite existing values in - * the block, including prototype values. This provides some insurance against - * mixin / extension incompatibilities with future block features. This check - * can be disabled by passing true as the second argument. - * @param {!Object} mixinObj The key/values pairs to add to this block object. - * @param {boolean=} opt_disableCheck Option flag to disable overwrite checks. - */ -Blockly.Block.prototype.mixin = function(mixinObj, opt_disableCheck) { - if (goog.isDef(opt_disableCheck) && !goog.isBoolean(opt_disableCheck)) { - throw new Error("opt_disableCheck must be a boolean if provided"); - } - if (!opt_disableCheck) { - var overwrites = []; - for (var key in mixinObj) { - if (this[key] !== undefined) { - overwrites.push(key); - } - } - if (overwrites.length) { - throw new Error('Mixin will overwrite block members: ' + - JSON.stringify(overwrites)); - } - } - goog.mixin(this, mixinObj); -}; - -/** - * Set the colour of the block from strings or string table references. - * @param {string|?} primary Primary colour, which may be a string that contains - * string table references. - * @param {string|?} secondary Secondary colour, which may be a string that - * contains string table references. - * @param {string|?} tertiary Tertiary colour, which may be a string that - * contains string table references. - * @param {string|?} quaternary Quaternary colour, which may be a string that - * contains string table references. - * @private - */ -Blockly.Block.prototype.setColourFromRawValues_ = function(primary, secondary, - tertiary, quaternary) { - primary = goog.isString(primary) ? - Blockly.utils.replaceMessageReferences(primary) : primary; - secondary = goog.isString(secondary) ? - Blockly.utils.replaceMessageReferences(secondary) : secondary; - tertiary = goog.isString(tertiary) ? - Blockly.utils.replaceMessageReferences(tertiary) : tertiary; - quaternary = goog.isString(quaternary) ? - Blockly.utils.replaceMessageReferences(quaternary) : quaternary; - - this.setColour(primary, secondary, tertiary, quaternary); -}; - -/** - * Set the colour of the block from JSON, replacing message references as - * needed. - * @param {!Object} json Structured data describing the block. - * @private - */ -Blockly.Block.prototype.setColourFromJson_ = function(json) { - this.setColourFromRawValues_(json['colour'], json['colourSecondary'], - json['colourTertiary'], json['colourQuaternary']); -}; - -/** - * Interpolate a message description onto the block. - * @param {string} message Text contains interpolation tokens (%1, %2, ...) - * that match with fields or inputs defined in the args array. - * @param {!Array} args Array of arguments to be interpolated. - * @param {string=} lastDummyAlign If a dummy input is added at the end, - * how should it be aligned? - * @private - */ -Blockly.Block.prototype.interpolate_ = function(message, args, lastDummyAlign) { - var tokens = Blockly.utils.tokenizeInterpolation(message); - // Interpolate the arguments. Build a list of elements. - var indexDup = []; - var indexCount = 0; - var elements = []; - for (var i = 0; i < tokens.length; i++) { - var token = tokens[i]; - if (typeof token == 'number') { - if (token <= 0 || token > args.length) { - throw new Error('Block "' + this.type + '": ' + - 'Message index %' + token + ' out of range.'); - } - if (indexDup[token]) { - throw new Error('Block "' + this.type + '": ' + - 'Message index %' + token + ' duplicated.'); - } - indexDup[token] = true; - indexCount++; - elements.push(args[token - 1]); - } else { - token = token.trim(); - if (token) { - elements.push(token); - } - } - } - if (indexCount != args.length) { - throw new Error('Block "' + this.type + '": ' + - 'Message does not reference all ' + args.length + ' arg(s).'); - } - // Add last dummy input if needed. - if (elements.length && (typeof elements[elements.length - 1] == 'string' || - goog.string.startsWith( - elements[elements.length - 1]['type'], 'field_'))) { - var dummyInput = {type: 'input_dummy'}; - if (lastDummyAlign) { - dummyInput['align'] = lastDummyAlign; - } - elements.push(dummyInput); - } - // Lookup of alignment constants. - var alignmentLookup = { - 'LEFT': Blockly.ALIGN_LEFT, - 'RIGHT': Blockly.ALIGN_RIGHT, - 'CENTRE': Blockly.ALIGN_CENTRE - }; - // Populate block with inputs and fields. - var fieldStack = []; - for (var i = 0; i < elements.length; i++) { - var element = elements[i]; - if (typeof element == 'string') { - fieldStack.push([element, undefined]); - } else { - var field = null; - var input = null; - do { - var altRepeat = false; - if (typeof element == 'string') { - field = new Blockly.FieldLabel(element); - } else { - switch (element['type']) { - case 'input_value': - input = this.appendValueInput(element['name']); - break; - case 'input_statement': - input = this.appendStatementInput(element['name']); - break; - case 'input_dummy': - input = this.appendDummyInput(element['name']); - break; - default: - field = Blockly.Field.fromJson(element); - - // Unknown field. - if (!field) { - if (element['alt']) { - element = element['alt']; - altRepeat = true; - } else { - console.warn('Blockly could not create a field of type ' + - element['type'] + - '. You may need to register your custom field. See ' + - 'github.com/google/blockly/issues/1584'); - } - } - } - } - } while (altRepeat); - if (field) { - fieldStack.push([field, element['name']]); - } else if (input) { - if (element['check']) { - input.setCheck(element['check']); - } - if (element['align']) { - input.setAlign(alignmentLookup[element['align']]); - } - for (var j = 0; j < fieldStack.length; j++) { - input.appendField(fieldStack[j][0], fieldStack[j][1]); - } - fieldStack.length = 0; - } - } - } -}; - -/** - * Add a value input, statement input or local variable to this block. - * @param {number} type Either Blockly.INPUT_VALUE or Blockly.NEXT_STATEMENT or - * Blockly.DUMMY_INPUT. - * @param {string} name Language-neutral identifier which may used to find this - * input again. Should be unique to this block. - * @return {!Blockly.Input} The input object created. - * @protected - */ -Blockly.Block.prototype.appendInput_ = function(type, name) { - var connection = null; - if (type == Blockly.INPUT_VALUE || type == Blockly.NEXT_STATEMENT) { - connection = this.makeConnection_(type); - } - var input = new Blockly.Input(type, name, this, connection); - // Append input to list. - this.inputList.push(input); - return input; -}; - -/** - * Move a named input to a different location on this block. - * @param {string} name The name of the input to move. - * @param {?string} refName Name of input that should be after the moved input, - * or null to be the input at the end. - */ -Blockly.Block.prototype.moveInputBefore = function(name, refName) { - if (name == refName) { - return; - } - // Find both inputs. - var inputIndex = -1; - var refIndex = refName ? -1 : this.inputList.length; - for (var i = 0, input; input = this.inputList[i]; i++) { - if (input.name == name) { - inputIndex = i; - if (refIndex != -1) { - break; - } - } else if (refName && input.name == refName) { - refIndex = i; - if (inputIndex != -1) { - break; - } - } - } - goog.asserts.assert(inputIndex != -1, 'Named input "%s" not found.', name); - goog.asserts.assert( - refIndex != -1, 'Reference input "%s" not found.', refName); - this.moveNumberedInputBefore(inputIndex, refIndex); -}; - -/** - * Move a numbered input to a different location on this block. - * @param {number} inputIndex Index of the input to move. - * @param {number} refIndex Index of input that should be after the moved input. - */ -Blockly.Block.prototype.moveNumberedInputBefore = function( - inputIndex, refIndex) { - // Validate arguments. - goog.asserts.assert(inputIndex != refIndex, 'Can\'t move input to itself.'); - goog.asserts.assert(inputIndex < this.inputList.length, - 'Input index ' + inputIndex + ' out of bounds.'); - goog.asserts.assert(refIndex <= this.inputList.length, - 'Reference input ' + refIndex + ' out of bounds.'); - // Remove input. - var input = this.inputList[inputIndex]; - this.inputList.splice(inputIndex, 1); - if (inputIndex < refIndex) { - refIndex--; - } - // Reinsert input. - this.inputList.splice(refIndex, 0, input); -}; - -/** - * Remove an input from this block. - * @param {string} name The name of the input. - * @param {boolean=} opt_quiet True to prevent error if input is not present. - * @throws {goog.asserts.AssertionError} if the input is not present and - * opt_quiet is not true. - */ -Blockly.Block.prototype.removeInput = function(name, opt_quiet) { - for (var i = 0, input; input = this.inputList[i]; i++) { - if (input.name == name) { - if (input.connection && input.connection.isConnected()) { - input.connection.setShadowDom(null); - var block = input.connection.targetBlock(); - if (block.isShadow()) { - // Destroy any attached shadow block. - block.dispose(); - } else { - // Disconnect any attached normal block. - block.unplug(); - } - } - input.dispose(); - this.inputList.splice(i, 1); - return; - } - } - if (!opt_quiet) { - goog.asserts.fail('Input "%s" not found.', name); - } -}; - -/** - * Fetches the named input object. - * @param {string} name The name of the input. - * @return {Blockly.Input} The input object, or null if input does not exist. - */ -Blockly.Block.prototype.getInput = function(name) { - for (var i = 0, input; input = this.inputList[i]; i++) { - if (input.name == name) { - return input; - } - } - // This input does not exist. - return null; -}; - -/** - * Fetches the block attached to the named input. - * @param {string} name The name of the input. - * @return {Blockly.Block} The attached value block, or null if the input is - * either disconnected or if the input does not exist. - */ -Blockly.Block.prototype.getInputTargetBlock = function(name) { - var input = this.getInput(name); - return input && input.connection && input.connection.targetBlock(); -}; - -/** - * Returns the comment on this block (or '' if none). - * @return {string} Block's comment. - */ -Blockly.Block.prototype.getCommentText = function() { - return this.comment || ''; -}; - -/** - * Set this block's comment text. - * @param {?string} text The text, or null to delete. - */ -Blockly.Block.prototype.setCommentText = function(text) { - if (this.comment != text) { - Blockly.Events.fire(new Blockly.Events.BlockChange( - this, 'comment', null, this.comment, text || '')); - this.comment = text; - } -}; - -/** - * Set this block's output shape. - * e.g., null, OUTPUT_SHAPE_HEXAGONAL, OUTPUT_SHAPE_ROUND, OUTPUT_SHAPE_SQUARE. - * @param {?number} outputShape Value representing output shape - * (see constants.js). - */ -Blockly.Block.prototype.setOutputShape = function(outputShape) { - this.outputShape_ = outputShape; -}; - -/** - * Get this block's output shape. - * @return {?number} Value representing output shape (see constants.js). - */ -Blockly.Block.prototype.getOutputShape = function() { - return this.outputShape_; -}; - -/** - * Set this block's category (for styling purposes) - * @param {?string} category The block's category (see constants.js). - */ -Blockly.Block.prototype.setCategory = function(category) { - this.category_ = category; -}; - -/** - * Get this block's category (for styling purposes) - * @return {?string} category The block's category (see constants.js). - */ -Blockly.Block.prototype.getCategory = function() { - return this.category_; -}; - -/** - * Set whether this block has a checkbox next to it in the flyout. - * @param {boolean} hasCheckbox True if this block should have a checkbox. - */ -Blockly.Block.prototype.setCheckboxInFlyout = function(hasCheckbox) { - this.checkboxInFlyout_ = hasCheckbox; -}; - -/** - * Get whether this block has a checkbox next to it in the flyout. - * @return {boolean} True if this block should have a checkbox. - */ -Blockly.Block.prototype.hasCheckboxInFlyout = function() { - return this.checkboxInFlyout_; -}; - -/** - * Set this block's warning text. - * @param {?string} text The text, or null to delete. - * @abstract - */ -Blockly.Block.prototype.setWarningText = function(/* text */) { - // NOP. -}; - -/** - * Give this block a mutator dialog. - * @param {Blockly.Mutator} mutator A mutator dialog instance or null to remove. - * @abstract - */ -Blockly.Block.prototype.setMutator = function(/* mutator */) { - // NOP. -}; - -/** - * Return the coordinates of the top-left corner of this block relative to the - * drawing surface's origin (0,0), in workspace units. - * @return {!goog.math.Coordinate} Object with .x and .y properties. - */ -Blockly.Block.prototype.getRelativeToSurfaceXY = function() { - return this.xy_; -}; - -/** - * Move a block by a relative offset. - * @param {number} dx Horizontal offset, in workspace units. - * @param {number} dy Vertical offset, in workspace units. - */ -Blockly.Block.prototype.moveBy = function(dx, dy) { - goog.asserts.assert(!this.parentBlock_, 'Block has parent.'); - var event = new Blockly.Events.BlockMove(this); - this.xy_.translate(dx, dy); - event.recordNew(); - Blockly.Events.fire(event); -}; - -/** - * Create a connection of the specified type. - * @param {number} type The type of the connection to create. - * @return {!Blockly.Connection} A new connection of the specified type. - * @private - */ -Blockly.Block.prototype.makeConnection_ = function(type) { - return new Blockly.Connection(this, type); -}; - -/** - * Recursively checks whether all statement and value inputs are filled with - * blocks. Also checks all following statement blocks in this stack. - * @param {boolean=} opt_shadowBlocksAreFilled An optional argument controlling - * whether shadow blocks are counted as filled. Defaults to true. - * @return {boolean} True if all inputs are filled, false otherwise. - */ -Blockly.Block.prototype.allInputsFilled = function(opt_shadowBlocksAreFilled) { - // Account for the shadow block filledness toggle. - if (opt_shadowBlocksAreFilled === undefined) { - opt_shadowBlocksAreFilled = true; - } - if (!opt_shadowBlocksAreFilled && this.isShadow()) { - return false; - } - - // Recursively check each input block of the current block. - for (var i = 0, input; input = this.inputList[i]; i++) { - if (!input.connection) { - continue; - } - var target = input.connection.targetBlock(); - if (!target || !target.allInputsFilled(opt_shadowBlocksAreFilled)) { - return false; - } - } - - // Recursively check the next block after the current block. - var next = this.getNextBlock(); - if (next) { - return next.allInputsFilled(opt_shadowBlocksAreFilled); - } - - return true; -}; - -/** - * This method returns a string describing this Block in developer terms (type - * name and ID; English only). - * - * Intended to on be used in console logs and errors. If you need a string that - * uses the user's native language (including block text, field values, and - * child blocks), use [toString()]{@link Blockly.Block#toString}. - * @return {string} The description. - */ -Blockly.Block.prototype.toDevString = function() { - var msg = this.type ? '"' + this.type + '" block' : 'Block'; - if (this.id) { - msg += ' (id="' + this.id + '")'; - } - return msg; -}; diff --git a/core/block_animations.js b/core/block_animations.js deleted file mode 100644 index 1e708c08f5..0000000000 --- a/core/block_animations.js +++ /dev/null @@ -1,107 +0,0 @@ -/** - * @license - * Visual Blocks Editor - * - * Copyright 2018 Google Inc. - * https://developers.google.com/blockly/ - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @fileoverview Methods animating a block on connection and disconnection. - * @author fenichel@google.com (Rachel Fenichel) - */ -'use strict'; - -goog.provide('Blockly.BlockAnimations'); - - -/** - * Play some UI effects (sound, animation) when disposing of a block. - * @param {!Blockly.BlockSvg} block The block being disposed of. - * @package - */ -Blockly.BlockAnimations.disposeUiEffect = function(block) { - var workspace = block.workspace; - var svgGroup = block.getSvgRoot(); - workspace.getAudioManager().play('delete'); - - var xy = workspace.getSvgXY(svgGroup); - // Deeply clone the current block. - var clone = svgGroup.cloneNode(true); - clone.translateX_ = xy.x; - clone.translateY_ = xy.y; - clone.setAttribute('transform', 'translate(' + xy.x + ',' + xy.y + ')'); - workspace.getParentSvg().appendChild(clone); - clone.bBox_ = clone.getBBox(); - // Start the animation. - Blockly.BlockAnimations.disposeUiStep_(clone, workspace.RTL, new Date, - workspace.scale); -}; - -/** - * Animate a cloned block and eventually dispose of it. - * This is a class method, not an instance method since the original block has - * been destroyed and is no longer accessible. - * @param {!Element} clone SVG element to animate and dispose of. - * @param {boolean} rtl True if RTL, false if LTR. - * @param {!Date} start Date of animation's start. - * @param {number} workspaceScale Scale of workspace. - * @private - */ -Blockly.BlockAnimations.disposeUiStep_ = function(clone, rtl, start, - workspaceScale) { - var ms = new Date - start; - var percent = ms / 150; - if (percent > 1) { - goog.dom.removeNode(clone); - } else { - var x = clone.translateX_ + - (rtl ? -1 : 1) * clone.bBox_.width * workspaceScale / 2 * percent; - var y = clone.translateY_ + clone.bBox_.height * workspaceScale * percent; - var scale = (1 - percent) * workspaceScale; - clone.setAttribute('transform', 'translate(' + x + ',' + y + ')' + - ' scale(' + scale + ')'); - setTimeout(Blockly.BlockAnimations.disposeUiStep_, 10, clone, rtl, start, - workspaceScale); - } -}; - -/** - * Play some UI effects (sound, ripple) after a connection has been established. - * @param {!Blockly.BlockSvg} block The block being connected. - * @package - */ -Blockly.BlockAnimations.connectionUiEffect = function(block) { - block.workspace.getAudioManager().play('click'); -}; - -/** - * Play some UI effects (sound, animation) when disconnecting a block. - * No-op in scratch-blocks, which has no disconnect animation. - * @param {!Blockly.BlockSvg} _block The block being disconnected. - * @package - */ -Blockly.BlockAnimations.disconnectUiEffect = function( - /* eslint-disable no-unused-vars */ _block - /* eslint-enable no-unused-vars */) { -}; - -/** - * Stop the disconnect UI animation immediately. - * No-op in scratch-blocks, which has no disconnect animation. - * @package - */ -Blockly.BlockAnimations.disconnectUiStop = function() { -}; diff --git a/core/block_drag_surface.js b/core/block_drag_surface.js deleted file mode 100644 index d5ad047140..0000000000 --- a/core/block_drag_surface.js +++ /dev/null @@ -1,299 +0,0 @@ -/** - * @license - * Visual Blocks Editor - * - * Copyright 2016 Google Inc. - * https://developers.google.com/blockly/ - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @fileoverview A class that manages a surface for dragging blocks. When a - * block drag is started, we move the block (and children) to a separate DOM - * element that we move around using translate3d. At the end of the drag, the - * blocks are put back in into the SVG they came from. This helps performance by - * avoiding repainting the entire SVG on every mouse move while dragging blocks. - * @author picklesrus - */ - -'use strict'; - -goog.provide('Blockly.BlockDragSurfaceSvg'); -goog.require('Blockly.utils'); -goog.require('goog.asserts'); -goog.require('goog.math.Coordinate'); - - -/** - * Class for a drag surface for the currently dragged block. This is a separate - * SVG that contains only the currently moving block, or nothing. - * @param {!Element} container Containing element. - * @constructor - */ -Blockly.BlockDragSurfaceSvg = function(container) { - /** - * @type {!Element} - * @private - */ - this.container_ = container; - this.createDom(); -}; - -/** - * The SVG drag surface. Set once by Blockly.BlockDragSurfaceSvg.createDom. - * @type {Element} - * @private - */ -Blockly.BlockDragSurfaceSvg.prototype.SVG_ = null; - -/** - * This is where blocks live while they are being dragged if the drag surface - * is enabled. - * @type {Element} - * @private - */ -Blockly.BlockDragSurfaceSvg.prototype.dragGroup_ = null; - -/** - * Containing HTML element; parent of the workspace and the drag surface. - * @type {Element} - * @private - */ -Blockly.BlockDragSurfaceSvg.prototype.container_ = null; - -/** - * Cached value for the scale of the drag surface. - * Used to set/get the correct translation during and after a drag. - * @type {number} - * @private - */ -Blockly.BlockDragSurfaceSvg.prototype.scale_ = 1; - -/** - * Cached value for the translation of the drag surface. - * This translation is in pixel units, because the scale is applied to the - * drag group rather than the top-level SVG. - * @type {goog.math.Coordinate} - * @private - */ -Blockly.BlockDragSurfaceSvg.prototype.surfaceXY_ = null; - -/** - * ID for the drag shadow filter, set in createDom. - * Belongs in Scratch Blocks but not Blockly. - * @type {string} - * @private - */ -Blockly.BlockDragSurfaceSvg.prototype.dragShadowFilterId_ = ''; - -/** - * Standard deviation for gaussian blur on drag shadow, in px. - * Belongs in Scratch Blocks but not Blockly. - * @type {number} - * @const - */ -Blockly.BlockDragSurfaceSvg.SHADOW_STD_DEVIATION = 6; - -/** - * Create the drag surface and inject it into the container. - */ -Blockly.BlockDragSurfaceSvg.prototype.createDom = function() { - if (this.SVG_) { - return; // Already created. - } - this.SVG_ = Blockly.utils.createSvgElement('svg', - { - 'xmlns': Blockly.SVG_NS, - 'xmlns:html': Blockly.HTML_NS, - 'xmlns:xlink': 'http://www.w3.org/1999/xlink', - 'version': '1.1', - 'class': 'blocklyBlockDragSurface' - }, this.container_); - this.dragGroup_ = Blockly.utils.createSvgElement('g', {}, this.SVG_); - // Belongs in Scratch Blocks, but not Blockly. - var defs = Blockly.utils.createSvgElement('defs', {}, this.SVG_); - this.dragShadowFilterId_ = this.createDropShadowDom_(defs); - this.dragGroup_.setAttribute( - 'filter', 'url(#' + this.dragShadowFilterId_ + ')'); -}; - -/** - * Scratch-specific: Create the SVG def for the drop shadow. - * @param {Element} defs Defs element to insert the shadow filter definition - * @return {string} ID for the filter element - * @private - */ -Blockly.BlockDragSurfaceSvg.prototype.createDropShadowDom_ = function(defs) { - var rnd = String(Math.random()).substring(2); - // Adjust these width/height, x/y properties to stop the shadow from clipping - var dragShadowFilter = Blockly.utils.createSvgElement('filter', - { - 'id': 'blocklyDragShadowFilter' + rnd, - 'height': '140%', - 'width': '140%', - 'y': '-20%', - 'x': '-20%' - }, - defs); - Blockly.utils.createSvgElement('feGaussianBlur', - { - 'in': 'SourceAlpha', - 'stdDeviation': Blockly.BlockDragSurfaceSvg.SHADOW_STD_DEVIATION - }, - dragShadowFilter); - var componentTransfer = Blockly.utils.createSvgElement( - 'feComponentTransfer', {'result': 'offsetBlur'}, dragShadowFilter); - // Shadow opacity is specified in the adjustable colour library, - // since the darkness of the shadow largely depends on the workspace colour. - Blockly.utils.createSvgElement('feFuncA', - { - 'type': 'linear', - 'slope': Blockly.Colours.dragShadowOpacity - }, - componentTransfer); - Blockly.utils.createSvgElement('feComposite', - { - 'in': 'SourceGraphic', - 'in2': 'offsetBlur', - 'operator': 'over' - }, - dragShadowFilter); - return dragShadowFilter.id; -}; - -/** - * Set the SVG blocks on the drag surface's group and show the surface. - * Only one block group should be on the drag surface at a time. - * @param {!Element} blocks Block or group of blocks to place on the drag - * surface. - */ -Blockly.BlockDragSurfaceSvg.prototype.setBlocksAndShow = function(blocks) { - goog.asserts.assert( - this.dragGroup_.childNodes.length == 0, 'Already dragging a block.'); - // appendChild removes the blocks from the previous parent - this.dragGroup_.appendChild(blocks); - this.SVG_.style.display = 'block'; - this.surfaceXY_ = new goog.math.Coordinate(0, 0); - // This allows blocks to be dragged outside of the blockly svg space. - // This should be reset to hidden at the end of the block drag. - // Note that this behavior is different from blockly where block disappear - // "under" the blockly area. - var injectionDiv = document.getElementsByClassName('injectionDiv')[0]; - injectionDiv.style.overflow = 'visible'; -}; - -/** - * Translate and scale the entire drag surface group to the given position, to - * keep in sync with the workspace. - * @param {number} x X translation in workspace coordinates. - * @param {number} y Y translation in workspace coordinates. - * @param {number} scale Scale of the group. - */ -Blockly.BlockDragSurfaceSvg.prototype.translateAndScaleGroup = function(x, y, scale) { - this.scale_ = scale; - // This is a work-around to prevent a the blocks from rendering - // fuzzy while they are being dragged on the drag surface. - var fixedX = x.toFixed(0); - var fixedY = y.toFixed(0); - this.dragGroup_.setAttribute('transform', - 'translate(' + fixedX + ',' + fixedY + ') scale(' + scale + ')'); -}; - -/** - * Translate the drag surface's SVG based on its internal state. - * @private - */ -Blockly.BlockDragSurfaceSvg.prototype.translateSurfaceInternal_ = function() { - var x = this.surfaceXY_.x; - var y = this.surfaceXY_.y; - // This is a work-around to prevent a the blocks from rendering - // fuzzy while they are being dragged on the drag surface. - x = x.toFixed(0); - y = y.toFixed(0); - this.SVG_.style.display = 'block'; - - Blockly.utils.setCssTransform(this.SVG_, - 'translate3d(' + x + 'px, ' + y + 'px, 0px)'); -}; - -/** - * Translate the entire drag surface during a drag. - * We translate the drag surface instead of the blocks inside the surface - * so that the browser avoids repainting the SVG. - * Because of this, the drag coordinates must be adjusted by scale. - * @param {number} x X translation for the entire surface. - * @param {number} y Y translation for the entire surface. - */ -Blockly.BlockDragSurfaceSvg.prototype.translateSurface = function(x, y) { - this.surfaceXY_ = new goog.math.Coordinate(x * this.scale_, y * this.scale_); - this.translateSurfaceInternal_(); -}; - -/** - * Reports the surface translation in scaled workspace coordinates. - * Use this when finishing a drag to return blocks to the correct position. - * @return {!goog.math.Coordinate} Current translation of the surface. - */ -Blockly.BlockDragSurfaceSvg.prototype.getSurfaceTranslation = function() { - var xy = Blockly.utils.getRelativeXY(this.SVG_); - return new goog.math.Coordinate(xy.x / this.scale_, xy.y / this.scale_); -}; - -/** - * Provide a reference to the drag group (primarily for - * BlockSvg.getRelativeToSurfaceXY). - * @return {Element} Drag surface group element. - */ -Blockly.BlockDragSurfaceSvg.prototype.getGroup = function() { - return this.dragGroup_; -}; - -/** - * Get the current blocks on the drag surface, if any (primarily - * for BlockSvg.getRelativeToSurfaceXY). - * @return {!Element|undefined} Drag surface block DOM element, or undefined - * if no blocks exist. - */ -Blockly.BlockDragSurfaceSvg.prototype.getCurrentBlock = function() { - return this.dragGroup_.firstChild; -}; - -/** - * Clear the group and hide the surface; move the blocks off onto the provided - * element. - * If the block is being deleted it doesn't need to go back to the original - * surface, since it would be removed immediately during dispose. - * @param {Element=} opt_newSurface Surface the dragging blocks should be moved - * to, or null if the blocks should be removed from this surface without - * being moved to a different surface. - */ -Blockly.BlockDragSurfaceSvg.prototype.clearAndHide = function(opt_newSurface) { - if (opt_newSurface) { - // appendChild removes the node from this.dragGroup_ - opt_newSurface.appendChild(this.getCurrentBlock()); - } else { - this.dragGroup_.removeChild(this.getCurrentBlock()); - } - this.SVG_.style.display = 'none'; - goog.asserts.assert( - this.dragGroup_.childNodes.length == 0, 'Drag group was not cleared.'); - this.surfaceXY_ = null; - - // Reset the overflow property back to hidden so that nothing appears outside - // of the blockly area. - // Note that this behavior is different from blockly. See note in - // setBlocksAndShow. - var injectionDiv = document.getElementsByClassName('injectionDiv')[0]; - injectionDiv.style.overflow = 'hidden'; -}; diff --git a/core/block_dragger.js b/core/block_dragger.js deleted file mode 100644 index 80591d1a72..0000000000 --- a/core/block_dragger.js +++ /dev/null @@ -1,421 +0,0 @@ -/** - * @license - * Visual Blocks Editor - * - * Copyright 2017 Google Inc. - * https://developers.google.com/blockly/ - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @fileoverview Methods for dragging a block visually. - * @author fenichel@google.com (Rachel Fenichel) - */ -'use strict'; - -goog.provide('Blockly.BlockDragger'); - -goog.require('Blockly.BlockAnimations'); -goog.require('Blockly.Events.BlockMove'); -goog.require('Blockly.Events.DragBlockOutside'); -goog.require('Blockly.Events.EndBlockDrag'); -goog.require('Blockly.InsertionMarkerManager'); - -goog.require('goog.math.Coordinate'); -goog.require('goog.asserts'); - - -/** - * Class for a block dragger. It moves blocks around the workspace when they - * are being dragged by a mouse or touch. - * @param {!Blockly.BlockSvg} block The block to drag. - * @param {!Blockly.WorkspaceSvg} workspace The workspace to drag on. - * @constructor - */ -Blockly.BlockDragger = function(block, workspace) { - /** - * The top block in the stack that is being dragged. - * @type {!Blockly.BlockSvg} - * @private - */ - this.draggingBlock_ = block; - - /** - * The workspace on which the block is being dragged. - * @type {!Blockly.WorkspaceSvg} - * @private - */ - this.workspace_ = workspace; - - /** - * Object that keeps track of connections on dragged blocks. - * @type {!Blockly.InsertionMarkerManager} - * @private - */ - this.draggedConnectionManager_ = new Blockly.InsertionMarkerManager( - this.draggingBlock_); - - /** - * Which delete area the mouse pointer is over, if any. - * One of {@link Blockly.DELETE_AREA_TRASH}, - * {@link Blockly.DELETE_AREA_TOOLBOX}, or {@link Blockly.DELETE_AREA_NONE}. - * @type {?number} - * @private - */ - this.deleteArea_ = null; - - /** - * Whether the block would be deleted if dropped immediately. - * @type {boolean} - * @private - */ - this.wouldDeleteBlock_ = false; - - /** - * Whether the currently dragged block is outside of the workspace. Keep - * track so that we can fire events only when this changes. - * @type {boolean} - * @private - */ - this.wasOutside_ = false; - - /** - * The location of the top left corner of the dragging block at the beginning - * of the drag in workspace coordinates. - * @type {!goog.math.Coordinate} - * @private - */ - this.startXY_ = this.draggingBlock_.getRelativeToSurfaceXY(); - - /** - * A list of all of the icons (comment, warning, and mutator) that are - * on this block and its descendants. Moving an icon moves the bubble that - * extends from it if that bubble is open. - * @type {Array.} - * @private - */ - this.dragIconData_ = Blockly.BlockDragger.initIconData_(block); -}; - -/** - * Sever all links from this object. - * @package - */ -Blockly.BlockDragger.prototype.dispose = function() { - this.draggingBlock_ = null; - this.workspace_ = null; - this.startWorkspace_ = null; - this.dragIconData_.length = 0; - - if (this.draggedConnectionManager_) { - this.draggedConnectionManager_.dispose(); - this.draggedConnectionManager_ = null; - } -}; - -/** - * Make a list of all of the icons (comment, warning, and mutator) that are - * on this block and its descendants. Moving an icon moves the bubble that - * extends from it if that bubble is open. - * @param {!Blockly.BlockSvg} block The root block that is being dragged. - * @return {!Array.} The list of all icons and their locations. - * @private - */ -Blockly.BlockDragger.initIconData_ = function(block) { - // Build a list of icons that need to be moved and where they started. - var dragIconData = []; - var descendants = block.getDescendants(false); - for (var i = 0, descendant; descendant = descendants[i]; i++) { - var icons = descendant.getIcons(); - for (var j = 0; j < icons.length; j++) { - var data = { - // goog.math.Coordinate with x and y properties (workspace coordinates). - location: icons[j].getIconLocation(), - // Blockly.Icon - icon: icons[j] - }; - dragIconData.push(data); - } - } - return dragIconData; -}; - -/** - * Start dragging a block. This includes moving it to the drag surface. - * @param {!goog.math.Coordinate} currentDragDeltaXY How far the pointer has - * moved from the position at mouse down, in pixel units. - * @package - */ -Blockly.BlockDragger.prototype.startBlockDrag = function(currentDragDeltaXY) { - if (!Blockly.Events.getGroup()) { - Blockly.Events.setGroup(true); - } - - this.workspace_.setResizesEnabled(false); - Blockly.BlockAnimations.disconnectUiStop(); - - if (this.draggingBlock_.getParent()) { - this.draggingBlock_.unplug(); - var delta = this.pixelsToWorkspaceUnits_(currentDragDeltaXY); - var newLoc = goog.math.Coordinate.sum(this.startXY_, delta); - - this.draggingBlock_.translate(newLoc.x, newLoc.y); - Blockly.BlockAnimations.disconnectUiEffect(this.draggingBlock_); - } - this.draggingBlock_.setDragging(true); - // For future consideration: we may be able to put moveToDragSurface inside - // the block dragger, which would also let the block not track the block drag - // surface. - this.draggingBlock_.moveToDragSurface_(); - - var toolbox = this.workspace_.getToolbox(); - if (toolbox) { - var style = this.draggingBlock_.isDeletable() ? 'blocklyToolboxDelete' : - 'blocklyToolboxGrab'; - toolbox.addStyle(style); - } -}; - -/** - * Execute a step of block dragging, based on the given event. Update the - * display accordingly. - * @param {!Event} e The most recent move event. - * @param {!goog.math.Coordinate} currentDragDeltaXY How far the pointer has - * moved from the position at the start of the drag, in pixel units. - * @package - * @return {boolean} True if the event should be propagated, false if not. - */ -Blockly.BlockDragger.prototype.dragBlock = function(e, currentDragDeltaXY) { - var delta = this.pixelsToWorkspaceUnits_(currentDragDeltaXY); - var newLoc = goog.math.Coordinate.sum(this.startXY_, delta); - - this.draggingBlock_.moveDuringDrag(newLoc); - this.dragIcons_(delta); - - this.deleteArea_ = this.workspace_.isDeleteArea(e); - var isOutside = !this.workspace_.isInsideBlocksArea(e); - this.draggedConnectionManager_.update(delta, this.deleteArea_, isOutside); - if (isOutside !== this.wasOutside_) { - this.fireDragOutsideEvent_(isOutside); - this.wasOutside_ = isOutside; - } - - this.updateCursorDuringBlockDrag_(isOutside); - return isOutside; -}; - -/** - * Finish a block drag and put the block back on the workspace. - * @param {!Event} e The mouseup/touchend event. - * @param {!goog.math.Coordinate} currentDragDeltaXY How far the pointer has - * moved from the position at the start of the drag, in pixel units. - * @package - */ -Blockly.BlockDragger.prototype.endBlockDrag = function(e, currentDragDeltaXY) { - // Make sure internal state is fresh. - this.dragBlock(e, currentDragDeltaXY); - this.dragIconData_ = []; - var isOutside = this.wasOutside_; - this.fireEndDragEvent_(isOutside); - this.draggingBlock_.setMouseThroughStyle(false); - - Blockly.BlockAnimations.disconnectUiStop(); - - var delta = this.pixelsToWorkspaceUnits_(currentDragDeltaXY); - var newLoc = goog.math.Coordinate.sum(this.startXY_, delta); - this.draggingBlock_.moveOffDragSurface_(newLoc); - - // Scratch-specific: note possible illegal definition deletion for rollback below. - var isDeletingProcDef = this.wouldDeleteBlock_ && - (this.draggingBlock_.type == Blockly.PROCEDURES_DEFINITION_BLOCK_TYPE); - - var deleted = this.maybeDeleteBlock_(); - if (!deleted) { - // These are expensive and don't need to be done if we're deleting. - this.draggingBlock_.moveConnections_(delta.x, delta.y); - this.draggingBlock_.setDragging(false); - this.fireMoveEvent_(); - if (this.draggedConnectionManager_.wouldConnectBlock()) { - // Applying connections also rerenders the relevant blocks. - this.draggedConnectionManager_.applyConnections(); - } else { - this.draggingBlock_.render(); - } - this.draggingBlock_.scheduleSnapAndBump(); - } - this.workspace_.setResizesEnabled(true); - - var toolbox = this.workspace_.getToolbox(); - if (toolbox) { - var style = this.draggingBlock_.isDeletable() ? 'blocklyToolboxDelete' : - 'blocklyToolboxGrab'; - toolbox.removeStyle(style); - } - Blockly.Events.setGroup(false); - - if (isOutside) { - var ws = this.workspace_; - // Reset a drag to outside of scratch-blocks - setTimeout(function() { - ws.undo(); - }); - } - - // Scratch-specific: roll back deletes that create call blocks with defines. - // Have to wait for connections to be re-established, so put in setTimeout. - // Only do this if we deleted a proc def. - if (isDeletingProcDef) { - var ws = this.workspace_; - setTimeout(function() { - var allBlocks = ws.getAllBlocks(); - for (var i = 0; i < allBlocks.length; i++) { - var block = allBlocks[i]; - if (block.type == Blockly.PROCEDURES_CALL_BLOCK_TYPE) { - var procCode = block.getProcCode(); - // Check for call blocks with no associated define block. - if (!Blockly.Procedures.getDefineBlock(procCode, ws)) { - alert(Blockly.Msg.PROCEDURE_USED); - ws.undo(); - return; // There can only be one define deletion at a time. - } - } - } - // The proc deletion was valid, update the toolbox. - ws.refreshToolboxSelection_(); - }); - } -}; - -/** - * Fire an event when the dragged blocks move outside or back into the blocks workspace - * @param {?boolean} isOutside True if the drag is going outside the visible area. - * @private - */ -Blockly.BlockDragger.prototype.fireDragOutsideEvent_ = function(isOutside) { - var event = new Blockly.Events.DragBlockOutside(this.draggingBlock_); - event.isOutside = isOutside; - Blockly.Events.fire(event); -}; - -/** - * Fire an end drag event at the end of a block drag. - * @param {?boolean} isOutside True if the drag is going outside the visible area. - * @private - */ -Blockly.BlockDragger.prototype.fireEndDragEvent_ = function(isOutside) { - var event = new Blockly.Events.EndBlockDrag(this.draggingBlock_, isOutside); - Blockly.Events.fire(event); -}; - -/** - * Fire a move event at the end of a block drag. - * @private - */ -Blockly.BlockDragger.prototype.fireMoveEvent_ = function() { - var event = new Blockly.Events.BlockMove(this.draggingBlock_); - event.oldCoordinate = this.startXY_; - event.recordNew(); - Blockly.Events.fire(event); -}; - -/** - * Shut the trash can and, if necessary, delete the dragging block. - * Should be called at the end of a block drag. - * @return {boolean} whether the block was deleted. - * @private - */ -Blockly.BlockDragger.prototype.maybeDeleteBlock_ = function() { - var trashcan = this.workspace_.trashcan; - - if (this.wouldDeleteBlock_) { - if (trashcan) { - goog.Timer.callOnce(trashcan.close, 100, trashcan); - } - // Fire a move event, so we know where to go back to for an undo. - this.fireMoveEvent_(); - this.draggingBlock_.dispose(false, true); - } else if (trashcan) { - // Make sure the trash can is closed. - trashcan.close(); - } - return this.wouldDeleteBlock_; -}; - -/** - * Update the cursor (and possibly the trash can lid) to reflect whether the - * dragging block would be deleted if released immediately. - * @param {boolean} isOutside True if the cursor is outside of the blocks workspace - * @private - */ -Blockly.BlockDragger.prototype.updateCursorDuringBlockDrag_ = function(isOutside) { - this.wouldDeleteBlock_ = this.draggedConnectionManager_.wouldDeleteBlock(); - var trashcan = this.workspace_.trashcan; - if (this.wouldDeleteBlock_) { - this.draggingBlock_.setDeleteStyle(true); - if (this.deleteArea_ == Blockly.DELETE_AREA_TRASH && trashcan) { - trashcan.setOpen_(true); - } - } else { - this.draggingBlock_.setDeleteStyle(false); - if (trashcan) { - trashcan.setOpen_(false); - } - } - - if (isOutside) { - // Let mouse events through to GUI - this.draggingBlock_.setMouseThroughStyle(true); - } else { - this.draggingBlock_.setMouseThroughStyle(false); - } -}; - -/** - * Convert a coordinate object from pixels to workspace units, including a - * correction for mutator workspaces. - * This function does not consider differing origins. It simply scales the - * input's x and y values. - * @param {!goog.math.Coordinate} pixelCoord A coordinate with x and y values - * in css pixel units. - * @return {!goog.math.Coordinate} The input coordinate divided by the workspace - * scale. - * @private - */ -Blockly.BlockDragger.prototype.pixelsToWorkspaceUnits_ = function(pixelCoord) { - var result = new goog.math.Coordinate(pixelCoord.x / this.workspace_.scale, - pixelCoord.y / this.workspace_.scale); - if (this.workspace_.isMutator) { - // If we're in a mutator, its scale is always 1, purely because of some - // oddities in our rendering optimizations. The actual scale is the same as - // the scale on the parent workspace. - // Fix that for dragging. - var mainScale = this.workspace_.options.parentWorkspace.scale; - result = result.scale(1 / mainScale); - } - return result; -}; - -/** - * Move all of the icons connected to this drag. - * @param {!goog.math.Coordinate} dxy How far to move the icons from their - * original positions, in workspace units. - * @private - */ -Blockly.BlockDragger.prototype.dragIcons_ = function(dxy) { - // Moving icons moves their associated bubbles. - for (var i = 0; i < this.dragIconData_.length; i++) { - var data = this.dragIconData_[i]; - data.icon.setIconLocation(goog.math.Coordinate.sum(data.location, dxy)); - } -}; diff --git a/core/block_events.js b/core/block_events.js deleted file mode 100644 index 681b8903e4..0000000000 --- a/core/block_events.js +++ /dev/null @@ -1,531 +0,0 @@ -/** - * @license - * Visual Blocks Editor - * - * Copyright 2018 Google Inc. - * https://developers.google.com/blockly/ - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @fileoverview Classes for all types of block events. - * @author fenichel@google.com (Rachel Fenichel) - */ -'use strict'; - -goog.provide('Blockly.Events.BlockBase'); -goog.provide('Blockly.Events.BlockChange'); -goog.provide('Blockly.Events.BlockCreate'); -goog.provide('Blockly.Events.BlockDelete'); -goog.provide('Blockly.Events.BlockMove'); -goog.provide('Blockly.Events.Change'); // Deprecated. -goog.provide('Blockly.Events.Create'); // Deprecated. -goog.provide('Blockly.Events.Delete'); // Deprecated. -goog.provide('Blockly.Events.Move'); // Deprecated. - -goog.require('Blockly.Events'); -goog.require('Blockly.Events.Abstract'); - -goog.require('goog.array'); -goog.require('goog.math.Coordinate'); - - -/** - * Abstract class for a block event. - * @param {Blockly.Block} block The block this event corresponds to. - * @extends {Blockly.Events.Abstract} - * @constructor - */ -Blockly.Events.BlockBase = function(block) { - Blockly.Events.BlockBase.superClass_.constructor.call(this); - - /** - * The block id for the block this event pertains to - * @type {string} - */ - this.blockId = block.id; - this.workspaceId = block.workspace.id; -}; -goog.inherits(Blockly.Events.BlockBase, Blockly.Events.Abstract); - -/** - * Encode the event as JSON. - * @return {!Object} JSON representation. - */ -Blockly.Events.BlockBase.prototype.toJson = function() { - var json = Blockly.Events.BlockBase.superClass_.toJson.call(this); - json['blockId'] = this.blockId; - return json; -}; - -/** - * Decode the JSON event. - * @param {!Object} json JSON representation. - */ -Blockly.Events.BlockBase.prototype.fromJson = function(json) { - Blockly.Events.BlockBase.superClass_.toJson.call(this); - this.blockId = json['blockId']; -}; - -/** - * Class for a block change event. - * @param {Blockly.Block} block The changed block. Null for a blank event. - * @param {string} element One of 'field', 'comment', 'disabled', etc. - * @param {?string} name Name of input or field affected, or null. - * @param {*} oldValue Previous value of element. - * @param {*} newValue New value of element. - * @extends {Blockly.Events.BlockBase} - * @constructor - */ -Blockly.Events.Change = function(block, element, name, oldValue, newValue) { - if (!block) { - return; // Blank event to be populated by fromJson. - } - Blockly.Events.Change.superClass_.constructor.call(this, block); - this.element = element; - this.name = name; - this.oldValue = oldValue; - this.newValue = newValue; -}; -goog.inherits(Blockly.Events.Change, Blockly.Events.BlockBase); - -/** - * Class for a block change event. - * @param {Blockly.Block} block The changed block. Null for a blank event. - * @param {string} element One of 'field', 'comment', 'disabled', etc. - * @param {?string} name Name of input or field affected, or null. - * @param {*} oldValue Previous value of element. - * @param {*} newValue New value of element. - * @extends {Blockly.Events.BlockBase} - * @constructor - */ -Blockly.Events.BlockChange = Blockly.Events.Change; - -/** - * Type of this event. - * @type {string} - */ -Blockly.Events.Change.prototype.type = Blockly.Events.CHANGE; - -/** - * Encode the event as JSON. - * @return {!Object} JSON representation. - */ -Blockly.Events.Change.prototype.toJson = function() { - var json = Blockly.Events.Change.superClass_.toJson.call(this); - json['element'] = this.element; - if (this.name) { - json['name'] = this.name; - } - json['newValue'] = this.newValue; - return json; -}; - -/** - * Decode the JSON event. - * @param {!Object} json JSON representation. - */ -Blockly.Events.Change.prototype.fromJson = function(json) { - Blockly.Events.Change.superClass_.fromJson.call(this, json); - this.element = json['element']; - this.name = json['name']; - this.newValue = json['newValue']; -}; - -/** - * Does this event record any change of state? - * @return {boolean} False if something changed. - */ -Blockly.Events.Change.prototype.isNull = function() { - return this.oldValue == this.newValue; -}; - -/** - * Run a change event. - * @param {boolean} forward True if run forward, false if run backward (undo). - */ -Blockly.Events.Change.prototype.run = function(forward) { - var workspace = this.getEventWorkspace_(); - var block = workspace.getBlockById(this.blockId); - if (!block) { - console.warn("Can't change non-existent block: " + this.blockId); - return; - } - if (block.mutator) { - // Close the mutator (if open) since we don't want to update it. - block.mutator.setVisible(false); - } - var value = forward ? this.newValue : this.oldValue; - switch (this.element) { - case 'field': - var field = block.getField(this.name); - if (field) { - // Run the validator for any side-effects it may have. - // The validator's opinion on validity is ignored. - field.callValidator(value); - field.setValue(value); - } else { - console.warn("Can't set non-existent field: " + this.name); - } - break; - case 'comment': - block.setCommentText(value || null); - break; - case 'collapsed': - block.setCollapsed(value); - break; - case 'disabled': - block.setDisabled(value); - break; - case 'inline': - block.setInputsInline(value); - break; - case 'mutation': - var oldMutation = ''; - if (block.mutationToDom) { - var oldMutationDom = block.mutationToDom(); - oldMutation = oldMutationDom && Blockly.Xml.domToText(oldMutationDom); - } - if (block.domToMutation) { - value = value || ''; - var dom = Blockly.Xml.textToDom('' + value + ''); - block.domToMutation(dom.firstChild); - } - Blockly.Events.fire(new Blockly.Events.Change( - block, 'mutation', null, oldMutation, value)); - break; - default: - console.warn('Unknown change type: ' + this.element); - } -}; - -/** - * Class for a block creation event. - * @param {Blockly.Block} block The created block. Null for a blank event. - * @extends {Blockly.Events.BlockBase} - * @constructor - */ -Blockly.Events.Create = function(block) { - if (!block) { - return; // Blank event to be populated by fromJson. - } - Blockly.Events.Create.superClass_.constructor.call(this, block); - - if (block.workspace.rendered) { - this.xml = Blockly.Xml.blockToDomWithXY(block); - } else { - this.xml = Blockly.Xml.blockToDom(block); - } - this.ids = Blockly.Events.getDescendantIds_(block); -}; -goog.inherits(Blockly.Events.Create, Blockly.Events.BlockBase); - -/** - * Class for a block creation event. - * @param {Blockly.Block} block The created block. Null for a blank event. - * @extends {Blockly.Events.BlockBase} - * @constructor - */ -Blockly.Events.BlockCreate = Blockly.Events.Create; - -/** - * Type of this event. - * @type {string} - */ -Blockly.Events.Create.prototype.type = Blockly.Events.CREATE; - -/** - * Encode the event as JSON. - * @return {!Object} JSON representation. - */ -Blockly.Events.Create.prototype.toJson = function() { - var json = Blockly.Events.Create.superClass_.toJson.call(this); - json['xml'] = Blockly.Xml.domToText(this.xml); - json['ids'] = this.ids; - return json; -}; - -/** - * Decode the JSON event. - * @param {!Object} json JSON representation. - */ -Blockly.Events.Create.prototype.fromJson = function(json) { - Blockly.Events.Create.superClass_.fromJson.call(this, json); - this.xml = Blockly.Xml.textToDom('' + json['xml'] + '').firstChild; - this.ids = json['ids']; -}; - -/** - * Run a creation event. - * @param {boolean} forward True if run forward, false if run backward (undo). - */ -Blockly.Events.Create.prototype.run = function(forward) { - var workspace = this.getEventWorkspace_(); - if (forward) { - var xml = goog.dom.createDom('xml'); - xml.appendChild(this.xml); - Blockly.Xml.domToWorkspace(xml, workspace); - } else { - for (var i = 0, id; id = this.ids[i]; i++) { - var block = workspace.getBlockById(id); - if (block) { - block.dispose(false, false); - } else if (id == this.blockId) { - // Only complain about root-level block. - console.warn("Can't uncreate non-existent block: " + id); - } - } - } -}; - -/** - * Class for a block deletion event. - * @param {Blockly.Block} block The deleted block. Null for a blank event. - * @extends {Blockly.Events.BlockBase} - * @constructor - */ -Blockly.Events.Delete = function(block) { - if (!block) { - return; // Blank event to be populated by fromJson. - } - if (block.getParent()) { - throw 'Connected blocks cannot be deleted.'; - } - Blockly.Events.Delete.superClass_.constructor.call(this, block); - - if (block.workspace.rendered) { - this.oldXml = Blockly.Xml.blockToDomWithXY(block); - } else { - this.oldXml = Blockly.Xml.blockToDom(block); - } - this.ids = Blockly.Events.getDescendantIds_(block); -}; -goog.inherits(Blockly.Events.Delete, Blockly.Events.BlockBase); - -/** - * Class for a block deletion event. - * @param {Blockly.Block} block The deleted block. Null for a blank event. - * @extends {Blockly.Events.BlockBase} - * @constructor - */ -Blockly.Events.BlockDelete = Blockly.Events.Delete; - -/** - * Type of this event. - * @type {string} - */ -Blockly.Events.Delete.prototype.type = Blockly.Events.DELETE; - -/** - * Encode the event as JSON. - * @return {!Object} JSON representation. - */ -Blockly.Events.Delete.prototype.toJson = function() { - var json = Blockly.Events.Delete.superClass_.toJson.call(this); - json['ids'] = this.ids; - return json; -}; - -/** - * Decode the JSON event. - * @param {!Object} json JSON representation. - */ -Blockly.Events.Delete.prototype.fromJson = function(json) { - Blockly.Events.Delete.superClass_.fromJson.call(this, json); - this.ids = json['ids']; -}; - -/** - * Run a deletion event. - * @param {boolean} forward True if run forward, false if run backward (undo). - */ -Blockly.Events.Delete.prototype.run = function(forward) { - var workspace = this.getEventWorkspace_(); - if (forward) { - for (var i = 0, id; id = this.ids[i]; i++) { - var block = workspace.getBlockById(id); - if (block) { - block.dispose(false, false); - } else if (id == this.blockId) { - // Only complain about root-level block. - console.warn("Can't delete non-existent block: " + id); - } - } - } else { - var xml = goog.dom.createDom('xml'); - xml.appendChild(this.oldXml); - Blockly.Xml.domToWorkspace(xml, workspace); - } -}; - -/** - * Class for a block move event. Created before the move. - * @param {Blockly.Block} block The moved block. Null for a blank event. - * @extends {Blockly.Events.BlockBase} - * @constructor - */ -Blockly.Events.Move = function(block) { - if (!block) { - return; // Blank event to be populated by fromJson. - } - Blockly.Events.Move.superClass_.constructor.call(this, block); - var location = this.currentLocation_(); - this.oldParentId = location.parentId; - this.oldInputName = location.inputName; - this.oldCoordinate = location.coordinate; -}; -goog.inherits(Blockly.Events.Move, Blockly.Events.BlockBase); - -/** - * Class for a block move event. Created before the move. - * @param {Blockly.Block} block The moved block. Null for a blank event. - * @extends {Blockly.Events.BlockBase} - * @constructor - */ -Blockly.Events.BlockMove = Blockly.Events.Move; - -/** - * Type of this event. - * @type {string} - */ -Blockly.Events.Move.prototype.type = Blockly.Events.MOVE; - -/** - * Encode the event as JSON. - * @return {!Object} JSON representation. - */ -Blockly.Events.Move.prototype.toJson = function() { - var json = Blockly.Events.Move.superClass_.toJson.call(this); - if (this.newParentId) { - json['newParentId'] = this.newParentId; - } - if (this.newInputName) { - json['newInputName'] = this.newInputName; - } - if (this.newCoordinate) { - json['newCoordinate'] = Math.round(this.newCoordinate.x) + ',' + - Math.round(this.newCoordinate.y); - } - return json; -}; - -/** - * Decode the JSON event. - * @param {!Object} json JSON representation. - */ -Blockly.Events.Move.prototype.fromJson = function(json) { - Blockly.Events.Move.superClass_.fromJson.call(this, json); - this.newParentId = json['newParentId']; - this.newInputName = json['newInputName']; - if (json['newCoordinate']) { - var xy = json['newCoordinate'].split(','); - this.newCoordinate = - new goog.math.Coordinate(parseFloat(xy[0]), parseFloat(xy[1])); - } -}; - -/** - * Record the block's new location. Called after the move. - */ -Blockly.Events.Move.prototype.recordNew = function() { - var location = this.currentLocation_(); - this.newParentId = location.parentId; - this.newInputName = location.inputName; - this.newCoordinate = location.coordinate; -}; - -/** - * Returns the parentId and input if the block is connected, - * or the XY location if disconnected. - * @return {!Object} Collection of location info. - * @private - */ -Blockly.Events.Move.prototype.currentLocation_ = function() { - var workspace = Blockly.Workspace.getById(this.workspaceId); - var block = workspace.getBlockById(this.blockId); - var location = {}; - var parent = block.getParent(); - if (parent) { - location.parentId = parent.id; - var input = parent.getInputWithBlock(block); - if (input) { - location.inputName = input.name; - } - } else { - var blockXY = block.getRelativeToSurfaceXY(); - // The X position in the block move event should be the language agnostic - // position of the block. I.e. it should not be different in LTR vs. RTL. - var rtlAwareX = workspace.RTL ? workspace.getWidth() - blockXY.x : blockXY.x; - location.coordinate = new goog.math.Coordinate(rtlAwareX, blockXY.y); - } - return location; -}; - -/** - * Does this event record any change of state? - * @return {boolean} False if something changed. - */ -Blockly.Events.Move.prototype.isNull = function() { - return this.oldParentId == this.newParentId && - this.oldInputName == this.newInputName && - goog.math.Coordinate.equals(this.oldCoordinate, this.newCoordinate); -}; - -/** - * Run a move event. - * @param {boolean} forward True if run forward, false if run backward (undo). - */ -Blockly.Events.Move.prototype.run = function(forward) { - var workspace = this.getEventWorkspace_(); - var block = workspace.getBlockById(this.blockId); - if (!block) { - console.warn("Can't move non-existent block: " + this.blockId); - return; - } - var parentId = forward ? this.newParentId : this.oldParentId; - var inputName = forward ? this.newInputName : this.oldInputName; - var coordinate = forward ? this.newCoordinate : this.oldCoordinate; - var parentBlock = null; - if (parentId) { - parentBlock = workspace.getBlockById(parentId); - if (!parentBlock) { - console.warn("Can't connect to non-existent block: " + parentId); - return; - } - } - if (block.getParent()) { - block.unplug(); - } - if (coordinate) { - var xy = block.getRelativeToSurfaceXY(); - var rtlAwareX = workspace.RTL ? workspace.getWidth() - coordinate.x : coordinate.x; - block.moveBy(rtlAwareX - xy.x, coordinate.y - xy.y); - } else { - var blockConnection = block.outputConnection || block.previousConnection; - var parentConnection; - if (inputName) { - var input = parentBlock.getInput(inputName); - if (input) { - parentConnection = input.connection; - } - } else if (blockConnection.type == Blockly.PREVIOUS_STATEMENT) { - parentConnection = parentBlock.nextConnection; - } - if (parentConnection) { - blockConnection.connect(parentConnection); - } else { - console.warn("Can't connect to non-existent input: " + inputName); - } - } -}; diff --git a/core/block_render_svg_horizontal.js b/core/block_render_svg_horizontal.js deleted file mode 100644 index c1c4ecce3f..0000000000 --- a/core/block_render_svg_horizontal.js +++ /dev/null @@ -1,890 +0,0 @@ -/** - * @license - * Visual Blocks Editor - * - * Copyright 2012 Google Inc. - * https://developers.google.com/blockly/ - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @fileoverview Methods for graphically rendering a block as SVG. - * @author fraser@google.com (Neil Fraser) - */ -'use strict'; - -goog.provide('Blockly.BlockSvg.render'); - -goog.require('Blockly.BlockSvg'); - - -// UI constants for rendering blocks. -/** -* Grid unit to pixels conversion -* @const -*/ -Blockly.BlockSvg.GRID_UNIT = 4; - -/** - * Horizontal space between elements. - * @const - */ -Blockly.BlockSvg.SEP_SPACE_X = 3 * Blockly.BlockSvg.GRID_UNIT; - -/** - * Vertical space between elements. - * @const - */ -Blockly.BlockSvg.SEP_SPACE_Y = 3 * Blockly.BlockSvg.GRID_UNIT; - -/** - * Vertical space above blocks with statements. - * @const - */ -Blockly.BlockSvg.STATEMENT_BLOCK_SPACE = 3 * Blockly.BlockSvg.GRID_UNIT; - -/** - * Height of user inputs - * @const - */ -Blockly.BlockSvg.FIELD_HEIGHT = 8 * Blockly.BlockSvg.GRID_UNIT; - -/** - * Width of user inputs - * @const - */ -Blockly.BlockSvg.FIELD_WIDTH = 12 * Blockly.BlockSvg.GRID_UNIT; - -/** - * Editable field padding (left/right of the text). - * @const - */ -Blockly.BlockSvg.EDITABLE_FIELD_PADDING = 0; - -/** - * Minimum width of user inputs during editing - * @const - */ -Blockly.BlockSvg.FIELD_WIDTH_MIN_EDIT = 13 * Blockly.BlockSvg.GRID_UNIT; - -/** - * Maximum width of user inputs during editing - * @const - */ -Blockly.BlockSvg.FIELD_WIDTH_MAX_EDIT = 24 * Blockly.BlockSvg.GRID_UNIT; - -/** - * Maximum height of user inputs during editing - * @const - */ -Blockly.BlockSvg.FIELD_HEIGHT_MAX_EDIT = 10 * Blockly.BlockSvg.GRID_UNIT; - -/** - * Top padding of user inputs - * @const - */ -Blockly.BlockSvg.FIELD_TOP_PADDING = 0.25 * Blockly.BlockSvg.GRID_UNIT; - -/** - * Corner radius of number inputs - * @const - */ -Blockly.BlockSvg.NUMBER_FIELD_CORNER_RADIUS = 4 * Blockly.BlockSvg.GRID_UNIT; - -/** - * Corner radius of text inputs - * @const - */ -Blockly.BlockSvg.TEXT_FIELD_CORNER_RADIUS = 1 * Blockly.BlockSvg.GRID_UNIT; - -/** - * Default radius for a field, in px. - * @const - */ -Blockly.BlockSvg.FIELD_DEFAULT_CORNER_RADIUS = 4 * Blockly.BlockSvg.GRID_UNIT; - -/** - * Minimum width of a block. - * @const - */ -Blockly.BlockSvg.MIN_BLOCK_X = 1 / 2 * 16 * Blockly.BlockSvg.GRID_UNIT; - -/** - * Minimum height of a block. - * @const - */ -Blockly.BlockSvg.MIN_BLOCK_Y = 16 * Blockly.BlockSvg.GRID_UNIT; - -/** - * Width of horizontal puzzle tab. - * @const - */ -Blockly.BlockSvg.TAB_WIDTH = 2 * Blockly.BlockSvg.GRID_UNIT; - -/** - * Rounded corner radius. - * @const - */ -Blockly.BlockSvg.CORNER_RADIUS = 1 * Blockly.BlockSvg.GRID_UNIT; - -/** - * Rounded corner radius. - * @const - */ -Blockly.BlockSvg.HAT_CORNER_RADIUS = 8 * Blockly.BlockSvg.GRID_UNIT; - -/** - * Full height of connector notch including rounded corner. - * @const - */ -Blockly.BlockSvg.NOTCH_HEIGHT = 8 * Blockly.BlockSvg.GRID_UNIT + 2; - -/** - * Width of connector notch - * @const - */ -Blockly.BlockSvg.NOTCH_WIDTH = 2 * Blockly.BlockSvg.GRID_UNIT; - -/** - * SVG path for drawing next/previous notch from top to bottom. - * Drawn in pixel units since Bezier control points are off the grid. - * @const - */ -Blockly.BlockSvg.NOTCH_PATH_DOWN = - 'c 0,2 1,3 2,4 ' + - 'l 4,4 ' + - 'c 1,1 2,2 2,4 ' + - 'v 12 ' + - 'c 0,2 -1,3 -2,4 ' + - 'l -4,4 ' + - 'c -1,1 -2,2 -2,4'; - -/** - * SVG path for drawing next/previous notch from bottom to top. - * Drawn in pixel units since Bezier control points are off the grid. - * @const - */ -Blockly.BlockSvg.NOTCH_PATH_UP = - 'c 0,-2 1,-3 2,-4 ' + - 'l 4,-4 ' + - 'c 1,-1 2,-2 2,-4 ' + - 'v -12 ' + - 'c 0,-2 -1,-3 -2,-4 ' + - 'l -4,-4 ' + - 'c -1,-1 -2,-2 -2,-4'; - -/** -* Width of rendered image field in px -* @const -*/ -Blockly.BlockSvg.IMAGE_FIELD_WIDTH = 10 * Blockly.BlockSvg.GRID_UNIT; - -/** -* Height of rendered image field in px -* @const -*/ -Blockly.BlockSvg.IMAGE_FIELD_HEIGHT = 10 * Blockly.BlockSvg.GRID_UNIT; - -/** -* y-offset of the top of the field shadow block from the bottom of the block. -* @const -*/ -Blockly.BlockSvg.FIELD_Y_OFFSET = -2 * Blockly.BlockSvg.GRID_UNIT; - -/** - * SVG start point for drawing the top-left corner. - * @const - */ -Blockly.BlockSvg.TOP_LEFT_CORNER_START = - 'm ' + Blockly.BlockSvg.CORNER_RADIUS + ',0'; - -/** - * SVG path for drawing the rounded top-left corner. - * @const - */ -Blockly.BlockSvg.TOP_LEFT_CORNER = - 'A ' + Blockly.BlockSvg.CORNER_RADIUS + ',' + - Blockly.BlockSvg.CORNER_RADIUS + ' 0 0,0 ' + - '0,' + Blockly.BlockSvg.CORNER_RADIUS; - -/** - * SVG start point for drawing the top-left corner. - * @const - */ -Blockly.BlockSvg.HAT_TOP_LEFT_CORNER_START = - 'm ' + Blockly.BlockSvg.HAT_CORNER_RADIUS + ',0'; -/** - * SVG path for drawing the rounded top-left corner. - * @const - */ -Blockly.BlockSvg.HAT_TOP_LEFT_CORNER = - 'A ' + Blockly.BlockSvg.HAT_CORNER_RADIUS + ',' + - Blockly.BlockSvg.HAT_CORNER_RADIUS + ' 0 0,0 ' + - '0,' + Blockly.BlockSvg.HAT_CORNER_RADIUS; - -/** - * @type {Object} An object containing computed measurements of this block. - * @private - */ -Blockly.BlockSvg.renderingMetrics_ = null; - -/** - * Max text display length for a field (per-horizontal/vertical) - * @const - */ -Blockly.BlockSvg.MAX_DISPLAY_LENGTH = 4; - -/** - * Point size of text field before animation. Must match size in CSS. - * See implementation in field_textinput. - */ -Blockly.BlockSvg.FIELD_TEXTINPUT_FONTSIZE_INITIAL = 12; - -/** - * Point size of text field after animation. - * See implementation in field_textinput. - */ -Blockly.BlockSvg.FIELD_TEXTINPUT_FONTSIZE_FINAL = 14; - -/** - * Whether text fields are allowed to expand past their truncated block size. - * @const{boolean} - */ -Blockly.BlockSvg.FIELD_TEXTINPUT_EXPAND_PAST_TRUNCATION = true; - -/** - * Whether text fields should animate their positioning. - * @const{boolean} - */ -Blockly.BlockSvg.FIELD_TEXTINPUT_ANIMATE_POSITIONING = true; - -/** - * @param {!Object} first An object containing computed measurements of a - * block. - * @param {!Object} second Another object containing computed measurements of a - * block. - * @return {boolean} Whether the two sets of metrics are equivalent. - * @private - */ -Blockly.BlockSvg.metricsAreEquivalent_ = function(first, second) { - if (first.statement != second.statement) { - return false; - } - if (first.imageField != second.imageField) { - return false; - } - - if ((first.height != second.height) || - (first.width != second.width) || - (first.bayHeight != second.bayHeight) || - (first.bayWidth != second.bayWidth) || - (first.fieldRadius != second.fieldRadius) || - (first.startHat != second.startHat)) { - return false; - } - return true; -}; - -/** - * Play some UI effects (sound) after a connection has been established. - */ -Blockly.BlockSvg.prototype.connectionUiEffect = function() { - this.workspace.getAudioManager().play('click'); -}; - -/** - * Change the colour of a block. - */ -Blockly.BlockSvg.prototype.updateColour = function() { - var fillColour = (this.isGlowing_) ? this.getColourSecondary() : this.getColour(); - var strokeColour = this.getColourTertiary(); - - // Render block stroke - this.svgPath_.setAttribute('stroke', strokeColour); - - // Render block fill - var fillColour = (this.isGlowingBlock_) ? this.getColourSecondary() : this.getColour(); - this.svgPath_.setAttribute('fill', fillColour); - - // Render opacity - this.svgPath_.setAttribute('fill-opacity', this.getOpacity()); - - // Bump every dropdown to change its colour. - for (var x = 0, input; input = this.inputList[x]; x++) { - for (var y = 0, field; field = input.fieldRow[y]; y++) { - field.setText(null); - } - } -}; - -/** - * Visual effect to show that if the dragging block is dropped, this block will - * be replaced. If a shadow block it will disappear. Otherwise it will bump. - * @param {boolean} add True if highlighting should be added. - */ -Blockly.BlockSvg.prototype.highlightForReplacement = function(add) { - if (add) { - var replacementGlowFilterId = this.workspace.options.replacementGlowFilterId - || 'blocklyReplacementGlowFilter'; - this.svgPath_.setAttribute('filter', 'url(#' + replacementGlowFilterId + ')'); - Blockly.utils.addClass(/** @type {!Element} */ (this.svgGroup_), - 'blocklyReplaceable'); - } else { - this.svgPath_.removeAttribute('filter'); - Blockly.utils.removeClass(/** @type {!Element} */ (this.svgGroup_), - 'blocklyReplaceable'); - } -}; - -/** - * Returns a bounding box describing the dimensions of this block - * and any blocks stacked below it. - * @param {boolean=} opt_ignoreFields True if we should ignore fields in the - * size calculation, and just give the size of the base block(s). - * @return {!{height: number, width: number}} Object with height and width properties. - */ -Blockly.BlockSvg.prototype.getHeightWidth = function(opt_ignoreFields) { - var height = this.height; - var width = this.width; - // Add the size of the field shadow block. - if (!opt_ignoreFields && this.getFieldShadowBlock_()) { - height += Blockly.BlockSvg.FIELD_Y_OFFSET; - height += Blockly.BlockSvg.FIELD_HEIGHT; - } - // Recursively add size of subsequent blocks. - var nextBlock = this.getNextBlock(); - if (nextBlock) { - var nextHeightWidth = nextBlock.getHeightWidth(opt_ignoreFields); - width += nextHeightWidth.width; - width -= Blockly.BlockSvg.NOTCH_WIDTH; // Exclude width of connected notch. - height = Math.max(height, nextHeightWidth.height); - } - return {height: height, width: width}; -}; - -/** - * Render the block. - * Lays out and reflows a block based on its contents and settings. - * @param {boolean=} opt_bubble If false, just render this block. - * If true, also render block's parent, grandparent, etc. Defaults to true. - */ -Blockly.BlockSvg.prototype.render = function(opt_bubble) { - Blockly.Field.startCache(); - this.rendered = true; - - var oldMetrics = this.renderingMetrics_; - var metrics = this.renderCompute_(); - - // Don't redraw if we don't need to. - if (oldMetrics && - Blockly.BlockSvg.metricsAreEquivalent_(oldMetrics, metrics)) { - // Skipping the redraw is fine, but we may still have to tighten up our - // connections with child blocks. - if (metrics.statement && metrics.statement.connection && - metrics.statement.targetConnection) { - metrics.statement.connection.tighten_(); - } - if (this.nextConnection && this.nextConnection.targetConnection) { - this.nextConnection.tighten_(); - } - } else { - this.height = metrics.height; - this.width = metrics.width; - this.renderDraw_(metrics); - this.renderClassify_(metrics); - this.renderingMetrics_ = metrics; - } - - if (opt_bubble !== false) { - // Render all blocks above this one (propagate a reflow). - var parentBlock = this.getParent(); - if (parentBlock) { - parentBlock.render(true); - } else { - // Top-most block. Fire an event to allow scrollbars to resize. - Blockly.resizeSvgContents(this.workspace); - } - } - Blockly.Field.stopCache(); -}; - -/** - * Computes the height and widths for each row and field. - * @return {!Array.>} 2D array of objects, each containing - * position information. - * @private - */ -Blockly.BlockSvg.prototype.renderCompute_ = function() { - var metrics = { - statement: null, - imageField: null, - iconMenu: null, - width: 0, - height: 0, - bayHeight: 0, - bayWidth: 0, - bayNotchAtRight: true, - fieldRadius: 0, - startHat: false, - endCap: false - }; - - // Does block have a statement? - for (var i = 0, input; input = this.inputList[i]; i++) { - if (input.type == Blockly.NEXT_STATEMENT) { - metrics.statement = input; - // Compute minimum input size. - metrics.bayHeight = Blockly.BlockSvg.MIN_BLOCK_Y; - metrics.bayWidth = Blockly.BlockSvg.MIN_BLOCK_X; - // Expand input size if there is a connection. - if (input.connection && input.connection.targetConnection) { - var linkedBlock = input.connection.targetBlock(); - var bBox = linkedBlock.getHeightWidth(true); - metrics.bayHeight = Math.max(metrics.bayHeight, bBox.height); - metrics.bayWidth = Math.max(metrics.bayWidth, bBox.width); - } - var linkedBlock = input.connection.targetBlock(); - if (linkedBlock && !linkedBlock.lastConnectionInStack()) { - metrics.bayNotchAtRight = false; - } else { - metrics.bayWidth -= Blockly.BlockSvg.NOTCH_WIDTH; - } - } - - // Find image field, input fields - for (var j = 0, field; field = input.fieldRow[j]; j++) { - if (field instanceof Blockly.FieldImage) { - metrics.imageField = field; - } - if (field instanceof Blockly.FieldIconMenu) { - metrics.iconMenu = field; - } - if (field instanceof Blockly.FieldTextInput) { - metrics.fieldRadius = field.getBorderRadius(); - } else { - metrics.fieldRadius = Blockly.BlockSvg.FIELD_DEFAULT_CORNER_RADIUS; - } - } - } - - // Determine whether a block is a start hat or end cap by checking connections. - if (this.nextConnection && !this.previousConnection) { - metrics.startHat = true; - } - - // End caps have no bay, a previous, no output, and no next. - if (!this.nextConnection && this.previousConnection && - !this.outputConnection && !metrics.statement) { - metrics.endCap = true; - } - - // If this block is an icon menu shadow, attempt to set the parent's - // ImageField src to the one that represents the current value of the field. - if (metrics.iconMenu) { - var currentSrc = metrics.iconMenu.getSrcForValue(metrics.iconMenu.getValue()); - if (currentSrc) { - metrics.iconMenu.setParentFieldImage(currentSrc); - } - } - - // Always render image field at 40x40 px - // Normal block sizing - metrics.width = Blockly.BlockSvg.SEP_SPACE_X * 2 + Blockly.BlockSvg.IMAGE_FIELD_WIDTH; - metrics.height = Blockly.BlockSvg.SEP_SPACE_Y * 2 + Blockly.BlockSvg.IMAGE_FIELD_HEIGHT; - - if (this.outputConnection) { - // Field shadow block - metrics.height = Blockly.BlockSvg.FIELD_HEIGHT; - metrics.width = Blockly.BlockSvg.FIELD_WIDTH; - } - if (metrics.statement) { - // Block with statement (e.g., repeat, forever) - metrics.width += metrics.bayWidth + 4 * Blockly.BlockSvg.CORNER_RADIUS + 2 * Blockly.BlockSvg.GRID_UNIT; - metrics.height = metrics.bayHeight + Blockly.BlockSvg.STATEMENT_BLOCK_SPACE; - } - if (metrics.startHat) { - // Start hats are 1 unit wider to account for optical effect of curve. - metrics.width += 1 * Blockly.BlockSvg.GRID_UNIT; - } - if (metrics.endCap) { - // End caps are 1 unit wider to account for optical effect of no notch. - metrics.width += 1 * Blockly.BlockSvg.GRID_UNIT; - } - return metrics; -}; - - -/** - * Draw the path of the block. - * Move the fields to the correct locations. - * @param {!Object} metrics An object containing computed measurements of the - * block. - * @private - */ -Blockly.BlockSvg.prototype.renderDraw_ = function(metrics) { - // Fetch the block's coordinates on the surface for use in anchoring - // the connections. - var connectionsXY = this.getRelativeToSurfaceXY(); - // Assemble the block's path. - var steps = []; - - this.renderDrawLeft_(steps, connectionsXY, metrics); - this.renderDrawBottom_(steps, connectionsXY, metrics); - this.renderDrawRight_(steps, connectionsXY, metrics); - this.renderDrawTop_(steps, connectionsXY, metrics); - - var pathString = steps.join(' '); - this.svgPath_.setAttribute('d', pathString); - - if (this.RTL) { - // Mirror the block's path. - // This is awesome. - this.svgPath_.setAttribute('transform', 'scale(-1 1)'); - } - - // Horizontal blocks have a single Image Field that is specially positioned - if (metrics.imageField) { - var imageField = metrics.imageField.getSvgRoot(); - var imageFieldSize = metrics.imageField.getSize(); - // Image field's position is calculated relative to the "end" edge of the - // block. - var imageFieldX = metrics.width - imageFieldSize.width - - Blockly.BlockSvg.SEP_SPACE_X / 1.5; - var imageFieldY = metrics.height - imageFieldSize.height - - Blockly.BlockSvg.SEP_SPACE_Y; - if (metrics.endCap) { - // End-cap image is offset by a grid unit to account for optical effect of no notch. - imageFieldX -= Blockly.BlockSvg.GRID_UNIT; - } - var imageFieldScale = "scale(1 1)"; - if (this.RTL) { - // Do we want to mirror the Image Field left-to-right? - if (metrics.imageField.getFlipRTL()) { - imageFieldScale = "scale(-1 1)"; - imageFieldX = -metrics.width + imageFieldSize.width + - Blockly.BlockSvg.SEP_SPACE_X / 1.5; - } else { - // If not, don't offset by imageFieldSize.width - imageFieldX = -metrics.width + Blockly.BlockSvg.SEP_SPACE_X / 1.5; - } - } - if (imageField) { - // Fields are invisible on insertion marker. - if (this.isInsertionMarker()) { - imageField.setAttribute('display', 'none'); - } - imageField.setAttribute('transform', - 'translate(' + imageFieldX + ',' + imageFieldY + ') ' + - imageFieldScale); - } - } - - // Position value input - if (this.getFieldShadowBlock_()) { - var input = this.getFieldShadowBlock_().getSvgRoot(); - var valueX = (Blockly.BlockSvg.NOTCH_WIDTH + - (metrics.bayWidth ? 2 * Blockly.BlockSvg.GRID_UNIT + - Blockly.BlockSvg.NOTCH_WIDTH * 2 : 0) + metrics.bayWidth); - if (metrics.startHat) { - // Start hats add some left margin to field for visual balance - valueX += Blockly.BlockSvg.GRID_UNIT * 2; - } - if (this.RTL) { - valueX = -valueX; - } - var valueY = (metrics.height + Blockly.BlockSvg.FIELD_Y_OFFSET); - var transformation = 'translate(' + valueX + ',' + valueY + ')'; - input.setAttribute('transform', transformation); - } -}; - -/** - * Give the block an attribute 'data-shapes' that lists its shape[s], and an - * attribute 'data-category' with its category. - * @param {!Object} metrics An object containing computed measurements of the - * block. - * @private - */ -Blockly.BlockSvg.prototype.renderClassify_ = function(metrics) { - var shapes = []; - - if (this.isShadow_) { - shapes.push('argument'); - } else { - if(metrics.statement) { - shapes.push('c-block'); - } - if (metrics.startHat) { - shapes.push('hat'); // c-block+hats are possible (e.x. reprter procedures) - } else if (!metrics.statement) { - shapes.push('stack'); //only call it "stack" if it's not a c-block - } - if (!this.nextConnection) { - shapes.push('end'); - } - } - - this.svgGroup_.setAttribute('data-shapes', shapes.join(' ')); - - if (this.getCategory()) { - this.svgGroup_.setAttribute('data-category', this.getCategory()); - } -}; - -/** - * Render the left edge of the block. - * @param {!Array.} steps Path of block outline. - * @param {!Object} connectionsXY Location of block. - * @param {!Object} metrics An object containing computed measurements of the - * block. - * @private - */ -Blockly.BlockSvg.prototype.renderDrawLeft_ = function(steps, connectionsXY, metrics) { - // Top edge. - if (metrics.startHat) { - // Hat block - // Position the cursor at the top-left starting point. - steps.push(Blockly.BlockSvg.HAT_TOP_LEFT_CORNER_START); - // Top-left rounded corner. - steps.push(Blockly.BlockSvg.HAT_TOP_LEFT_CORNER); - } else if (this.previousConnection) { - // Regular block - // Position the cursor at the top-left starting point. - steps.push(Blockly.BlockSvg.TOP_LEFT_CORNER_START); - // Top-left rounded corner. - steps.push(Blockly.BlockSvg.TOP_LEFT_CORNER); - var cursorY = metrics.height - Blockly.BlockSvg.CORNER_RADIUS - - Blockly.BlockSvg.SEP_SPACE_Y - Blockly.BlockSvg.NOTCH_HEIGHT; - steps.push('V', cursorY); - steps.push(Blockly.BlockSvg.NOTCH_PATH_DOWN); - // Create previous block connection. - var connectionX = connectionsXY.x; - var connectionY = connectionsXY.y + metrics.height - - Blockly.BlockSvg.CORNER_RADIUS * 2; - this.previousConnection.moveTo(connectionX, connectionY); - // This connection will be tightened when the parent renders. - steps.push('V', metrics.height - Blockly.BlockSvg.CORNER_RADIUS); - } else { - // Input - // Position the cursor at the top-left starting point. - steps.push('m', metrics.fieldRadius + ',0'); - // Top-left rounded corner. - steps.push( - 'A', metrics.fieldRadius + ',' + metrics.fieldRadius, - '0', '0,0', '0,' + metrics.fieldRadius); - steps.push( - 'V', metrics.height - metrics.fieldRadius); - } -}; - -/** - * Render the bottom edge of the block. - * @param {!Array.} steps Path of block outline. - * @param {!Object} connectionsXY Location of block. - * @param {!Object} metrics An object containing computed measurements of the - * block. - * @private - */ -Blockly.BlockSvg.prototype.renderDrawBottom_ = function(steps, - connectionsXY, metrics) { - - if (metrics.startHat) { - steps.push('a', Blockly.BlockSvg.HAT_CORNER_RADIUS + ',' + - Blockly.BlockSvg.HAT_CORNER_RADIUS + ' 0 0,0 ' + - Blockly.BlockSvg.HAT_CORNER_RADIUS + ',' + - Blockly.BlockSvg.HAT_CORNER_RADIUS); - } else if (this.previousConnection) { - steps.push('a', Blockly.BlockSvg.CORNER_RADIUS + ',' + - Blockly.BlockSvg.CORNER_RADIUS + ' 0 0,0 ' + - Blockly.BlockSvg.CORNER_RADIUS + ',' + - Blockly.BlockSvg.CORNER_RADIUS); - } else { - // Input - steps.push( - 'a', metrics.fieldRadius + ',' + metrics.fieldRadius, - '0', '0,0', metrics.fieldRadius + ',' + metrics.fieldRadius); - } - - // Has statement - if (metrics.statement) { - steps.push('h', 4 * Blockly.BlockSvg.GRID_UNIT); - steps.push('a', Blockly.BlockSvg.CORNER_RADIUS + ',' + - Blockly.BlockSvg.CORNER_RADIUS + ' 0 0,0 ' + - Blockly.BlockSvg.CORNER_RADIUS + ',-' + - Blockly.BlockSvg.CORNER_RADIUS); - steps.push('v', -2.5 * Blockly.BlockSvg.GRID_UNIT); - steps.push(Blockly.BlockSvg.NOTCH_PATH_UP); - // @todo Why 3? - steps.push('v', -metrics.bayHeight + (Blockly.BlockSvg.CORNER_RADIUS * 3) + - Blockly.BlockSvg.NOTCH_HEIGHT + 2 * Blockly.BlockSvg.GRID_UNIT); - steps.push('a', Blockly.BlockSvg.CORNER_RADIUS + ',' + - Blockly.BlockSvg.CORNER_RADIUS + ' 0 0,1 ' + - Blockly.BlockSvg.CORNER_RADIUS + ',-' + - Blockly.BlockSvg.CORNER_RADIUS); - steps.push('h', metrics.bayWidth - (Blockly.BlockSvg.CORNER_RADIUS * 2)); - steps.push('a', Blockly.BlockSvg.CORNER_RADIUS + ',' + - Blockly.BlockSvg.CORNER_RADIUS + ' 0 0,1 ' + - Blockly.BlockSvg.CORNER_RADIUS + ',' + - Blockly.BlockSvg.CORNER_RADIUS); - if (metrics.bayNotchAtRight) { - steps.push('v', metrics.bayHeight - (Blockly.BlockSvg.CORNER_RADIUS * 3) - - Blockly.BlockSvg.NOTCH_HEIGHT - 2 * Blockly.BlockSvg.GRID_UNIT); - steps.push(Blockly.BlockSvg.NOTCH_PATH_DOWN); - } - steps.push('V', metrics.bayHeight + 2 * Blockly.BlockSvg.GRID_UNIT); - steps.push('a', Blockly.BlockSvg.CORNER_RADIUS + ',' + - Blockly.BlockSvg.CORNER_RADIUS + ' 0 0,0 ' + - Blockly.BlockSvg.CORNER_RADIUS + ',' + - Blockly.BlockSvg.CORNER_RADIUS); - - // Create statement connection. - var connectionX = connectionsXY.x + Blockly.BlockSvg.CORNER_RADIUS * 2 + - 4 * Blockly.BlockSvg.GRID_UNIT; - if (this.RTL) { - connectionX = connectionsXY.x - Blockly.BlockSvg.CORNER_RADIUS * 2 - - 4 * Blockly.BlockSvg.GRID_UNIT; - } - var connectionY = connectionsXY.y + metrics.height - - Blockly.BlockSvg.CORNER_RADIUS * 2; - metrics.statement.connection.moveTo(connectionX, connectionY); - if (metrics.statement.connection.targetConnection) { - metrics.statement.connection.tighten_(); - } - } - - if (!this.isShadow()) { - steps.push('H', metrics.width - Blockly.BlockSvg.CORNER_RADIUS); - } else { - // input - steps.push('H', metrics.width - metrics.fieldRadius); - } -}; - -/** - * Render the right edge of the block. - * @param {!Array.} steps Path of block outline. - * @param {!Object} connectionsXY Location of block. - * @param {!Object} metrics An object containing computed measurements of the - * block. - * @private - */ -Blockly.BlockSvg.prototype.renderDrawRight_ = function(steps, connectionsXY, metrics) { - if (!this.isShadow()) { - steps.push('a', Blockly.BlockSvg.CORNER_RADIUS + ',' + - Blockly.BlockSvg.CORNER_RADIUS + ' 0 0,0 ' + - Blockly.BlockSvg.CORNER_RADIUS + ',-' + - Blockly.BlockSvg.CORNER_RADIUS); - steps.push('v', -2.5 * Blockly.BlockSvg.GRID_UNIT); - } else { - // Input - steps.push( - 'a', metrics.fieldRadius + ',' + metrics.fieldRadius, - '0', '0,0', metrics.fieldRadius + ',' + -1 * metrics.fieldRadius); - steps.push('v', -1 * (metrics.height - metrics.fieldRadius * 2)); - } - - if (this.nextConnection) { - steps.push(Blockly.BlockSvg.NOTCH_PATH_UP); - - // Include width of notch in block width. - this.width += Blockly.BlockSvg.NOTCH_WIDTH; - - // Create next block connection. - var connectionX; - if (this.RTL) { - connectionX = connectionsXY.x - metrics.width; - } else { - connectionX = connectionsXY.x + metrics.width; - } - var connectionY = connectionsXY.y + metrics.height - - Blockly.BlockSvg.CORNER_RADIUS * 2; - this.nextConnection.moveTo(connectionX, connectionY); - if (this.nextConnection.targetConnection) { - this.nextConnection.tighten_(); - } - steps.push('V', Blockly.BlockSvg.CORNER_RADIUS); - } else if (!this.isShadow()) { - steps.push('V', Blockly.BlockSvg.CORNER_RADIUS); - } -}; - -/** - * Render the top edge of the block. - * @param {!Array.} steps Path of block outline. - * @param {!Object} connectionsXY Location of block. - * @param {!Object} metrics An object containing computed measurements of the - * block. - * @private - */ -Blockly.BlockSvg.prototype.renderDrawTop_ = function(steps, connectionsXY, metrics) { - if (!this.isShadow()) { - steps.push('a', Blockly.BlockSvg.CORNER_RADIUS + ',' + - Blockly.BlockSvg.CORNER_RADIUS + ' 0 0,0 -' + - Blockly.BlockSvg.CORNER_RADIUS + ',-' + - Blockly.BlockSvg.CORNER_RADIUS); - } else { - steps.push( - 'a', metrics.fieldRadius + ',' + metrics.fieldRadius, - '0', '0,0', '-' + metrics.fieldRadius + ',-' + metrics.fieldRadius); - } - steps.push('z'); -}; - -/** - * Get the field shadow block, if this block has one. - *

This is horizontal Scratch-specific, as "fields" are implemented as inputs - * with shadow blocks, and there is only one per block. - * @return {Blockly.BlockSvg} The field shadow block, or null if not found. - * @private - */ -Blockly.BlockSvg.prototype.getFieldShadowBlock_ = function() { - for (var i = 0, child; child = this.childBlocks_[i]; i++) { - if (child.isShadow()) { - return child; - } - } - - return null; -}; - -/** - * Position an new block correctly, so that it doesn't move the existing block - * when connected to it. - * @param {!Blockly.Block} newBlock The block to position - either the first - * block in a dragged stack or an insertion marker. - * @param {!Blockly.Connection} newConnection The connection on the new block's - * stack - either a connection on newBlock, or the last NEXT_STATEMENT - * connection on the stack if the stack's being dropped before another - * block. - * @param {!Blockly.Connection} existingConnection The connection on the - * existing block, which newBlock should line up with. - */ -Blockly.BlockSvg.prototype.positionNewBlock = function(newBlock, newConnection, existingConnection) { - // We only need to position the new block if it's before the existing one, - // otherwise its position is set by the previous block. - if (newConnection.type == Blockly.NEXT_STATEMENT) { - var dx = existingConnection.x_ - newConnection.x_; - var dy = existingConnection.y_ - newConnection.y_; - - // When putting a c-block around another c-block, the outer block must - // positioned above the inner block, as its connection point will stretch - // downwards when connected. - if (newConnection == newBlock.getFirstStatementConnection()) { - dy -= existingConnection.sourceBlock_.getHeightWidth(true).height - - Blockly.BlockSvg.MIN_BLOCK_Y; - } - - newBlock.moveBy(dx, dy); - } -}; diff --git a/core/block_render_svg_vertical.js b/core/block_render_svg_vertical.js deleted file mode 100644 index ca5ea470f3..0000000000 --- a/core/block_render_svg_vertical.js +++ /dev/null @@ -1,1732 +0,0 @@ -/** - * @license - * Visual Blocks Editor - * - * Copyright 2012 Google Inc. - * https://developers.google.com/blockly/ - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @fileoverview Methods for graphically rendering a block as SVG. - * @author fraser@google.com (Neil Fraser) - */ -'use strict'; - -goog.provide('Blockly.BlockSvg.render'); - -goog.require('Blockly.BlockSvg'); -goog.require('Blockly.scratchBlocksUtils'); -goog.require('Blockly.utils'); - - -// UI constants for rendering blocks. -/** -* Grid unit to pixels conversion -* @const -*/ -Blockly.BlockSvg.GRID_UNIT = 4; - -/** - * Horizontal space between elements. - * @const - */ -Blockly.BlockSvg.SEP_SPACE_X = 2 * Blockly.BlockSvg.GRID_UNIT; - -/** - * Vertical space between elements. - * @const - */ -Blockly.BlockSvg.SEP_SPACE_Y = 2 * Blockly.BlockSvg.GRID_UNIT; - -/** - * Minimum width of a block. - * @const - */ -Blockly.BlockSvg.MIN_BLOCK_X = 16 * Blockly.BlockSvg.GRID_UNIT; - -/** - * Minimum width of a block with output (reporters). - * @const - */ -Blockly.BlockSvg.MIN_BLOCK_X_OUTPUT = 12 * Blockly.BlockSvg.GRID_UNIT; - -/** - * Minimum width of a shadow block with output (single fields). - * @const - */ -Blockly.BlockSvg.MIN_BLOCK_X_SHADOW_OUTPUT = 10 * Blockly.BlockSvg.GRID_UNIT; - -/** - * Minimum height of a block. - * @const - */ -Blockly.BlockSvg.MIN_BLOCK_Y = 12 * Blockly.BlockSvg.GRID_UNIT; - -/** - * Height of extra row after a statement input. - * @const - */ -Blockly.BlockSvg.EXTRA_STATEMENT_ROW_Y = 8 * Blockly.BlockSvg.GRID_UNIT; - -/** - * Minimum width of a C- or E-shaped block. - * @const - */ -Blockly.BlockSvg.MIN_BLOCK_X_WITH_STATEMENT = 40 * Blockly.BlockSvg.GRID_UNIT; - -/** - * Minimum height of a shadow block with output and a single field. - * This is used for shadow blocks that only contain a field - which are smaller than even reporters. - * @const - */ -Blockly.BlockSvg.MIN_BLOCK_Y_SINGLE_FIELD_OUTPUT = 8 * Blockly.BlockSvg.GRID_UNIT; - -/** - * Minimum height of a non-shadow block with output, i.e. a reporter. - * @const - */ -Blockly.BlockSvg.MIN_BLOCK_Y_REPORTER = 10 * Blockly.BlockSvg.GRID_UNIT; - -/** - * Minimum space for a statement input height. - * @const - */ -Blockly.BlockSvg.MIN_STATEMENT_INPUT_HEIGHT = 6 * Blockly.BlockSvg.GRID_UNIT; - -/** - * Width of vertical notch. - * @const - */ -Blockly.BlockSvg.NOTCH_WIDTH = 8 * Blockly.BlockSvg.GRID_UNIT; - -/** - * Height of vertical notch. - * @const - */ -Blockly.BlockSvg.NOTCH_HEIGHT = 2 * Blockly.BlockSvg.GRID_UNIT; - -/** - * Rounded corner radius. - * @const - */ -Blockly.BlockSvg.CORNER_RADIUS = 1 * Blockly.BlockSvg.GRID_UNIT; - -/** - * Minimum width of statement input edge on the left, in px. - * @const - */ -Blockly.BlockSvg.STATEMENT_INPUT_EDGE_WIDTH = 4 * Blockly.BlockSvg.GRID_UNIT; - -/** - * Inner space between edge of statement input and notch. - * @const - */ -Blockly.BlockSvg.STATEMENT_INPUT_INNER_SPACE = 2 * Blockly.BlockSvg.GRID_UNIT; - -/** - * Height of the top hat. - * @const - */ -Blockly.BlockSvg.START_HAT_HEIGHT = 16; - -/** - * Height of the vertical separator line for icons that appear at the left edge - * of a block, such as extension icons. - * @const - */ -Blockly.BlockSvg.ICON_SEPARATOR_HEIGHT = 10 * Blockly.BlockSvg.GRID_UNIT; - -/** - * Path of the top hat's curve. - * @const - */ -Blockly.BlockSvg.START_HAT_PATH = 'c 25,-22 71,-22 96,0'; - -/** - * SVG path for drawing next/previous notch from left to right. - * @const - */ -Blockly.BlockSvg.NOTCH_PATH_LEFT = ( - 'c 2,0 3,1 4,2 ' + - 'l 4,4 ' + - 'c 1,1 2,2 4,2 ' + - 'h 12 ' + - 'c 2,0 3,-1 4,-2 ' + - 'l 4,-4 ' + - 'c 1,-1 2,-2 4,-2' -); - -/** - * SVG path for drawing next/previous notch from right to left. - * @const - */ -Blockly.BlockSvg.NOTCH_PATH_RIGHT = ( - 'c -2,0 -3,1 -4,2 ' + - 'l -4,4 ' + - 'c -1,1 -2,2 -4,2 ' + - 'h -12 ' + - 'c -2,0 -3,-1 -4,-2 ' + - 'l -4,-4 ' + - 'c -1,-1 -2,-2 -4,-2' -); - -/** - * Amount of padding before the notch. - * @const - */ -Blockly.BlockSvg.NOTCH_START_PADDING = 3 * Blockly.BlockSvg.GRID_UNIT; - -/** - * SVG start point for drawing the top-left corner. - * @const - */ -Blockly.BlockSvg.TOP_LEFT_CORNER_START = - 'm 0,' + Blockly.BlockSvg.CORNER_RADIUS; - -/** - * SVG path for drawing the rounded top-left corner. - * @const - */ -Blockly.BlockSvg.TOP_LEFT_CORNER = - 'A ' + Blockly.BlockSvg.CORNER_RADIUS + ',' + - Blockly.BlockSvg.CORNER_RADIUS + ' 0 0,1 ' + - Blockly.BlockSvg.CORNER_RADIUS + ',0'; - -/** - * SVG path for drawing the rounded top-right corner. - * @const - */ -Blockly.BlockSvg.TOP_RIGHT_CORNER = - 'a ' + Blockly.BlockSvg.CORNER_RADIUS + ',' + - Blockly.BlockSvg.CORNER_RADIUS + ' 0 0,1 ' + - Blockly.BlockSvg.CORNER_RADIUS + ',' + - Blockly.BlockSvg.CORNER_RADIUS; - -/** - * SVG path for drawing the rounded bottom-right corner. - * @const - */ -Blockly.BlockSvg.BOTTOM_RIGHT_CORNER = - ' a ' + Blockly.BlockSvg.CORNER_RADIUS + ',' + - Blockly.BlockSvg.CORNER_RADIUS + ' 0 0,1 -' + - Blockly.BlockSvg.CORNER_RADIUS + ',' + - Blockly.BlockSvg.CORNER_RADIUS; - -/** - * SVG path for drawing the rounded bottom-left corner. - * @const - */ -Blockly.BlockSvg.BOTTOM_LEFT_CORNER = - 'a ' + Blockly.BlockSvg.CORNER_RADIUS + ',' + - Blockly.BlockSvg.CORNER_RADIUS + ' 0 0,1 -' + - Blockly.BlockSvg.CORNER_RADIUS + ',-' + - Blockly.BlockSvg.CORNER_RADIUS; - -/** - * SVG path for drawing the top-left corner of a statement input. - * @const - */ -Blockly.BlockSvg.INNER_TOP_LEFT_CORNER = - ' a ' + Blockly.BlockSvg.CORNER_RADIUS + ',' + - Blockly.BlockSvg.CORNER_RADIUS + ' 0 0,0 -' + - Blockly.BlockSvg.CORNER_RADIUS + ',' + - Blockly.BlockSvg.CORNER_RADIUS; - -/** - * SVG path for drawing the bottom-left corner of a statement input. - * Includes the rounded inside corner. - * @const - */ -Blockly.BlockSvg.INNER_BOTTOM_LEFT_CORNER = - 'a ' + Blockly.BlockSvg.CORNER_RADIUS + ',' + - Blockly.BlockSvg.CORNER_RADIUS + ' 0 0,0 ' + - Blockly.BlockSvg.CORNER_RADIUS + ',' + - Blockly.BlockSvg.CORNER_RADIUS; - -/** - * SVG path for an empty hexagonal input shape. - * @const - */ -Blockly.BlockSvg.INPUT_SHAPE_HEXAGONAL = - 'M ' + 4 * Blockly.BlockSvg.GRID_UNIT + ',0 ' + - ' h ' + 4 * Blockly.BlockSvg.GRID_UNIT + - ' l ' + 4 * Blockly.BlockSvg.GRID_UNIT + ',' + 4 * Blockly.BlockSvg.GRID_UNIT + - ' l ' + -4 * Blockly.BlockSvg.GRID_UNIT + ',' + 4 * Blockly.BlockSvg.GRID_UNIT + - ' h ' + -4 * Blockly.BlockSvg.GRID_UNIT + - ' l ' + -4 * Blockly.BlockSvg.GRID_UNIT + ',' + -4 * Blockly.BlockSvg.GRID_UNIT + - ' l ' + 4 * Blockly.BlockSvg.GRID_UNIT + ',' + -4 * Blockly.BlockSvg.GRID_UNIT + - ' z'; - -/** - * Width of empty boolean input shape. - * @const - */ -Blockly.BlockSvg.INPUT_SHAPE_HEXAGONAL_WIDTH = 12 * Blockly.BlockSvg.GRID_UNIT; - -/** - * SVG path for an empty square input shape. - * @const - */ -Blockly.BlockSvg.INPUT_SHAPE_SQUARE = - Blockly.BlockSvg.TOP_LEFT_CORNER_START + - Blockly.BlockSvg.TOP_LEFT_CORNER + - ' h ' + (12 * Blockly.BlockSvg.GRID_UNIT - 2 * Blockly.BlockSvg.CORNER_RADIUS) + - Blockly.BlockSvg.TOP_RIGHT_CORNER + - ' v ' + (8 * Blockly.BlockSvg.GRID_UNIT - 2 * Blockly.BlockSvg.CORNER_RADIUS) + - Blockly.BlockSvg.BOTTOM_RIGHT_CORNER + - ' h ' + (-12 * Blockly.BlockSvg.GRID_UNIT + 2 * Blockly.BlockSvg.CORNER_RADIUS) + - Blockly.BlockSvg.BOTTOM_LEFT_CORNER + - ' z'; - -/** - * Width of empty square input shape. - * @const - */ -Blockly.BlockSvg.INPUT_SHAPE_SQUARE_WIDTH = 10 * Blockly.BlockSvg.GRID_UNIT; - -/** - * SVG path for an empty round input shape. - * @const - */ - -Blockly.BlockSvg.INPUT_SHAPE_ROUND = - 'M ' + (4 * Blockly.BlockSvg.GRID_UNIT) + ',0' + - ' h ' + (4 * Blockly.BlockSvg.GRID_UNIT) + - ' a ' + (4 * Blockly.BlockSvg.GRID_UNIT) + ' ' + - (4 * Blockly.BlockSvg.GRID_UNIT) + ' 0 0 1 0 ' + (8 * Blockly.BlockSvg.GRID_UNIT) + - ' h ' + (-4 * Blockly.BlockSvg.GRID_UNIT) + - ' a ' + (4 * Blockly.BlockSvg.GRID_UNIT) + ' ' + - (4 * Blockly.BlockSvg.GRID_UNIT) + ' 0 0 1 0 -' + (8 * Blockly.BlockSvg.GRID_UNIT) + - ' z'; - -/** - * Width of empty round input shape. - * @const - */ -Blockly.BlockSvg.INPUT_SHAPE_ROUND_WIDTH = 12 * Blockly.BlockSvg.GRID_UNIT; - -/** - * Height of empty input shape. - * @const - */ -Blockly.BlockSvg.INPUT_SHAPE_HEIGHT = 8 * Blockly.BlockSvg.GRID_UNIT; - -/** - * Height of user inputs - * @const - */ -Blockly.BlockSvg.FIELD_HEIGHT = 8 * Blockly.BlockSvg.GRID_UNIT; - -/** - * Width of user inputs - * @const - */ -Blockly.BlockSvg.FIELD_WIDTH = 6 * Blockly.BlockSvg.GRID_UNIT; - -/** - * Editable field padding (left/right of the text). - * @const - */ -Blockly.BlockSvg.EDITABLE_FIELD_PADDING = 6; - -/** - * Square box field padding (left/right of the text). - * @const - */ -Blockly.BlockSvg.BOX_FIELD_PADDING = 2 * Blockly.BlockSvg.GRID_UNIT; - -/** - * Drop-down arrow padding. - * @const - */ -Blockly.BlockSvg.DROPDOWN_ARROW_PADDING = 2 * Blockly.BlockSvg.GRID_UNIT; - -/** - * Minimum width of user inputs during editing - * @const - */ -Blockly.BlockSvg.FIELD_WIDTH_MIN_EDIT = 8 * Blockly.BlockSvg.GRID_UNIT; - -/** - * Maximum width of user inputs during editing - * @const - */ -Blockly.BlockSvg.FIELD_WIDTH_MAX_EDIT = Infinity; - -/** - * Maximum height of user inputs during editing - * @const - */ -Blockly.BlockSvg.FIELD_HEIGHT_MAX_EDIT = Blockly.BlockSvg.FIELD_HEIGHT; - -/** - * Top padding of user inputs - * @const - */ -Blockly.BlockSvg.FIELD_TOP_PADDING = 0.5 * Blockly.BlockSvg.GRID_UNIT; - -/** - * Corner radius of number inputs - * @const - */ -Blockly.BlockSvg.NUMBER_FIELD_CORNER_RADIUS = 4 * Blockly.BlockSvg.GRID_UNIT; - -/** - * Corner radius of text inputs - * @const - */ -Blockly.BlockSvg.TEXT_FIELD_CORNER_RADIUS = 1 * Blockly.BlockSvg.GRID_UNIT; - -/** - * Default radius for a field, in px. - * @const - */ -Blockly.BlockSvg.FIELD_DEFAULT_CORNER_RADIUS = 4 * Blockly.BlockSvg.GRID_UNIT; - -/** - * Max text display length for a field (per-horizontal/vertical) - * @const - */ -Blockly.BlockSvg.MAX_DISPLAY_LENGTH = Infinity; - -/** - * Minimum X of inputs and fields for blocks with a previous connection. - * Ensures that inputs will not overlap with the top notch of blocks. - * @const - */ -Blockly.BlockSvg.INPUT_AND_FIELD_MIN_X = 12 * Blockly.BlockSvg.GRID_UNIT; - -/** - * Vertical padding around inline elements. - * @const - */ -Blockly.BlockSvg.INLINE_PADDING_Y = 1 * Blockly.BlockSvg.GRID_UNIT; - -/** - * Point size of text field before animation. Must match size in CSS. - * See implementation in field_textinput. - */ -Blockly.BlockSvg.FIELD_TEXTINPUT_FONTSIZE_INITIAL = 12; - -/** - * Point size of text field after animation. - * See implementation in field_textinput. - */ -Blockly.BlockSvg.FIELD_TEXTINPUT_FONTSIZE_FINAL = 12; - -/** - * Whether text fields are allowed to expand past their truncated block size. - * @const{boolean} - */ -Blockly.BlockSvg.FIELD_TEXTINPUT_EXPAND_PAST_TRUNCATION = false; - -/** - * Whether text fields should animate their positioning. - * @const{boolean} - */ -Blockly.BlockSvg.FIELD_TEXTINPUT_ANIMATE_POSITIONING = false; - -/** - * Map of output/input shapes and the amount they should cause a block to be padded. - * Outer key is the outer shape, inner key is the inner shape. - * When a block with the outer shape contains an input block with the inner shape - * on its left or right edge, that side is extended by the padding specified. - * See also: `Blockly.BlockSvg.computeOutputPadding_`. - */ -Blockly.BlockSvg.SHAPE_IN_SHAPE_PADDING = { - 1: { // Outer shape: hexagon. - 0: 5 * Blockly.BlockSvg.GRID_UNIT, // Field in hexagon. - 1: 2 * Blockly.BlockSvg.GRID_UNIT, // Hexagon in hexagon. - 2: 5 * Blockly.BlockSvg.GRID_UNIT, // Round in hexagon. - 3: 5 * Blockly.BlockSvg.GRID_UNIT // Square in hexagon. - }, - 2: { // Outer shape: round. - 0: 3 * Blockly.BlockSvg.GRID_UNIT, // Field in round. - 1: 3 * Blockly.BlockSvg.GRID_UNIT, // Hexagon in round. - 2: 1 * Blockly.BlockSvg.GRID_UNIT, // Round in round. - 3: 2 * Blockly.BlockSvg.GRID_UNIT // Square in round. - }, - 3: { // Outer shape: square. - 0: 2 * Blockly.BlockSvg.GRID_UNIT, // Field in square. - 1: 2 * Blockly.BlockSvg.GRID_UNIT, // Hexagon in square. - 2: 2 * Blockly.BlockSvg.GRID_UNIT, // Round in square. - 3: 2 * Blockly.BlockSvg.GRID_UNIT // Square in square. - } -}; - -/** - * Corner radius of the hat on the define block. - * @const - */ -Blockly.BlockSvg.DEFINE_HAT_CORNER_RADIUS = 5 * Blockly.BlockSvg.GRID_UNIT; - -/** - * SVG path for drawing the rounded top-left corner. - * @const - */ -Blockly.BlockSvg.TOP_LEFT_CORNER_DEFINE_HAT = - 'a ' + Blockly.BlockSvg.DEFINE_HAT_CORNER_RADIUS + ',' + - Blockly.BlockSvg.DEFINE_HAT_CORNER_RADIUS + ' 0 0,1 ' + - Blockly.BlockSvg.DEFINE_HAT_CORNER_RADIUS + ',-' + - Blockly.BlockSvg.DEFINE_HAT_CORNER_RADIUS; - -/** - * SVG path for drawing the rounded top-left corner. - * @const - */ -Blockly.BlockSvg.TOP_RIGHT_CORNER_DEFINE_HAT = - 'a ' + Blockly.BlockSvg.DEFINE_HAT_CORNER_RADIUS + ',' + - Blockly.BlockSvg.DEFINE_HAT_CORNER_RADIUS + ' 0 0,1 ' + - Blockly.BlockSvg.DEFINE_HAT_CORNER_RADIUS + ',' + - Blockly.BlockSvg.DEFINE_HAT_CORNER_RADIUS; - -/** - * Padding on the right side of the internal block on the define block. - * @const - */ -Blockly.BlockSvg.DEFINE_BLOCK_PADDING_RIGHT = 2 * Blockly.BlockSvg.GRID_UNIT; - -/** - * Change the colour of a block. - */ -Blockly.BlockSvg.prototype.updateColour = function() { - var strokeColour = this.getColourTertiary(); - var renderShadowed = this.isShadow() && - !Blockly.scratchBlocksUtils.isShadowArgumentReporter(this); - - if (renderShadowed && this.parentBlock_) { - // Pull shadow block stroke colour from parent block's tertiary if possible. - strokeColour = this.parentBlock_.getColourTertiary(); - // Special case: if we contain a colour field, set to a special stroke colour. - if (this.inputList[0] && - this.inputList[0].fieldRow[0] && - (this.inputList[0].fieldRow[0] instanceof Blockly.FieldColour || - this.inputList[0].fieldRow[0] instanceof Blockly.FieldColourSlider)) { - strokeColour = Blockly.Colours.colourPickerStroke; - } - } - - // Render block stroke - this.svgPath_.setAttribute('stroke', strokeColour); - - // Render block fill - if (this.isGlowingBlock_ || renderShadowed) { - // Use the block's shadow colour if possible. - if (this.getShadowColour()) { - var fillColour = this.getShadowColour(); - } else { - var fillColour = this.getColourSecondary(); - } - } else { - var fillColour = this.getColour(); - } - this.svgPath_.setAttribute('fill', fillColour); - - // Render opacity - this.svgPath_.setAttribute('fill-opacity', this.getOpacity()); - - // Update colours of input shapes. - for (var i = 0, input; input = this.inputList[i]; i++) { - if (input.outlinePath) { - input.outlinePath.setAttribute('fill', this.getColourTertiary()); - } - } - - // Render icon(s) if applicable - var icons = this.getIcons(); - for (var i = 0; i < icons.length; i++) { - icons[i].updateColour(); - } - - // Bump every dropdown to change its colour. - for (var x = 0, input; input = this.inputList[x]; x++) { - for (var y = 0, field; field = input.fieldRow[y]; y++) { - field.setText(null); - } - } -}; - -/** - * Visual effect to show that if the dragging block is dropped, this block will - * be replaced. If a shadow block it will disappear. Otherwise it will bump. - * @param {boolean} add True if highlighting should be added. - */ -Blockly.BlockSvg.prototype.highlightForReplacement = function(add) { - if (add) { - var replacementGlowFilterId = this.workspace.options.replacementGlowFilterId - || 'blocklyReplacementGlowFilter'; - this.svgPath_.setAttribute('filter', 'url(#' + replacementGlowFilterId + ')'); - Blockly.utils.addClass(/** @type {!Element} */ (this.svgGroup_), - 'blocklyReplaceable'); - } else { - this.svgPath_.removeAttribute('filter'); - Blockly.utils.removeClass(/** @type {!Element} */ (this.svgGroup_), - 'blocklyReplaceable'); - } -}; - -/** - * Visual effect to show that if the dragging block is dropped it will connect - * to this input. - * @param {Blockly.Connection} conn The connection on the input to highlight. - * @param {boolean} add True if highlighting should be added. - */ -Blockly.BlockSvg.prototype.highlightShapeForInput = function(conn, add) { - var input = this.getInputWithConnection(conn); - if (!input) { - throw 'No input found for the connection'; - } - if (!input.outlinePath) { - return; - } - if (add) { - var replacementGlowFilterId = this.workspace.options.replacementGlowFilterId - || 'blocklyReplacementGlowFilter'; - input.outlinePath.setAttribute('filter', - 'url(#' + replacementGlowFilterId + ')'); - Blockly.utils.addClass(/** @type {!Element} */ (this.svgGroup_), - 'blocklyReplaceable'); - } else { - input.outlinePath.removeAttribute('filter'); - Blockly.utils.removeClass(/** @type {!Element} */ (this.svgGroup_), - 'blocklyReplaceable'); - } -}; - -/** - * Returns a bounding box describing the dimensions of this block - * and any blocks stacked below it. - * @return {!{height: number, width: number}} Object with height and width properties. - */ -Blockly.BlockSvg.prototype.getHeightWidth = function() { - var height = this.height; - var width = this.width; - // Recursively add size of subsequent blocks. - var nextBlock = this.getNextBlock(); - if (nextBlock) { - var nextHeightWidth = nextBlock.getHeightWidth(); - height += nextHeightWidth.height; - height -= Blockly.BlockSvg.NOTCH_HEIGHT; // Exclude height of connected notch. - width = Math.max(width, nextHeightWidth.width); - } - return {height: height, width: width}; -}; - -/** - * Render the block. - * Lays out and reflows a block based on its contents and settings. - * @param {boolean=} opt_bubble If false, just render this block. - * If true, also render block's parent, grandparent, etc. Defaults to true. - */ -Blockly.BlockSvg.prototype.render = function(opt_bubble) { - Blockly.Field.startCache(); - this.rendered = true; - - var cursorX = Blockly.BlockSvg.SEP_SPACE_X; - if (this.RTL) { - cursorX = -cursorX; - } - // Move the icons into position. - var icons = this.getIcons(); - var scratchCommentIcon = null; - for (var i = 0; i < icons.length; i++) { - if (icons[i] instanceof Blockly.ScratchBlockComment) { - // Don't render scratch block comment icon until - // after the inputs - scratchCommentIcon = icons[i]; - } else { - cursorX = icons[i].renderIcon(cursorX); - } - } - cursorX += this.RTL ? - Blockly.BlockSvg.SEP_SPACE_X : -Blockly.BlockSvg.SEP_SPACE_X; - // If there are no icons, cursorX will be 0, otherwise it will be the - // width that the first label needs to move over by. - - // If this is an extension reporter block, add a horizontal offset. - if (this.isScratchExtension && this.outputConnection) { - cursorX += this.RTL ? - -Blockly.BlockSvg.GRID_UNIT : Blockly.BlockSvg.GRID_UNIT; - } - - var inputRows = this.renderCompute_(cursorX); - this.renderDraw_(cursorX, inputRows); - this.renderMoveConnections_(); - - this.renderClassify_(); - - // Position the Scratch Block Comment Icon at the end of the block - if (scratchCommentIcon) { - var iconX = this.RTL ? -inputRows.rightEdge : inputRows.rightEdge; - var inputMarginY = inputRows[0].height / 2; - scratchCommentIcon.renderIcon(iconX, inputMarginY); - } - - if (opt_bubble !== false) { - // Render all blocks above this one (propagate a reflow). - var parentBlock = this.getParent(); - if (parentBlock) { - parentBlock.render(true); - } else { - // Top-most block. Fire an event to allow scrollbars to resize. - Blockly.resizeSvgContents(this.workspace); - } - } - Blockly.Field.stopCache(); -}; - -/** - * Render a list of fields starting at the specified location. - * @param {!Array.} fieldList List of fields. - * @param {number} cursorX X-coordinate to start the fields. - * @param {number} cursorY Y-coordinate around which fields are centered. - * @return {number} X-coordinate of the end of the field row (plus a gap). - * @private - */ -Blockly.BlockSvg.prototype.renderFields_ = function(fieldList, cursorX, - cursorY) { - if (this.RTL) { - cursorX = -cursorX; - } - for (var t = 0, field; field = fieldList[t]; t++) { - var root = field.getSvgRoot(); - if (!root) { - continue; - } - // In blocks with a notch, fields should be bumped to a min X, - // to avoid overlapping with the notch. Label and image fields are - // excluded. - if (this.previousConnection && !(field instanceof Blockly.FieldLabel) && - !(field instanceof Blockly.FieldImage)) { - cursorX = this.RTL ? - Math.min(cursorX, -Blockly.BlockSvg.INPUT_AND_FIELD_MIN_X) : - Math.max(cursorX, Blockly.BlockSvg.INPUT_AND_FIELD_MIN_X); - } - // Offset the field upward by half its height. - // This vertically centers the fields around cursorY. - var yOffset = -field.getSize().height / 2; - - // If this is an extension block, and this field is the first field, and - // it is an image field, and this block has a previous connection, bump - // the image down by one grid unit to align it vertically. - if (this.isScratchExtension && (field === this.inputList[0].fieldRow[0]) - && (field instanceof Blockly.FieldImage) && this.previousConnection) { - yOffset += Blockly.BlockSvg.GRID_UNIT; - } - - // If this is an extension hat block, adjust the height of the vertical - // separator without adjusting the field height. The effect is to move - // the bottom end of the line up one grid unit. - if (this.isScratchExtension && - !this.previousConnection && this.nextConnection && - field instanceof Blockly.FieldVerticalSeparator) { - field.setLineHeight(Blockly.BlockSvg.ICON_SEPARATOR_HEIGHT - - Blockly.BlockSvg.GRID_UNIT); - } - - var translateX, translateY; - var scale = ''; - if (this.RTL) { - cursorX -= field.renderSep + field.renderWidth; - translateX = cursorX; - translateY = cursorY + yOffset; - if (field.renderWidth) { - cursorX -= Blockly.BlockSvg.SEP_SPACE_X; - } - } else { - translateX = cursorX + field.renderSep; - translateY = cursorY + yOffset; - if (field.renderWidth) { - cursorX += field.renderSep + field.renderWidth + - Blockly.BlockSvg.SEP_SPACE_X; - } - } - if (this.RTL && - field instanceof Blockly.FieldImage && - field.getFlipRTL()) { - scale = 'scale(-1 1)'; - translateX += field.renderWidth; - } - root.setAttribute('transform', - 'translate(' + translateX + ', ' + translateY + ') ' + scale); - - // Fields are invisible on insertion marker. - if (this.isInsertionMarker()) { - root.setAttribute('display', 'none'); - } - } - return this.RTL ? -cursorX : cursorX; -}; - -/** - * Computes the height and widths for each row and field. - * @param {number} iconWidth Offset of first row due to icons. - * @return {!Array.>} 2D array of objects, each containing - * position information. - * @private - */ -Blockly.BlockSvg.prototype.renderCompute_ = function(iconWidth) { - var inputList = this.inputList; - var inputRows = []; - // Block will be drawn from 0 (left edge) to rightEdge, in px. - inputRows.rightEdge = 0; - // Drawn from 0 to bottomEdge vertically. - inputRows.bottomEdge = 0; - var fieldValueWidth = 0; // Width of longest external value field. - var fieldStatementWidth = 0; // Width of longest statement field. - var hasValue = false; - var hasStatement = false; - var hasDummy = false; - var lastType = undefined; - - // Previously created row, for special-casing row heights on C- and E- shaped blocks. - var previousRow; - for (var i = 0, input; input = inputList[i]; i++) { - if (!input.isVisible()) { - continue; - } - var isSecondInputOnProcedure = this.type == 'procedures_definition' && - lastType && lastType == Blockly.NEXT_STATEMENT; - var row; - // Don't create a new row for the second dummy input on a procedure block. - // See github.com/LLK/scratch-blocks/issues/1658 - // In all other cases, statement and value inputs catch all preceding dummy - // inputs, and cause a line break before following inputs. - if (!isSecondInputOnProcedure && - (!lastType || lastType == Blockly.NEXT_STATEMENT || - input.type == Blockly.NEXT_STATEMENT)) { - lastType = input.type; - row = this.createRowForInput_(input); - inputRows.push(row); - } else { - row = inputRows[inputRows.length - 1]; - } - row.push(input); - - // Compute minimum dimensions for this input. - input.renderHeight = this.computeInputHeight_(input, row, previousRow); - input.renderWidth = this.computeInputWidth_(input); - - // If the input is a statement input, determine if a notch - // should be drawn at the inner bottom of the C. - row.statementNotchAtBottom = true; - if (input.connection && input.connection.type === Blockly.NEXT_STATEMENT) { - var linkedBlock = input.connection.targetBlock(); - if (linkedBlock && !linkedBlock.lastConnectionInStack()) { - row.statementNotchAtBottom = false; - } - } - - // Expand input size. - if (input.connection) { - var linkedBlock = input.connection.targetBlock(); - var paddedHeight = 0; - var paddedWidth = 0; - if (linkedBlock) { - // A block is connected to the input - use its size. - var bBox = linkedBlock.getHeightWidth(); - paddedHeight = bBox.height; - paddedWidth = bBox.width; - } else { - // No block connected - use the size of the rendered empty input shape. - paddedHeight = Blockly.BlockSvg.INPUT_SHAPE_HEIGHT; - } - if (input.connection.type === Blockly.INPUT_VALUE) { - paddedHeight += 2 * Blockly.BlockSvg.INLINE_PADDING_Y; - } - if (input.connection.type === Blockly.NEXT_STATEMENT) { - // Subtract height of notch, only if the last block in the stack has a next connection. - if (row.statementNotchAtBottom) { - paddedHeight -= Blockly.BlockSvg.NOTCH_HEIGHT; - } - } - input.renderHeight = Math.max(input.renderHeight, paddedHeight); - input.renderWidth = Math.max(input.renderWidth, paddedWidth); - } - row.height = Math.max(row.height, input.renderHeight); - input.fieldWidth = 0; - if (inputRows.length == 1) { - // The first row gets shifted to accommodate any icons. - input.fieldWidth += this.RTL ? -iconWidth : iconWidth; - } - var previousFieldEditable = false; - for (var j = 0, field; field = input.fieldRow[j]; j++) { - if (j != 0) { - input.fieldWidth += Blockly.BlockSvg.SEP_SPACE_X; - } - // Get the dimensions of the field. - var fieldSize = field.getSize(); - field.renderWidth = fieldSize.width; - field.renderSep = (previousFieldEditable && field.EDITABLE) ? - Blockly.BlockSvg.SEP_SPACE_X : 0; - // See github.com/LLK/scratch-blocks/issues/1658 - if (!isSecondInputOnProcedure) { - input.fieldWidth += field.renderWidth + field.renderSep; - } - row.height = Math.max(row.height, fieldSize.height); - previousFieldEditable = field.EDITABLE; - } - - if (row.type != Blockly.BlockSvg.INLINE) { - if (row.type == Blockly.NEXT_STATEMENT) { - hasStatement = true; - fieldStatementWidth = Math.max(fieldStatementWidth, input.fieldWidth); - } else { - if (row.type == Blockly.INPUT_VALUE) { - hasValue = true; - } else if (row.type == Blockly.DUMMY_INPUT) { - hasDummy = true; - } - fieldValueWidth = Math.max(fieldValueWidth, input.fieldWidth); - } - } - previousRow = row; - } - // Compute padding for output blocks. - // Data is attached to the row. - this.computeOutputPadding_(inputRows); - // Compute the statement edge. - // This is the width of a block where statements are nested. - inputRows.statementEdge = Blockly.BlockSvg.STATEMENT_INPUT_EDGE_WIDTH + - fieldStatementWidth; - - // Compute the preferred right edge. - inputRows.rightEdge = this.computeRightEdge_(inputRows.rightEdge, - hasStatement); - - // Bottom edge is sum of row heights - for (var i = 0; i < inputRows.length; i++) { - inputRows.bottomEdge += inputRows[i].height; - } - - inputRows.hasValue = hasValue; - inputRows.hasStatement = hasStatement; - inputRows.hasDummy = hasDummy; - return inputRows; -}; - -/** - * Compute the minimum width of this input based on the connection type and - * outputs. - * @param {!Blockly.Input} input The input to measure. - * @return {number} the computed width of this input. - * @private - */ -Blockly.BlockSvg.prototype.computeInputWidth_ = function(input) { - // Empty input shape widths. - if (input.type == Blockly.INPUT_VALUE && - (!input.connection || !input.connection.isConnected())) { - switch (input.connection.getOutputShape()) { - case Blockly.OUTPUT_SHAPE_SQUARE: - return Blockly.BlockSvg.INPUT_SHAPE_SQUARE_WIDTH; - case Blockly.OUTPUT_SHAPE_ROUND: - return Blockly.BlockSvg.INPUT_SHAPE_ROUND_WIDTH; - case Blockly.OUTPUT_SHAPE_HEXAGONAL: - return Blockly.BlockSvg.INPUT_SHAPE_HEXAGONAL_WIDTH; - default: - return 0; - } - } else { - return 0; - } -}; - -/** - * Compute the minimum height of this input. - * @param {!Blockly.Input} input The input to measure. - * @param {!Object} row The row of the block that is currently being measured. - * @param {!Object} previousRow The previous row of the block, which was just - * measured. - * @return {number} the computed height of this input. - * @private - */ -Blockly.BlockSvg.prototype.computeInputHeight_ = function(input, row, - previousRow) { - if (this.inputList.length === 1 && this.outputConnection && - (this.isShadow() && - !Blockly.scratchBlocksUtils.isShadowArgumentReporter(this))) { - // "Lone" field blocks are smaller. - return Blockly.BlockSvg.MIN_BLOCK_Y_SINGLE_FIELD_OUTPUT; - } else if (this.outputConnection) { - // If this is an extension reporter block, make it taller. - if (this.isScratchExtension) { - return Blockly.BlockSvg.MIN_BLOCK_Y_REPORTER + 2 * Blockly.BlockSvg.GRID_UNIT; - } - // All other reporters. - return Blockly.BlockSvg.MIN_BLOCK_Y_REPORTER; - } else if (row.type == Blockly.NEXT_STATEMENT) { - // Statement input. - return Blockly.BlockSvg.MIN_STATEMENT_INPUT_HEIGHT; - } else if (previousRow && previousRow.type == Blockly.NEXT_STATEMENT) { - // Extra row for below statement input. - return Blockly.BlockSvg.EXTRA_STATEMENT_ROW_Y; - } else { - // If this is an extension block, and it has a previous connection, - // make it taller. - if (this.isScratchExtension && this.previousConnection) { - return Blockly.BlockSvg.MIN_BLOCK_Y + 2 * Blockly.BlockSvg.GRID_UNIT; - } - // All other blocks. - return Blockly.BlockSvg.MIN_BLOCK_Y; - } -}; - -/** - * Create a row for an input and associated fields. - * @param {!Blockly.Input} input The input that the row is based on. - * @return {!Object} The new row, with the correct type and default sizing info. - */ -Blockly.BlockSvg.prototype.createRowForInput_ = function(input) { - // Create new row. - var row = []; - if (input.type != Blockly.NEXT_STATEMENT) { - row.type = Blockly.BlockSvg.INLINE; - } else { - row.type = input.type; - } - row.height = 0; - // Default padding for a block: same as separators between fields/inputs. - row.paddingStart = Blockly.BlockSvg.SEP_SPACE_X; - row.paddingEnd = Blockly.BlockSvg.SEP_SPACE_X; - return row; -}; - -/** - * Compute the preferred right edge of the block. - * @param {number} curEdge The previously calculated right edge. - * @param {boolean} hasStatement Whether this block has a statement input. - * @return {number} The preferred right edge of the block. - */ -Blockly.BlockSvg.prototype.computeRightEdge_ = function(curEdge, hasStatement) { - var edge = curEdge; - if (this.previousConnection || this.nextConnection) { - // Blocks with notches - edge = Math.max(edge, Blockly.BlockSvg.MIN_BLOCK_X); - } else if (this.outputConnection) { - if (this.isShadow() && - !Blockly.scratchBlocksUtils.isShadowArgumentReporter(this)) { - // Single-fields - edge = Math.max(edge, Blockly.BlockSvg.MIN_BLOCK_X_SHADOW_OUTPUT); - } else { - // Reporters - edge = Math.max(edge, Blockly.BlockSvg.MIN_BLOCK_X_OUTPUT); - } - } - if (hasStatement) { - // Statement blocks (C- or E- shaped) have a longer minimum width. - edge = Math.max(edge, Blockly.BlockSvg.MIN_BLOCK_X_WITH_STATEMENT); - } - - // Ensure insertion markers are at least insertionMarkerMinWidth_ wide. - if (this.insertionMarkerMinWidth_ > 0) { - edge = Math.max(edge, this.insertionMarkerMinWidth_); - } - return edge; -}; - -/** - * For a block with output, - * determine start and end padding, based on connected inputs. - * Padding will depend on the shape of the output, the shape of the input, - * and possibly the size of the input. - * @param {!Array.>} inputRows Partially calculated rows. - */ -Blockly.BlockSvg.prototype.computeOutputPadding_ = function(inputRows) { - // Only apply to blocks with outputs and not single fields (shadows). - if (!this.getOutputShape() || !this.outputConnection || - (this.isShadow() && - !Blockly.scratchBlocksUtils.isShadowArgumentReporter(this))) { - return; - } - // Blocks with outputs must have single row to be padded. - if (inputRows.length > 1) { - return; - } - var row = inputRows[0]; - var shape = this.getOutputShape(); - // Reset any padding: it's about to be set. - row.paddingStart = 0; - row.paddingEnd = 0; - // Start row padding: based on first input or first field. - var firstInput = row[0]; - var firstField = firstInput.fieldRow[0]; - var otherShape; - // In checking the left/start side, a field takes precedence over any input. - // That's because a field will be rendered before any value input. - if (firstField) { - otherShape = 0; // Field comes first in the row. - } else { - // Value input comes first in the row. - var inputConnection = firstInput.connection; - if (!inputConnection.targetConnection) { - // Not connected: use the drawn shape. - otherShape = inputConnection.getOutputShape(); - } else { - // Connected: use the connected block's output shape. - otherShape = inputConnection.targetConnection.getSourceBlock().getOutputShape(); - } - // Special case for hexagonal output: if the connection is larger height - // than a standard reporter, add some start padding. - // https://github.com/LLK/scratch-blocks/issues/376 - if (shape == Blockly.OUTPUT_SHAPE_HEXAGONAL && - otherShape != Blockly.OUTPUT_SHAPE_HEXAGONAL) { - var deltaHeight = firstInput.renderHeight - Blockly.BlockSvg.MIN_BLOCK_Y_REPORTER; - // One grid unit per level of nesting. - row.paddingStart += deltaHeight / 2; - } - } - row.paddingStart += Blockly.BlockSvg.SHAPE_IN_SHAPE_PADDING[shape][otherShape]; - // End row padding: based on last input or last field. - var lastInput = row[row.length - 1]; - // In checking the right/end side, any value input takes precedence over any field. - // That's because fields are rendered before inputs...the last item - // in the row will be an input, if one exists. - if (lastInput.connection) { - // Value input last in the row. - var inputConnection = lastInput.connection; - if (!inputConnection.targetConnection) { - // Not connected: use the drawn shape. - otherShape = inputConnection.getOutputShape(); - } else { - // Connected: use the connected block's output shape. - otherShape = inputConnection.targetConnection.getSourceBlock().getOutputShape(); - } - // Special case for hexagonal output: if the connection is larger height - // than a standard reporter, add some end padding. - // https://github.com/LLK/scratch-blocks/issues/376 - if (shape == Blockly.OUTPUT_SHAPE_HEXAGONAL && - otherShape != Blockly.OUTPUT_SHAPE_HEXAGONAL) { - var deltaHeight = lastInput.renderHeight - Blockly.BlockSvg.MIN_BLOCK_Y_REPORTER; - // One grid unit per level of nesting. - row.paddingEnd += deltaHeight / 2; - } - } else { - // No input in this row - mark as field. - otherShape = 0; - } - row.paddingEnd += Blockly.BlockSvg.SHAPE_IN_SHAPE_PADDING[shape][otherShape]; -}; - -/** - * Draw the path of the block. - * Move the fields to the correct locations. - * @param {number} iconWidth Offset of first row due to icons. - * @param {!Array.>} inputRows 2D array of objects, each - * containing position information. - * @private - */ -Blockly.BlockSvg.prototype.renderDraw_ = function(iconWidth, inputRows) { - this.startHat_ = false; - // Should the top left corners be rounded or square? - // Currently, it is squared only if it's a hat. - this.squareTopLeftCorner_ = false; - if (!this.outputConnection && !this.previousConnection) { - // No output or previous connection. - this.squareTopLeftCorner_ = true; - this.startHat_ = true; - inputRows.rightEdge = Math.max(inputRows.rightEdge, 100); - } - - // Amount of space to skip drawing the top and bottom, - // to make room for the left and right to draw shapes (curves or angles). - this.edgeShapeWidth_ = 0; - this.edgeShape_ = null; - if (this.outputConnection) { - // Width of the curve/pointy-curve - var shape = this.getOutputShape(); - if (shape === Blockly.OUTPUT_SHAPE_HEXAGONAL || shape === Blockly.OUTPUT_SHAPE_ROUND) { - this.edgeShapeWidth_ = inputRows.bottomEdge / 2; - this.edgeShape_ = shape; - this.squareTopLeftCorner_ = true; - } - } - - // Assemble the block's path. - var steps = []; - - this.renderDrawTop_(steps, inputRows.rightEdge); - var cursorY = this.renderDrawRight_(steps, inputRows, iconWidth); - this.renderDrawBottom_(steps, cursorY); - this.renderDrawLeft_(steps); - - var pathString = steps.join(' '); - this.svgPath_.setAttribute('d', pathString); - - if (this.RTL) { - // Mirror the block's path. - // This is awesome. - this.svgPath_.setAttribute('transform', 'scale(-1 1)'); - } -}; - -/** - * Give the block an attribute 'data-shapes' that lists its shape[s], and an - * attribute 'data-category' with its category. - * @private - */ -Blockly.BlockSvg.prototype.renderClassify_ = function() { - var shapes = []; - - if (this.outputConnection) { - if (this.isShadow_) { - shapes.push('argument'); - } else { - shapes.push('reporter'); - } - if (this.edgeShape_ === Blockly.OUTPUT_SHAPE_HEXAGONAL) { - shapes.push('boolean'); - } else if (this.edgeShape_ === Blockly.OUTPUT_SHAPE_ROUND) { - shapes.push('round'); - } - } else { - // count the number of statement inputs - var inputList = this.inputList; - var statementCount = 0; - for (var i = 0, input; input = inputList[i]; i++) { - if (input.connection && input.connection.type === Blockly.NEXT_STATEMENT) { - statementCount++; - } - } - - if (statementCount) { - shapes.push('c-block'); - shapes.push('c-' + statementCount); - } - if (this.startHat_) { - shapes.push('hat'); // c-block+hats are possible (e.x. reprter procedures) - } else if (!statementCount) { - shapes.push('stack'); //only call it "stack" if it's not a c-block - } - if (!this.nextConnection) { - shapes.push('end'); - } - } - - this.svgGroup_.setAttribute('data-shapes', shapes.join(' ')); - - if (this.getCategory()) { - this.svgGroup_.setAttribute('data-category', this.getCategory()); - } -}; - -/** - * Render the top edge of the block. - * @param {!Array.} steps Path of block outline. - * @param {number} rightEdge Minimum width of block. - * @private - */ -Blockly.BlockSvg.prototype.renderDrawTop_ = function(steps, rightEdge) { - if (this.type == Blockly.PROCEDURES_DEFINITION_BLOCK_TYPE) { - steps.push('m 0, 0'); - steps.push(Blockly.BlockSvg.TOP_LEFT_CORNER_DEFINE_HAT); - } else { - // Position the cursor at the top-left starting point. - if (this.squareTopLeftCorner_) { - steps.push('m 0,0'); - if (this.startHat_) { - steps.push(Blockly.BlockSvg.START_HAT_PATH); - } - // Skip space for the output shape - if (this.edgeShapeWidth_) { - steps.push('m ' + this.edgeShapeWidth_ + ',0'); - } - } else { - steps.push(Blockly.BlockSvg.TOP_LEFT_CORNER_START); - // Top-left rounded corner. - steps.push(Blockly.BlockSvg.TOP_LEFT_CORNER); - } - - // Top edge. - if (this.previousConnection) { - // Space before the notch - steps.push('H', Blockly.BlockSvg.NOTCH_START_PADDING); - steps.push(Blockly.BlockSvg.NOTCH_PATH_LEFT); - // Create previous block connection. - var connectionX = (this.RTL ? - -Blockly.BlockSvg.NOTCH_WIDTH : Blockly.BlockSvg.NOTCH_WIDTH); - this.previousConnection.setOffsetInBlock(connectionX, 0); - } - } - this.width = rightEdge; -}; - -/** - * Render the right edge of the block. - * @param {!Array.} steps Path of block outline. - * @param {!Array.>} inputRows 2D array of objects, each - * containing position information. - * @param {number} iconWidth Offset of first row due to icons. - * @return {number} Height of block. - * @private - */ -Blockly.BlockSvg.prototype.renderDrawRight_ = function(steps, - inputRows, iconWidth) { - var cursorX = 0; - var cursorY = 0; - var connectionX, connectionY; - for (var y = 0, row; row = inputRows[y]; y++) { - cursorX = row.paddingStart; - if (y == 0) { - cursorX += this.RTL ? -iconWidth : iconWidth; - } - - if (row.type == Blockly.BlockSvg.INLINE) { - // Inline inputs. - for (var x = 0, input; input = row[x]; x++) { - // Align fields vertically within the row. - // Moves the field to half of the row's height. - // In renderFields_, the field is further centered - // by its own rendered height. - var fieldY = cursorY + row.height / 2; - - var fieldX = Blockly.BlockSvg.getAlignedCursor_(cursorX, input, - inputRows.rightEdge); - - cursorX = this.renderFields_(input.fieldRow, fieldX, fieldY); - if (input.type == Blockly.INPUT_VALUE) { - // Create inline input connection. - // In blocks with a notch, inputs should be bumped to a min X, - // to avoid overlapping with the notch. - if (this.previousConnection) { - cursorX = Math.max(cursorX, Blockly.BlockSvg.INPUT_AND_FIELD_MIN_X); - } - connectionX = this.RTL ? -cursorX : cursorX; - // Attempt to center the connection vertically. - var connectionYOffset = row.height / 2; - connectionY = cursorY + connectionYOffset; - input.connection.setOffsetInBlock(connectionX, connectionY); - this.renderInputShape_(input, cursorX, cursorY + connectionYOffset); - cursorX += input.renderWidth + Blockly.BlockSvg.SEP_SPACE_X; - } - } - // Remove final separator and replace it with right-padding. - cursorX -= Blockly.BlockSvg.SEP_SPACE_X; - cursorX += row.paddingEnd; - // Update right edge for all inputs, such that all rows - // stretch to be at least the size of all previous rows. - inputRows.rightEdge = Math.max(cursorX, inputRows.rightEdge); - // Move to the right edge - cursorX = Math.max(cursorX, inputRows.rightEdge); - this.width = Math.max(this.width, cursorX); - if (!this.edgeShape_) { - // Include corner radius in drawing the horizontal line. - steps.push('H', cursorX - Blockly.BlockSvg.CORNER_RADIUS - this.edgeShapeWidth_); - steps.push(Blockly.BlockSvg.TOP_RIGHT_CORNER); - } else { - // Don't include corner radius - no corner (edge shape drawn). - steps.push('H', cursorX - this.edgeShapeWidth_); - } - // Subtract CORNER_RADIUS * 2 to account for the top right corner - // and also the bottom right corner. Only move vertically the non-corner length. - if (!this.edgeShape_) { - steps.push('v', row.height - Blockly.BlockSvg.CORNER_RADIUS * 2); - } - } else if (row.type == Blockly.NEXT_STATEMENT) { - // Nested statement. - var input = row[0]; - var fieldX = cursorX; - // Align fields vertically within the row. - // In renderFields_, the field is further centered by its own height. - var fieldY = cursorY; - fieldY += Blockly.BlockSvg.MIN_STATEMENT_INPUT_HEIGHT; - this.renderFields_(input.fieldRow, fieldX, fieldY); - // Move to the start of the notch. - cursorX = inputRows.statementEdge + Blockly.BlockSvg.NOTCH_WIDTH; - - if (this.type == Blockly.PROCEDURES_DEFINITION_BLOCK_TYPE) { - this.renderDefineBlock_(steps, inputRows, input, row, cursorY); - } else { - Blockly.BlockSvg.drawStatementInputFromTopRight_(steps, cursorX, - inputRows.rightEdge, row); - } - - // Create statement connection. - connectionX = this.RTL ? -cursorX : cursorX; - input.connection.setOffsetInBlock(connectionX, cursorY); - if (input.connection.isConnected()) { - this.width = Math.max(this.width, inputRows.statementEdge + - input.connection.targetBlock().getHeightWidth().width); - } - if (this.type != Blockly.PROCEDURES_DEFINITION_BLOCK_TYPE && - (y == inputRows.length - 1 || - inputRows[y + 1].type == Blockly.NEXT_STATEMENT)) { - // If the final input is a statement stack, add a small row underneath. - // Consecutive statement stacks are also separated by a small divider. - steps.push(Blockly.BlockSvg.TOP_RIGHT_CORNER); - steps.push('v', Blockly.BlockSvg.EXTRA_STATEMENT_ROW_Y - 2 * Blockly.BlockSvg.CORNER_RADIUS); - cursorY += Blockly.BlockSvg.EXTRA_STATEMENT_ROW_Y; - } - } - cursorY += row.height; - } - this.drawEdgeShapeRight_(steps); - if (!inputRows.length) { - cursorY = Blockly.BlockSvg.MIN_BLOCK_Y; - steps.push('V', cursorY); - } - return cursorY; -}; - -/** - * Render the input shapes. - * If there's a connected block, hide the input shape. - * Otherwise, draw and set the position of the input shape. - * @param {!Blockly.Input} input Input to be rendered. - * @param {Number} x X offset of input. - * @param {Number} y Y offset of input. - */ -Blockly.BlockSvg.prototype.renderInputShape_ = function(input, x, y) { - var inputShape = input.outlinePath; - if (!inputShape) { - // No input shape for this input - e.g., the block is an insertion marker. - return; - } - // Input shapes are only visibly rendered on non-connected slots. - if (input.connection.targetConnection) { - inputShape.setAttribute('style', 'visibility: hidden'); - } else { - var inputShapeX = 0, inputShapeY = 0; - var inputShapeInfo = - Blockly.BlockSvg.getInputShapeInfo_(input.connection.getOutputShape()); - if (this.RTL) { - inputShapeX = -x - inputShapeInfo.width; - } else { - inputShapeX = x; - } - inputShapeY = y - (Blockly.BlockSvg.INPUT_SHAPE_HEIGHT / 2); - inputShape.setAttribute('d', inputShapeInfo.path); - inputShape.setAttribute('transform', - 'translate(' + inputShapeX + ',' + inputShapeY + ')'); - inputShape.setAttribute('data-argument-type', inputShapeInfo.argType); - inputShape.setAttribute('style', 'visibility: visible'); - } -}; - -/** - * Render the bottom edge of the block. - * @param {!Array.} steps Path of block outline. - * @param {number} cursorY Height of block. - * @private - */ -Blockly.BlockSvg.prototype.renderDrawBottom_ = function(steps, cursorY) { - this.height = cursorY; - if (!this.edgeShape_) { - steps.push(Blockly.BlockSvg.BOTTOM_RIGHT_CORNER); - } - if (this.nextConnection) { - // Move to the right-side of the notch. - var notchStart = ( - Blockly.BlockSvg.NOTCH_WIDTH + - Blockly.BlockSvg.NOTCH_START_PADDING + - Blockly.BlockSvg.CORNER_RADIUS - ); - steps.push('H', notchStart, ' '); - steps.push(Blockly.BlockSvg.NOTCH_PATH_RIGHT); - // Create next block connection. - var connectionX = this.RTL ? -Blockly.BlockSvg.NOTCH_WIDTH : - Blockly.BlockSvg.NOTCH_WIDTH; - this.nextConnection.setOffsetInBlock(connectionX, cursorY); - // Include height of notch in block height. - this.height += Blockly.BlockSvg.NOTCH_HEIGHT; - } - // Bottom horizontal line - if (!this.edgeShape_) { - steps.push('H', Blockly.BlockSvg.CORNER_RADIUS); - // Bottom left corner - steps.push(Blockly.BlockSvg.BOTTOM_LEFT_CORNER); - } else { - steps.push('H', this.edgeShapeWidth_); - } -}; - -/** - * Render the left edge of the block. - * @param {!Array.} steps Path of block outline. - * @param {number} cursorY Height of block. - * @private - */ -Blockly.BlockSvg.prototype.renderDrawLeft_ = function(steps) { - if (this.outputConnection) { - // Scratch-style reporters have output connection y at half block height. - this.outputConnection.setOffsetInBlock(0, this.height / 2); - } - if (this.edgeShape_) { - // Draw the left-side edge shape. - if (this.edgeShape_ === Blockly.OUTPUT_SHAPE_ROUND) { - // Draw a rounded arc. - steps.push('a ' + this.edgeShapeWidth_ + ' ' + this.edgeShapeWidth_ + ' 0 0 1 0 -' + this.edgeShapeWidth_ * 2); - } else if (this.edgeShape_ === Blockly.OUTPUT_SHAPE_HEXAGONAL) { - // Draw a half-hexagon. - steps.push('l ' + -this.edgeShapeWidth_ + ' ' + -this.edgeShapeWidth_ + - ' l ' + this.edgeShapeWidth_ + ' ' + -this.edgeShapeWidth_); - } - } - steps.push('z'); -}; - -/** - * Draw the edge shape (rounded or hexagonal) on the right side of a block with - * an output. - * @param {!Array.} steps Path of block outline. - * @private - */ -Blockly.BlockSvg.prototype.drawEdgeShapeRight_ = function(steps) { - if (this.edgeShape_) { - // Draw the right-side edge shape. - if (this.edgeShape_ === Blockly.OUTPUT_SHAPE_ROUND) { - // Draw a rounded arc. - steps.push('a ' + this.edgeShapeWidth_ + ' ' + this.edgeShapeWidth_ + - ' 0 0 1 0 ' + this.edgeShapeWidth_ * 2); - } else if (this.edgeShape_ === Blockly.OUTPUT_SHAPE_HEXAGONAL) { - // Draw an half-hexagon. - steps.push('l ' + this.edgeShapeWidth_ + ' ' + this.edgeShapeWidth_ + - ' l ' + -this.edgeShapeWidth_ + ' ' + this.edgeShapeWidth_); - } - } -}; - -/** - * Position an new block correctly, so that it doesn't move the existing block - * when connected to it. - * @param {!Blockly.Block} newBlock The block to position - either the first - * block in a dragged stack or an insertion marker. - * @param {!Blockly.Connection} newConnection The connection on the new block's - * stack - either a connection on newBlock, or the last NEXT_STATEMENT - * connection on the stack if the stack's being dropped before another - * block. - * @param {!Blockly.Connection} existingConnection The connection on the - * existing block, which newBlock should line up with. - */ -Blockly.BlockSvg.prototype.positionNewBlock = function(newBlock, newConnection, - existingConnection) { - // We only need to position the new block if it's before the existing one, - // otherwise its position is set by the previous block. - if (newConnection.type == Blockly.NEXT_STATEMENT) { - var dx = existingConnection.x_ - newConnection.x_; - var dy = existingConnection.y_ - newConnection.y_; - - newBlock.moveBy(dx, dy); - } -}; - -/** - * Draw the outline of a statement input, starting at the top right corner. - * @param {!Array.} steps Path of block outline. - * @param {number} cursorX The x position of the start of the notch at the top - * of the input. - * @param {number} rightEdge The far right edge of the block, which determines - * how wide the statement input is. - * @param {!Array.} row An object containing information about the - * current row, including its height and whether it should have a notch at - * the bottom. - * @private - */ -Blockly.BlockSvg.drawStatementInputFromTopRight_ = function(steps, cursorX, - rightEdge, row) { - Blockly.BlockSvg.drawStatementInputTop_(steps, cursorX); - steps.push('v', row.height - 2 * Blockly.BlockSvg.CORNER_RADIUS); - Blockly.BlockSvg.drawStatementInputBottom_(steps, rightEdge, row); -}; - -/** - * Draw the top of the outline of a statement input, starting at the top right - * corner. - * @param {!Array.} steps Path of block outline. - * @param {number} cursorX The x position of the start of the notch at the top - * of the input. - * @private - */ -Blockly.BlockSvg.drawStatementInputTop_ = function(steps, cursorX) { - steps.push(Blockly.BlockSvg.BOTTOM_RIGHT_CORNER); - steps.push('H', cursorX + Blockly.BlockSvg.STATEMENT_INPUT_INNER_SPACE + - 2 * Blockly.BlockSvg.CORNER_RADIUS); - steps.push(Blockly.BlockSvg.NOTCH_PATH_RIGHT); - steps.push('h', '-' + Blockly.BlockSvg.STATEMENT_INPUT_INNER_SPACE); - steps.push(Blockly.BlockSvg.INNER_TOP_LEFT_CORNER); -}; - -/** - * Draw the bottom of the outline of a statement input, starting at the inner - * left corner. - * @param {!Array.} steps Path of block outline. - * @param {number} rightEdge The far right edge of the block, which determines - * how wide the statement input is. - * @param {!Array.} row An object containing information about the - * current row, including its height and whether it should have a notch at - * the bottom. - * @private - */ -Blockly.BlockSvg.drawStatementInputBottom_ = function(steps, rightEdge, row) { - steps.push(Blockly.BlockSvg.INNER_BOTTOM_LEFT_CORNER); - if (row.statementNotchAtBottom) { - steps.push('h ', Blockly.BlockSvg.STATEMENT_INPUT_INNER_SPACE); - steps.push(Blockly.BlockSvg.NOTCH_PATH_LEFT); - } - steps.push('H', rightEdge - Blockly.BlockSvg.CORNER_RADIUS); -}; - -/** - * Render part of the hat and the right side of the define block to fully wrap - * the connected statement block. - * Scratch-specific. - * @param {!Array.} steps Path of block outline. - * @param {!Array.>} inputRows 2D array of objects, each - * containing position information. - * @param {!Blockly.Input} input The input that is currently being rendered. - * @param {!Array.} row An object containing information about the - * current row, including its height and whether it should have a notch at - * the bottom. - * @param {number} cursorY The y position of the start of this row. Used to - * position the following dummy input's fields. - * @private - */ -Blockly.BlockSvg.prototype.renderDefineBlock_ = function(steps, inputRows, - input, row, cursorY) { - // Following text shows up as a dummy input after the statement input, which - // we are forcing to stay inline with the statement input instead of letting - // it drop to a new line. - var hasFollowingText = row.length == 2; - - // Figure out where the right side of the block is. - var rightSide = inputRows.rightEdge; - if (input.connection && input.connection.targetBlock()) { - rightSide = inputRows.statementEdge + - input.connection.targetBlock().getHeightWidth().width + - Blockly.BlockSvg.DEFINE_BLOCK_PADDING_RIGHT; - } else { - // Handles the case where block is being rendered as an insertion marker - rightSide = Math.max(Blockly.BlockSvg.MIN_BLOCK_X_WITH_STATEMENT, rightSide) - + Blockly.BlockSvg.DEFINE_BLOCK_PADDING_RIGHT; - } - rightSide -= Blockly.BlockSvg.DEFINE_HAT_CORNER_RADIUS; - - if (hasFollowingText) { - var followingTextInput = row[1]; - var fieldStart = rightSide + 3 * Blockly.BlockSvg.SEP_SPACE_X; - rightSide += followingTextInput.fieldRow[0].getSize().width; - rightSide += 2 * Blockly.BlockSvg.SEP_SPACE_X; - - // Align fields vertically within the row. - // In renderFields_, the field is further centered by its own height. - // The dummy input's fields did not get laid out normally because we're - // forcing them to stay inline with a statement input. - var fieldY = cursorY; - fieldY += Blockly.BlockSvg.MIN_STATEMENT_INPUT_HEIGHT; - this.renderFields_(followingTextInput.fieldRow, fieldStart, fieldY); - } - // Draw the top and the right corner of the hat. - steps.push('H', rightSide); - steps.push(Blockly.BlockSvg.TOP_RIGHT_CORNER_DEFINE_HAT); - row.height += 3 * Blockly.BlockSvg.GRID_UNIT; - // Draw the right side of the block around the statement input. - steps.push('v', row.height); - // row.height will be used to update the cursor in the calling function. - row.height += Blockly.BlockSvg.GRID_UNIT; - -}; - -/** - * Get some information about the input shape to draw, based on the type of the - * connection. - * @param {number} shape An enum representing the shape of the connection we're - * drawing around. - * @return {!Object} An object containing an SVG path, a string representation - * of the argument type, and a width. - * @private - */ -Blockly.BlockSvg.getInputShapeInfo_ = function(shape) { - var inputShapePath = null; - var inputShapeArgType = null; - var inputShapeWidth = 0; - - switch (shape) { - case Blockly.OUTPUT_SHAPE_HEXAGONAL: - inputShapePath = Blockly.BlockSvg.INPUT_SHAPE_HEXAGONAL; - inputShapeWidth = Blockly.BlockSvg.INPUT_SHAPE_HEXAGONAL_WIDTH; - inputShapeArgType = 'boolean'; - break; - case Blockly.OUTPUT_SHAPE_ROUND: - inputShapePath = Blockly.BlockSvg.INPUT_SHAPE_ROUND; - inputShapeWidth = Blockly.BlockSvg.INPUT_SHAPE_ROUND_WIDTH; - inputShapeArgType = 'round'; - break; - case Blockly.OUTPUT_SHAPE_SQUARE: - default: // If the input connection is not connected, draw a hole shape. - inputShapePath = Blockly.BlockSvg.INPUT_SHAPE_SQUARE; - inputShapeWidth = Blockly.BlockSvg.INPUT_SHAPE_SQUARE_WIDTH; - inputShapeArgType = 'square'; - break; - } - return { - path: inputShapePath, - argType: inputShapeArgType, - width: inputShapeWidth - }; -}; - -/** - * Get the correct cursor position for the given input, based on alignment, - * the total size of the block, and the size of the input. - * @param {number} cursorX The minimum x value of the cursor. - * @param {!Blockly.Input} input The input to align the fields for. - * @param {number} rightEdge The maximum width of the block. Right-aligned - * fields are positioned based on this number. - * @return {number} The new cursor position. - * @private - */ -Blockly.BlockSvg.getAlignedCursor_ = function(cursorX, input, rightEdge) { - // Align inline field rows (left/right/centre). - if (input.align === Blockly.ALIGN_RIGHT) { - cursorX += rightEdge - input.fieldWidth - - (2 * Blockly.BlockSvg.SEP_SPACE_X); - } else if (input.align === Blockly.ALIGN_CENTRE) { - cursorX = Math.max(cursorX, rightEdge / 2 - input.fieldWidth / 2); - } - return cursorX; -}; - -/** - * Update all of the connections on this block with the new locaitons calculated - * in renderCompute, and move all of the connected blocks based on the new - * connection locations. - * @private - */ -Blockly.BlockSvg.prototype.renderMoveConnections_ = function() { - var blockTL = this.getRelativeToSurfaceXY(); - // Don't tighten previous or output connections because they are inferior. - if (this.previousConnection) { - this.previousConnection.moveToOffset(blockTL); - } - if (this.outputConnection) { - this.outputConnection.moveToOffset(blockTL); - } - - for (var i = 0; i < this.inputList.length; i++) { - var conn = this.inputList[i].connection; - if (conn) { - conn.moveToOffset(blockTL); - if (conn.isConnected()) { - conn.tighten_(); - } - } - } - - if (this.nextConnection) { - this.nextConnection.moveToOffset(blockTL); - if (this.nextConnection.isConnected()) { - this.nextConnection.tighten_(); - } - } -}; diff --git a/core/block_svg.js b/core/block_svg.js deleted file mode 100644 index 6e24dbe86f..0000000000 --- a/core/block_svg.js +++ /dev/null @@ -1,1316 +0,0 @@ -/** - * @license - * Visual Blocks Editor - * - * Copyright 2012 Google Inc. - * https://developers.google.com/blockly/ - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @fileoverview Methods for graphically rendering a block as SVG. - * @author fraser@google.com (Neil Fraser) - */ -'use strict'; - -goog.provide('Blockly.BlockSvg'); - -goog.require('Blockly.Block'); -goog.require('Blockly.BlockAnimations'); -goog.require('Blockly.ContextMenu'); -goog.require('Blockly.Events.Ui'); -goog.require('Blockly.Events.BlockMove'); -goog.require('Blockly.Grid'); -goog.require('Blockly.RenderedConnection'); -goog.require('Blockly.scratchBlocksUtils'); -goog.require('Blockly.Tooltip'); -goog.require('Blockly.Touch'); -goog.require('Blockly.utils'); - -goog.require('goog.Timer'); -goog.require('goog.asserts'); -goog.require('goog.dom'); -goog.require('goog.math.Coordinate'); - - -/** - * Class for a block's SVG representation. - * Not normally called directly, workspace.newBlock() is preferred. - * @param {!Blockly.Workspace} workspace The block's workspace. - * @param {?string} prototypeName Name of the language object containing - * type-specific functions for this block. - * @param {string=} opt_id Optional ID. Use this ID if provided, otherwise - * create a new ID. If the ID conflicts with an in-use ID, a new one will - * be generated. - * @extends {Blockly.Block} - * @constructor - */ -Blockly.BlockSvg = function(workspace, prototypeName, opt_id) { - // Create core elements for the block. - /** - * @type {SVGElement} - * @private - */ - this.svgGroup_ = Blockly.utils.createSvgElement('g', {}, null); - /** @type {SVGElement} */ - this.svgPath_ = Blockly.utils.createSvgElement('path', - {'class': 'blocklyPath blocklyBlockBackground'}, - this.svgGroup_); - this.svgPath_.tooltip = this; - - /** @type {boolean} */ - this.rendered = false; - - /** - * Whether to move the block to the drag surface when it is dragged. - * True if it should move, false if it should be translated directly. - * @type {boolean} - * @private - */ - this.useDragSurface_ = Blockly.utils.is3dSupported() && !!workspace.blockDragSurface_; - - Blockly.Tooltip.bindMouseEvents(this.svgPath_); - Blockly.BlockSvg.superClass_.constructor.call(this, - workspace, prototypeName, opt_id); - - // Expose this block's ID on its top-level SVG group. - if (this.svgGroup_.dataset) { - this.svgGroup_.dataset.id = this.id; - } -}; -goog.inherits(Blockly.BlockSvg, Blockly.Block); - -/** - * Height of this block, not including any statement blocks above or below. - * Height is in workspace units. - */ -Blockly.BlockSvg.prototype.height = 0; - -/** - * Width of this block, including any connected value blocks. - * Width is in workspace units. - */ -Blockly.BlockSvg.prototype.width = 0; - -/** - * Minimum width of block if insertion marker; comes from inserting block. - * @type {number} - */ -Blockly.BlockSvg.prototype.insertionMarkerMinWidth_ = 0; - -/** - * Opacity of this block between 0 and 1. - * @type {number} - * @private - */ -Blockly.BlockSvg.prototype.opacity_ = 1; - -/** - * Original location of block being dragged. - * @type {goog.math.Coordinate} - * @private - */ -Blockly.BlockSvg.prototype.dragStartXY_ = null; - -/** - * Whether the block glows as if running. - * @type {boolean} - * @private - */ -Blockly.BlockSvg.prototype.isGlowingBlock_ = false; - -/** - * Whether the block's whole stack glows as if running. - * @type {boolean} - * @private - */ -Blockly.BlockSvg.prototype.isGlowingStack_ = false; - -/** - * Constant for identifying rows that are to be rendered inline. - * Don't collide with Blockly.INPUT_VALUE and friends. - * @const - */ -Blockly.BlockSvg.INLINE = -1; - -/** - * Create and initialize the SVG representation of the block. - * May be called more than once. - */ -Blockly.BlockSvg.prototype.initSvg = function() { - goog.asserts.assert(this.workspace.rendered, 'Workspace is headless.'); - if (!this.isInsertionMarker()) { // Insertion markers not allowed to have inputs or icons - // Input shapes are empty holes drawn when a value input is not connected. - for (var i = 0, input; input = this.inputList[i]; i++) { - input.init(); - input.initOutlinePath(this.svgGroup_); - } - var icons = this.getIcons(); - for (i = 0; i < icons.length; i++) { - icons[i].createIcon(); - } - } - this.updateColour(); - this.updateMovable(); - if (!this.workspace.options.readOnly && !this.eventsInit_) { - Blockly.bindEventWithChecks_( - this.getSvgRoot(), 'mousedown', this, this.onMouseDown_); - } - this.eventsInit_ = true; - - if (!this.getSvgRoot().parentNode) { - this.workspace.getCanvas().appendChild(this.getSvgRoot()); - } -}; - -/** - * Select this block. Highlight it visually. - */ -Blockly.BlockSvg.prototype.select = function() { - if (this.isShadow() && this.getParent()) { - // Shadow blocks should not be selected. - this.getParent().select(); - return; - } - if (Blockly.selected == this) { - return; - } - var oldId = null; - if (Blockly.selected) { - oldId = Blockly.selected.id; - // Unselect any previously selected block. - Blockly.Events.disable(); - try { - Blockly.selected.unselect(); - } finally { - Blockly.Events.enable(); - } - } - var event = new Blockly.Events.Ui(null, 'selected', oldId, this.id); - event.workspaceId = this.workspace.id; - Blockly.Events.fire(event); - Blockly.selected = this; - this.addSelect(); -}; - -/** - * Unselect this block. Remove its highlighting. - */ -Blockly.BlockSvg.prototype.unselect = function() { - if (Blockly.selected != this) { - return; - } - var event = new Blockly.Events.Ui(null, 'selected', this.id, null); - event.workspaceId = this.workspace.id; - Blockly.Events.fire(event); - Blockly.selected = null; - this.removeSelect(); -}; - -/** - * Glow only this particular block, to highlight it visually as if it's running. - * @param {boolean} isGlowingBlock Whether the block should glow. - */ -Blockly.BlockSvg.prototype.setGlowBlock = function(isGlowingBlock) { - this.isGlowingBlock_ = isGlowingBlock; - this.updateColour(); -}; - -/** - * Glow the stack starting with this block, to highlight it visually as if it's running. - * @param {boolean} isGlowingStack Whether the stack starting with this block should glow. - */ -Blockly.BlockSvg.prototype.setGlowStack = function(isGlowingStack) { - this.isGlowingStack_ = isGlowingStack; - // Update the applied SVG filter if the property has changed - var svg = this.getSvgRoot(); - if (this.isGlowingStack_ && !svg.hasAttribute('filter')) { - var stackGlowFilterId = this.workspace.options.stackGlowFilterId || 'blocklyStackGlowFilter'; - svg.setAttribute('filter', 'url(#' + stackGlowFilterId + ')'); - } else if (!this.isGlowingStack_ && svg.hasAttribute('filter')) { - svg.removeAttribute('filter'); - } -}; - -/** - * Block's mutator icon (if any). - * @type {Blockly.Mutator} - */ -Blockly.BlockSvg.prototype.mutator = null; - -/** - * Block's comment icon (if any). - * @type {Blockly.Comment} - */ -Blockly.BlockSvg.prototype.comment = null; - -/** - * Block's warning icon (if any). - * @type {Blockly.Warning} - */ -Blockly.BlockSvg.prototype.warning = null; - -/** - * Returns a list of mutator, comment, and warning icons. - * @return {!Array} List of icons. - */ -Blockly.BlockSvg.prototype.getIcons = function() { - var icons = []; - if (this.mutator) { - icons.push(this.mutator); - } - if (this.comment) { - icons.push(this.comment); - } - if (this.warning) { - icons.push(this.warning); - } - return icons; -}; - -/** - * Set parent of this block to be a new block or null. - * @param {Blockly.BlockSvg} newParent New parent block. - */ -Blockly.BlockSvg.prototype.setParent = function(newParent) { - var oldParent = this.parentBlock_; - if (newParent == oldParent) { - return; - } - Blockly.Field.startCache(); - Blockly.BlockSvg.superClass_.setParent.call(this, newParent); - Blockly.Field.stopCache(); - - var svgRoot = this.getSvgRoot(); - - // Bail early if workspace is clearing, or we aren't rendered. - // We won't need to reattach ourselves anywhere. - if (this.workspace.isClearing || !svgRoot) { - return; - } - - var oldXY = this.getRelativeToSurfaceXY(); - if (newParent) { - newParent.getSvgRoot().appendChild(svgRoot); - var newXY = this.getRelativeToSurfaceXY(); - // Move the connections to match the child's new position. - this.moveConnections_(newXY.x - oldXY.x, newXY.y - oldXY.y); - // If we are a shadow block, inherit tertiary colour. - if (this.isShadow()) { - this.setColour(this.getColour(), this.getColourSecondary(), - newParent.getColourTertiary(), this.getColourQuaternary()); - } - } - // If we are losing a parent, we want to move our DOM element to the - // root of the workspace. - else if (oldParent) { - this.workspace.getCanvas().appendChild(svgRoot); - this.translate(oldXY.x, oldXY.y); - } - -}; - -/** - * Return the coordinates of the top-left corner of this block relative to the - * drawing surface's origin (0,0), in workspace units. - * If the block is on the workspace, (0, 0) is the origin of the workspace - * coordinate system. - * This does not change with workspace scale. - * @return {!goog.math.Coordinate} Object with .x and .y properties in - * workspace coordinates. - */ -Blockly.BlockSvg.prototype.getRelativeToSurfaceXY = function() { - // The drawing surface is relative to either the workspace canvas - // or to the drag surface group. - var x = 0; - var y = 0; - - var dragSurfaceGroup = this.useDragSurface_ ? - this.workspace.blockDragSurface_.getGroup() : null; - - var element = this.getSvgRoot(); - if (element) { - do { - // Loop through this block and every parent. - var xy = Blockly.utils.getRelativeXY(element); - x += xy.x; - y += xy.y; - // If this element is the current element on the drag surface, include - // the translation of the drag surface itself. - if (this.useDragSurface_ && - this.workspace.blockDragSurface_.getCurrentBlock() == element) { - var surfaceTranslation = this.workspace.blockDragSurface_.getSurfaceTranslation(); - x += surfaceTranslation.x; - y += surfaceTranslation.y; - } - element = element.parentNode; - } while (element && element != this.workspace.getCanvas() && - element != dragSurfaceGroup); - } - return new goog.math.Coordinate(x, y); -}; - -/** - * Move a block by a relative offset. - * @param {number} dx Horizontal offset in workspace units. - * @param {number} dy Vertical offset in workspace units. - */ -Blockly.BlockSvg.prototype.moveBy = function(dx, dy) { - goog.asserts.assert(!this.parentBlock_, 'Block has parent.'); - var eventsEnabled = Blockly.Events.isEnabled(); - if (eventsEnabled) { - var event = new Blockly.Events.BlockMove(this); - } - var xy = this.getRelativeToSurfaceXY(); - this.translate(xy.x + dx, xy.y + dy); - this.moveConnections_(dx, dy); - if (eventsEnabled) { - event.recordNew(); - Blockly.Events.fire(event); - } - this.workspace.resizeContents(); -}; - -/** - * Transforms a block by setting the translation on the transform attribute - * of the block's SVG. - * @param {number} x The x coordinate of the translation in workspace units. - * @param {number} y The y coordinate of the translation in workspace units. - */ -Blockly.BlockSvg.prototype.translate = function(x, y) { - this.getSvgRoot().setAttribute('transform', - 'translate(' + x + ',' + y + ')'); -}; - -/** - * Move this block to its workspace's drag surface, accounting for positioning. - * Generally should be called at the same time as setDragging_(true). - * Does nothing if useDragSurface_ is false. - * @private - */ -Blockly.BlockSvg.prototype.moveToDragSurface_ = function() { - if (!this.useDragSurface_) { - return; - } - // The translation for drag surface blocks, - // is equal to the current relative-to-surface position, - // to keep the position in sync as it move on/off the surface. - // This is in workspace coordinates. - var xy = this.getRelativeToSurfaceXY(); - this.clearTransformAttributes_(); - this.workspace.blockDragSurface_.translateSurface(xy.x, xy.y); - // Execute the move on the top-level SVG component - this.workspace.blockDragSurface_.setBlocksAndShow(this.getSvgRoot()); -}; - -/** - * Move this block back to the workspace block canvas. - * Generally should be called at the same time as setDragging_(false). - * Does nothing if useDragSurface_ is false. - * @param {!goog.math.Coordinate} newXY The position the block should take on - * on the workspace canvas, in workspace coordinates. - * @private - */ -Blockly.BlockSvg.prototype.moveOffDragSurface_ = function(newXY) { - if (!this.useDragSurface_) { - return; - } - // Translate to current position, turning off 3d. - this.translate(newXY.x, newXY.y); - this.workspace.blockDragSurface_.clearAndHide(this.workspace.getCanvas()); -}; - -/** - * Move this block during a drag, taking into account whether we are using a - * drag surface to translate blocks. - * This block must be a top-level block. - * @param {!goog.math.Coordinate} newLoc The location to translate to, in - * workspace coordinates. - * @package - */ -Blockly.BlockSvg.prototype.moveDuringDrag = function(newLoc) { - if (this.useDragSurface_) { - this.workspace.blockDragSurface_.translateSurface(newLoc.x, newLoc.y); - } else { - this.svgGroup_.translate_ = 'translate(' + newLoc.x + ',' + newLoc.y + ')'; - this.svgGroup_.setAttribute('transform', - this.svgGroup_.translate_ + this.svgGroup_.skew_); - } -}; - -/** - * Clear the block of transform="..." attributes. - * Used when the block is switching from 3d to 2d transform or vice versa. - * @private - */ -Blockly.BlockSvg.prototype.clearTransformAttributes_ = function() { - Blockly.utils.removeAttribute(this.getSvgRoot(), 'transform'); -}; - -/** - * Snap this block to the nearest grid point. - */ -Blockly.BlockSvg.prototype.snapToGrid = function() { - if (!this.workspace) { - return; // Deleted block. - } - if (this.workspace.isDragging()) { - return; // Don't bump blocks during a drag. - } - if (this.getParent()) { - return; // Only snap top-level blocks. - } - if (this.isInFlyout) { - return; // Don't move blocks around in a flyout. - } - var grid = this.workspace.getGrid(); - if (!grid || !grid.shouldSnap()) { - return; // Config says no snapping. - } - var spacing = grid.getSpacing(); - var half = spacing / 2; - var xy = this.getRelativeToSurfaceXY(); - var dx = Math.round((xy.x - half) / spacing) * spacing + half - xy.x; - var dy = Math.round((xy.y - half) / spacing) * spacing + half - xy.y; - dx = Math.round(dx); - dy = Math.round(dy); - if (dx != 0 || dy != 0) { - this.moveBy(dx, dy); - } -}; - -/** - * Returns the coordinates of a bounding box describing the dimensions of this - * block and any blocks stacked below it. - * Coordinate system: workspace coordinates. - * @return {!{topLeft: goog.math.Coordinate, bottomRight: goog.math.Coordinate}} - * Object with top left and bottom right coordinates of the bounding box. - */ -Blockly.BlockSvg.prototype.getBoundingRectangle = function() { - var blockXY = this.getRelativeToSurfaceXY(this); - var blockBounds = this.getHeightWidth(); - var topLeft; - var bottomRight; - if (this.RTL) { - topLeft = new goog.math.Coordinate(blockXY.x - blockBounds.width, - blockXY.y); - bottomRight = new goog.math.Coordinate(blockXY.x, - blockXY.y + blockBounds.height); - } else { - topLeft = new goog.math.Coordinate(blockXY.x, blockXY.y); - bottomRight = new goog.math.Coordinate(blockXY.x + blockBounds.width, - blockXY.y + blockBounds.height); - } - - return {topLeft: topLeft, bottomRight: bottomRight}; -}; - -/** - * Set block opacity for SVG rendering. - * @param {number} opacity Intended opacity, betweeen 0 and 1 - */ -Blockly.BlockSvg.prototype.setOpacity = function(opacity) { - this.opacity_ = opacity; - if (this.rendered) { - this.updateColour(); - } -}; - -/** - * Get block opacity for SVG rendering. - * @return {number} Intended opacity, betweeen 0 and 1 - */ -Blockly.BlockSvg.prototype.getOpacity = function() { - return this.opacity_; -}; - -/** - * Set whether the block is collapsed or not. - * @param {boolean} collapsed True if collapsed. - */ -Blockly.BlockSvg.prototype.setCollapsed = function(collapsed) { - if (this.collapsed_ == collapsed) { - return; - } - var renderList = []; - // Show/hide the inputs. - for (var i = 0, input; input = this.inputList[i]; i++) { - renderList.push.apply(renderList, input.setVisible(!collapsed)); - } - - var COLLAPSED_INPUT_NAME = '_TEMP_COLLAPSED_INPUT'; - if (collapsed) { - var icons = this.getIcons(); - for (var i = 0; i < icons.length; i++) { - icons[i].setVisible(false); - } - var text = this.toString(Blockly.COLLAPSE_CHARS); - this.appendDummyInput(COLLAPSED_INPUT_NAME).appendField(text).init(); - } else { - this.removeInput(COLLAPSED_INPUT_NAME); - // Clear any warnings inherited from enclosed blocks. - this.setWarningText(null); - } - Blockly.BlockSvg.superClass_.setCollapsed.call(this, collapsed); - - if (!renderList.length) { - // No child blocks, just render this block. - renderList[0] = this; - } - if (this.rendered) { - for (var i = 0, block; block = renderList[i]; i++) { - block.render(); - } - // Don't bump neighbours. - // Although bumping neighbours would make sense, users often collapse - // all their functions and store them next to each other. Expanding and - // bumping causes all their definitions to go out of alignment. - } -}; - -/** - * Open the next (or previous) FieldTextInput. - * @param {Blockly.Field|Blockly.Block} start Current location. - * @param {boolean} forward If true go forward, otherwise backward. - */ -Blockly.BlockSvg.prototype.tab = function(start, forward) { - var list = this.createTabList_(); - var i = list.indexOf(start); - if (i == -1) { - // No start location, start at the beginning or end. - i = forward ? -1 : list.length; - } - var target = list[forward ? i + 1 : i - 1]; - if (!target) { - // Ran off of list. - // If there is an output, tab up to that block. - var outputBlock = this.outputConnection && this.outputConnection.targetBlock(); - if (outputBlock) { - outputBlock.tab(this, forward); - } else { // Otherwise, go to next / previous block, depending on value of `forward` - var block = forward ? this.getNextBlock() : this.getPreviousBlock(); - if (block) { - block.tab(this, forward); - } - } - } else if (target instanceof Blockly.Field) { - target.showEditor_(); - } else { - target.tab(null, forward); - } -}; - -/** - * Create an ordered list of all text fields and connected inputs. - * @return {!Array.} The ordered list. - * @private - */ -Blockly.BlockSvg.prototype.createTabList_ = function() { - // This function need not be efficient since it runs once on a keypress. - var list = []; - for (var i = 0, input; input = this.inputList[i]; i++) { - for (var j = 0, field; field = input.fieldRow[j]; j++) { - if (field instanceof Blockly.FieldTextInput) { - // TODO(# 1276): Also support dropdown fields. - list.push(field); - } - } - if (input.connection) { - var block = input.connection.targetBlock(); - if (block) { - list.push(block); - } - } - } - return list; -}; - -/** - * Handle a mouse-down on an SVG block. - * @param {!Event} e Mouse down event or touch start event. - * @private - */ -Blockly.BlockSvg.prototype.onMouseDown_ = function(e) { - var gesture = this.workspace && this.workspace.getGesture(e); - if (gesture) { - gesture.handleBlockStart(e, this); - } -}; - -/** - * Load the block's help page in a new window. - * @private - */ -Blockly.BlockSvg.prototype.showHelp_ = function() { - var url = goog.isFunction(this.helpUrl) ? this.helpUrl() : this.helpUrl; - if (url) { - // @todo rewrite - alert(url); - } -}; - - -/** - * Show the context menu for this block. - * @param {!Event} e Mouse event. - * @private - */ -Blockly.BlockSvg.prototype.showContextMenu_ = function(e) { - if (this.workspace.options.readOnly || !this.contextMenu) { - return; - } - // Save the current block in a variable for use in closures. - var block = this; - var menuOptions = []; - if (this.isDeletable() && this.isMovable() && !block.isInFlyout) { - menuOptions.push( - Blockly.ContextMenu.blockDuplicateOption(block, e)); - if (this.isEditable() && this.workspace.options.comments) { - menuOptions.push(Blockly.ContextMenu.blockCommentOption(block)); - } - menuOptions.push(Blockly.ContextMenu.blockDeleteOption(block)); - } else if (this.parentBlock_ && this.isShadow_) { - this.parentBlock_.showContextMenu_(e); - return; - } - - // Allow the block to add or modify menuOptions. - if (this.customContextMenu) { - this.customContextMenu(menuOptions); - } - Blockly.ContextMenu.show(e, menuOptions, this.RTL); - Blockly.ContextMenu.currentBlock = this; -}; - -/** - * Move the connections for this block and all blocks attached under it. - * Also update any attached bubbles. - * @param {number} dx Horizontal offset from current location, in workspace - * units. - * @param {number} dy Vertical offset from current location, in workspace - * units. - * @private - */ -Blockly.BlockSvg.prototype.moveConnections_ = function(dx, dy) { - if (!this.rendered) { - // Rendering is required to lay out the blocks. - // This is probably an invisible block attached to a collapsed block. - return; - } - var myConnections = this.getConnections_(false); - for (var i = 0; i < myConnections.length; i++) { - myConnections[i].moveBy(dx, dy); - } - var icons = this.getIcons(); - for (i = 0; i < icons.length; i++) { - icons[i].computeIconLocation(); - } - - // Recurse through all blocks attached under this one. - for (i = 0; i < this.childBlocks_.length; i++) { - this.childBlocks_[i].moveConnections_(dx, dy); - } -}; - -/** - * Recursively adds or removes the dragging class to this node and its children. - * @param {boolean} adding True if adding, false if removing. - * @package - */ -Blockly.BlockSvg.prototype.setDragging = function(adding) { - if (adding) { - var group = this.getSvgRoot(); - group.translate_ = ''; - group.skew_ = ''; - Blockly.draggingConnections_ = - Blockly.draggingConnections_.concat(this.getConnections_(true)); - Blockly.utils.addClass( - /** @type {!Element} */ (this.svgGroup_), 'blocklyDragging'); - } else { - Blockly.draggingConnections_ = []; - Blockly.utils.removeClass( - /** @type {!Element} */ (this.svgGroup_), 'blocklyDragging'); - } - // Recurse through all blocks attached under this one. - for (var i = 0; i < this.childBlocks_.length; i++) { - this.childBlocks_[i].setDragging(adding); - } -}; - -/** - * Add or remove the UI indicating if this block is movable or not. - */ -Blockly.BlockSvg.prototype.updateMovable = function() { - if (this.isMovable()) { - Blockly.utils.addClass( - /** @type {!Element} */ (this.svgGroup_), 'blocklyDraggable'); - } else { - Blockly.utils.removeClass( - /** @type {!Element} */ (this.svgGroup_), 'blocklyDraggable'); - } -}; - -/** - * Set whether this block is movable or not. - * @param {boolean} movable True if movable. - */ -Blockly.BlockSvg.prototype.setMovable = function(movable) { - Blockly.BlockSvg.superClass_.setMovable.call(this, movable); - this.updateMovable(); -}; - -/** - * Set whether this block is editable or not. - * @param {boolean} editable True if editable. - */ -Blockly.BlockSvg.prototype.setEditable = function(editable) { - Blockly.BlockSvg.superClass_.setEditable.call(this, editable); - var icons = this.getIcons(); - for (var i = 0; i < icons.length; i++) { - icons[i].updateEditable(); - } -}; - -/** - * Set whether this block is a shadow block or not. - * @param {boolean} shadow True if a shadow. - */ -Blockly.BlockSvg.prototype.setShadow = function(shadow) { - Blockly.BlockSvg.superClass_.setShadow.call(this, shadow); - this.updateColour(); -}; - -/** - * Set whether this block is an insertion marker block or not. - * @param {boolean} insertionMarker True if an insertion marker. - * @param {Number=} opt_minWidth Optional minimum width of the marker. - */ -Blockly.BlockSvg.prototype.setInsertionMarker = function(insertionMarker, opt_minWidth) { - Blockly.BlockSvg.superClass_.setInsertionMarker.call(this, insertionMarker); - this.insertionMarkerMinWidth_ = opt_minWidth; - this.updateColour(); -}; - -/** - * Return the root node of the SVG or null if none exists. - * @return {Element} The root SVG node (probably a group). - */ -Blockly.BlockSvg.prototype.getSvgRoot = function() { - return this.svgGroup_; -}; - -/** - * Dispose of this block. - * @param {boolean} healStack If true, then try to heal any gap by connecting - * the next statement with the previous statement. Otherwise, dispose of - * all children of this block. - * @param {boolean} animate If true, show a disposal animation and sound. - */ -Blockly.BlockSvg.prototype.dispose = function(healStack, animate) { - if (!this.workspace) { - // The block has already been deleted. - return; - } - Blockly.Tooltip.hide(); - Blockly.Field.startCache(); - // Save the block's workspace temporarily so we can resize the - // contents once the block is disposed. - var blockWorkspace = this.workspace; - // If this block is being dragged, unlink the mouse events. - if (Blockly.selected == this) { - this.unselect(); - this.workspace.cancelCurrentGesture(); - } - // If this block has a context menu open, close it. - if (Blockly.ContextMenu.currentBlock == this) { - Blockly.ContextMenu.hide(); - } - - if (animate && this.rendered) { - this.unplug(healStack); - Blockly.BlockAnimations.disposeUiEffect(this); - } - // Stop rerendering. - this.rendered = false; - - Blockly.Events.disable(); - try { - var icons = this.getIcons(); - for (var i = 0; i < icons.length; i++) { - icons[i].dispose(); - } - } finally { - Blockly.Events.enable(); - } - Blockly.BlockSvg.superClass_.dispose.call(this, healStack); - - goog.dom.removeNode(this.svgGroup_); - blockWorkspace.resizeContents(); - // Sever JavaScript to DOM connections. - this.svgGroup_ = null; - this.svgPath_ = null; - Blockly.Field.stopCache(); -}; - -/** - * Enable or disable a block. - */ -Blockly.BlockSvg.prototype.updateDisabled = function() { - // not supported -}; - -/** - * Returns the comment on this block (or '' if none). - * @return {string} Block's comment. - */ -Blockly.BlockSvg.prototype.getCommentText = function() { - if (this.comment) { - var comment = this.comment.getText(); - // Trim off trailing whitespace. - return comment.replace(/\s+$/, '').replace(/ +\n/g, '\n'); - } - return ''; -}; - -/** - * Set this block's comment text. - * @param {?string} text The text, or null to delete. - * @param {string=} commentId Id of the comment, or a new one will be generated if not provided. - * @param {number=} commentX Optional x position for scratch comment in workspace coordinates - * @param {number=} commentY Optional y position for scratch comment in workspace coordinates - * @param {boolean=} minimized Optional minimized state for scratch comment, defaults to false - */ -Blockly.BlockSvg.prototype.setCommentText = function(text, commentId, - commentX, commentY, minimized) { - var changedState = false; - if (goog.isString(text)) { - if (!this.comment) { - this.comment = new Blockly.ScratchBlockComment(this, text, commentId, - commentX, commentY, minimized); - changedState = true; - } else { - this.comment.setText(/** @type {string} */ (text)); - } - } else { - if (this.comment) { - this.comment.dispose(); - changedState = true; - } - } - if (changedState && this.rendered) { - this.render(); - if (goog.isString(text)) { - this.comment.setVisible(true); - } - // Adding or removing a comment icon will cause the block to change shape. - this.bumpNeighbours_(); - } -}; - -/** - * Set this block's warning text. - * @param {?string} text The text, or null to delete. - * @param {string=} opt_id An optional ID for the warning text to be able to - * maintain multiple warnings. - */ -Blockly.BlockSvg.prototype.setWarningText = function(text, opt_id) { - if (!this.setWarningText.pid_) { - // Create a database of warning PIDs. - // Only runs once per block (and only those with warnings). - this.setWarningText.pid_ = Object.create(null); - } - var id = opt_id || ''; - if (!id) { - // Kill all previous pending processes, this edit supersedes them all. - for (var n in this.setWarningText.pid_) { - clearTimeout(this.setWarningText.pid_[n]); - delete this.setWarningText.pid_[n]; - } - } else if (this.setWarningText.pid_[id]) { - // Only queue up the latest change. Kill any earlier pending process. - clearTimeout(this.setWarningText.pid_[id]); - delete this.setWarningText.pid_[id]; - } - if (this.workspace.isDragging()) { - // Don't change the warning text during a drag. - // Wait until the drag finishes. - var thisBlock = this; - this.setWarningText.pid_[id] = setTimeout(function() { - if (thisBlock.workspace) { // Check block wasn't deleted. - delete thisBlock.setWarningText.pid_[id]; - thisBlock.setWarningText(text, id); - } - }, 100); - return; - } - if (this.isInFlyout) { - text = null; - } - - var changedState = false; - if (goog.isString(text)) { - if (!this.warning) { - this.warning = new Blockly.Warning(this); - changedState = true; - } - this.warning.setText(/** @type {string} */ (text), id); - } else { - // Dispose all warnings if no ID is given. - if (this.warning && !id) { - this.warning.dispose(); - changedState = true; - } else if (this.warning) { - var oldText = this.warning.getText(); - this.warning.setText('', id); - var newText = this.warning.getText(); - if (!newText) { - this.warning.dispose(); - } - changedState = oldText != newText; - } - } - if (changedState && this.rendered) { - this.render(); - // Adding or removing a warning icon will cause the block to change shape. - this.bumpNeighbours_(); - } -}; - -/** - * Give this block a mutator dialog. - * @param {Blockly.Mutator} mutator A mutator dialog instance or null to remove. - */ -Blockly.BlockSvg.prototype.setMutator = function(mutator) { - if (this.mutator && this.mutator !== mutator) { - this.mutator.dispose(); - } - if (mutator) { - mutator.block_ = this; - this.mutator = mutator; - mutator.createIcon(); - } -}; - -/** - * Select this block. Highlight it visually. - */ -Blockly.BlockSvg.prototype.addSelect = function() { - Blockly.utils.addClass( - /** @type {!Element} */ (this.svgGroup_), 'blocklySelected'); -}; - -/** - * Unselect this block. Remove its highlighting. - */ -Blockly.BlockSvg.prototype.removeSelect = function() { - Blockly.utils.removeClass( - /** @type {!Element} */ (this.svgGroup_), 'blocklySelected'); -}; - -/** - * Update the cursor over this block by adding or removing a class. - * @param {boolean} letMouseThrough True if the blocks should ignore pointer - * events, false otherwise. - * @package - */ -Blockly.BlockSvg.prototype.setMouseThroughStyle = function(letMouseThrough) { - if (letMouseThrough) { - Blockly.utils.addClass(/** @type {!Element} */ (this.svgGroup_), - 'blocklyDraggingMouseThrough'); - } else { - Blockly.utils.removeClass(/** @type {!Element} */ (this.svgGroup_), - 'blocklyDraggingMouseThrough'); - } -}; - -/** - * Update the cursor over this block by adding or removing a class. - * @param {boolean} enable True if the delete cursor should be shown, false - * otherwise. - * @package - */ -Blockly.BlockSvg.prototype.setDeleteStyle = function(enable) { - if (enable) { - Blockly.utils.addClass(/** @type {!Element} */ (this.svgGroup_), - 'blocklyDraggingDelete'); - } else { - Blockly.utils.removeClass(/** @type {!Element} */ (this.svgGroup_), - 'blocklyDraggingDelete'); - } -}; - -// Overrides of functions on Blockly.Block that take into account whether the -// block has been rendered. - -/** - * Change the colour of a block. - * @param {number|string} colour HSV hue value, or #RRGGBB string. - * @param {number|string} colourSecondary Secondary HSV hue value, or #RRGGBB - * string. - * @param {number|string} colourTertiary Tertiary HSV hue value, or #RRGGBB - * string. - * @param {number|string} colourQuaternary Quaternary HSV hue value, or #RRGGBB - * string. - */ -Blockly.BlockSvg.prototype.setColour = function(colour, colourSecondary, - colourTertiary, colourQuaternary) { - Blockly.BlockSvg.superClass_.setColour.call(this, colour, colourSecondary, - colourTertiary, colourQuaternary); - - if (this.rendered) { - this.updateColour(); - } -}; - -/** - * Move this block to the front of the visible workspace. - * tags do not respect z-index so SVG renders them in the - * order that they are in the DOM. By placing this block first within the - * block group's , it will render on top of any other blocks. - * @package - */ -Blockly.BlockSvg.prototype.bringToFront = function() { - var block = this; - do { - var root = block.getSvgRoot(); - root.parentNode.appendChild(root); - block = block.getParent(); - } while (block); -}; - -/** - * Set whether this block can chain onto the bottom of another block. - * @param {boolean} newBoolean True if there can be a previous statement. - * @param {(string|Array.|null)=} opt_check Statement type or - * list of statement types. Null/undefined if any type could be connected. - */ -Blockly.BlockSvg.prototype.setPreviousStatement = function(newBoolean, - opt_check) { - Blockly.BlockSvg.superClass_.setPreviousStatement.call(this, newBoolean, - opt_check); - - if (this.rendered) { - this.render(); - this.bumpNeighbours_(); - } -}; - -/** - * Set whether another block can chain onto the bottom of this block. - * @param {boolean} newBoolean True if there can be a next statement. - * @param {(string|Array.|null)=} opt_check Statement type or - * list of statement types. Null/undefined if any type could be connected. - */ -Blockly.BlockSvg.prototype.setNextStatement = function(newBoolean, opt_check) { - Blockly.BlockSvg.superClass_.setNextStatement.call(this, newBoolean, - opt_check); - - if (this.rendered) { - this.render(); - this.bumpNeighbours_(); - } -}; - -/** - * Set whether this block returns a value. - * @param {boolean} newBoolean True if there is an output. - * @param {(string|Array.|null)=} opt_check Returned type or list - * of returned types. Null or undefined if any type could be returned - * (e.g. variable get). - */ -Blockly.BlockSvg.prototype.setOutput = function(newBoolean, opt_check) { - Blockly.BlockSvg.superClass_.setOutput.call(this, newBoolean, opt_check); - - if (this.rendered) { - this.render(); - this.bumpNeighbours_(); - } -}; - -/** - * Set whether value inputs are arranged horizontally or vertically. - * @param {boolean} newBoolean True if inputs are horizontal. - */ -Blockly.BlockSvg.prototype.setInputsInline = function(newBoolean) { - Blockly.BlockSvg.superClass_.setInputsInline.call(this, newBoolean); - - if (this.rendered) { - this.render(); - this.bumpNeighbours_(); - } -}; - -/** - * Remove an input from this block. - * @param {string} name The name of the input. - * @param {boolean=} opt_quiet True to prevent error if input is not present. - * @throws {goog.asserts.AssertionError} if the input is not present and - * opt_quiet is not true. - */ -Blockly.BlockSvg.prototype.removeInput = function(name, opt_quiet) { - Blockly.BlockSvg.superClass_.removeInput.call(this, name, opt_quiet); - - if (this.rendered) { - this.render(); - // Removing an input will cause the block to change shape. - this.bumpNeighbours_(); - } -}; - -/** - * Move a numbered input to a different location on this block. - * @param {number} inputIndex Index of the input to move. - * @param {number} refIndex Index of input that should be after the moved input. - */ -Blockly.BlockSvg.prototype.moveNumberedInputBefore = function( - inputIndex, refIndex) { - Blockly.BlockSvg.superClass_.moveNumberedInputBefore.call(this, inputIndex, - refIndex); - - if (this.rendered) { - this.render(); - // Moving an input will cause the block to change shape. - this.bumpNeighbours_(); - } -}; - -/** - * Add a value input, statement input or local variable to this block. - * @param {number} type Either Blockly.INPUT_VALUE or Blockly.NEXT_STATEMENT or - * Blockly.DUMMY_INPUT. - * @param {string} name Language-neutral identifier which may used to find this - * input again. Should be unique to this block. - * @return {!Blockly.Input} The input object created. - * @private - */ -Blockly.BlockSvg.prototype.appendInput_ = function(type, name) { - var input = Blockly.BlockSvg.superClass_.appendInput_.call(this, type, name); - - if (this.rendered) { - this.render(); - // Adding an input will cause the block to change shape. - this.bumpNeighbours_(); - } - return input; -}; - -/** - * Returns connections originating from this block. - * @param {boolean} all If true, return all connections even hidden ones. - * Otherwise, for a non-rendered block return an empty list, and for a - * collapsed block don't return inputs connections. - * @return {!Array.} Array of connections. - * @package - */ -Blockly.BlockSvg.prototype.getConnections_ = function(all) { - var myConnections = []; - if (all || this.rendered) { - if (this.outputConnection) { - myConnections.push(this.outputConnection); - } - if (this.previousConnection) { - myConnections.push(this.previousConnection); - } - if (this.nextConnection) { - myConnections.push(this.nextConnection); - } - if (all || !this.collapsed_) { - for (var i = 0, input; input = this.inputList[i]; i++) { - if (input.connection) { - myConnections.push(input.connection); - } - } - } - } - return myConnections; -}; - -/** - * Create a connection of the specified type. - * @param {number} type The type of the connection to create. - * @return {!Blockly.RenderedConnection} A new connection of the specified type. - * @private - */ -Blockly.BlockSvg.prototype.makeConnection_ = function(type) { - return new Blockly.RenderedConnection(this, type); -}; - -/** - * Bump unconnected blocks out of alignment. Two blocks which aren't actually - * connected should not coincidentally line up on screen. - * @private - */ -Blockly.BlockSvg.prototype.bumpNeighbours_ = function() { - if (!this.workspace) { - return; // Deleted block. - } - if (this.workspace.isDragging()) { - return; // Don't bump blocks during a drag. - } - var rootBlock = this.getRootBlock(); - if (rootBlock.isInFlyout) { - return; // Don't move blocks around in a flyout. - } - // Loop through every connection on this block. - var myConnections = this.getConnections_(false); - for (var i = 0, connection; connection = myConnections[i]; i++) { - - // Spider down from this block bumping all sub-blocks. - if (connection.isConnected() && connection.isSuperior()) { - connection.targetBlock().bumpNeighbours_(); - } - - var neighbours = connection.neighbours_(Blockly.SNAP_RADIUS); - for (var j = 0, otherConnection; otherConnection = neighbours[j]; j++) { - - // If both connections are connected, that's probably fine. But if - // either one of them is unconnected, then there could be confusion. - if (!connection.isConnected() || !otherConnection.isConnected()) { - // Only bump blocks if they are from different tree structures. - if (otherConnection.getSourceBlock().getRootBlock() != rootBlock) { - - // Always bump the inferior block. - if (connection.isSuperior()) { - otherConnection.bumpAwayFrom_(connection); - } else { - connection.bumpAwayFrom_(otherConnection); - } - } - } - } - } -}; - -/** - * Schedule snapping to grid and bumping neighbours to occur after a brief - * delay. - * @package - */ -Blockly.BlockSvg.prototype.scheduleSnapAndBump = function() { - var block = this; - // Ensure that any snap and bump are part of this move's event group. - var group = Blockly.Events.getGroup(); - - setTimeout(function() { - Blockly.Events.setGroup(group); - block.snapToGrid(); - Blockly.Events.setGroup(false); - }, Blockly.BUMP_DELAY / 2); - - setTimeout(function() { - Blockly.Events.setGroup(group); - block.bumpNeighbours_(); - Blockly.Events.setGroup(false); - }, Blockly.BUMP_DELAY); -}; diff --git a/core/blockly.js b/core/blockly.js deleted file mode 100644 index fa0b484896..0000000000 --- a/core/blockly.js +++ /dev/null @@ -1,622 +0,0 @@ -/** - * @license - * Visual Blocks Editor - * - * Copyright 2011 Google Inc. - * https://developers.google.com/blockly/ - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @fileoverview Core JavaScript library for Blockly. - * @author fraser@google.com (Neil Fraser) - */ -'use strict'; - -/** - * The top level namespace used to access the Blockly library. - * @namespace Blockly - **/ -goog.provide('Blockly'); - -goog.require('Blockly.BlockSvg.render'); -goog.require('Blockly.DropDownDiv'); -goog.require('Blockly.Events'); -goog.require('Blockly.FieldAngle'); -goog.require('Blockly.FieldCheckbox'); -goog.require('Blockly.FieldColour'); -goog.require('Blockly.FieldColourSlider'); -// Date picker commented out since it increases footprint by 60%. -// Add it only if you need it. -//goog.require('Blockly.FieldDate'); -goog.require('Blockly.FieldDropdown'); -goog.require('Blockly.FieldIconMenu'); -goog.require('Blockly.FieldImage'); -goog.require('Blockly.FieldNote'); -goog.require('Blockly.FieldTextInput'); -goog.require('Blockly.FieldTextInputRemovable'); -goog.require('Blockly.FieldTextDropdown'); -goog.require('Blockly.FieldNumber'); -goog.require('Blockly.FieldNumberDropdown'); -goog.require('Blockly.FieldMatrix'); -goog.require('Blockly.FieldVariable'); -goog.require('Blockly.FieldVerticalSeparator'); -goog.require('Blockly.Generator'); -goog.require('Blockly.Msg'); -goog.require('Blockly.Procedures'); -goog.require('Blockly.ScratchMsgs'); -goog.require('Blockly.Toolbox'); -goog.require('Blockly.Touch'); -goog.require('Blockly.WidgetDiv'); -goog.require('Blockly.WorkspaceSvg'); -goog.require('Blockly.constants'); -goog.require('Blockly.inject'); -goog.require('Blockly.utils'); -goog.require('goog.color'); - - -// Turn off debugging when compiled. -/* eslint-disable no-unused-vars */ -var CLOSURE_DEFINES = {'goog.DEBUG': false}; -/* eslint-enable no-unused-vars */ - -/** - * The main workspace most recently used. - * Set by Blockly.WorkspaceSvg.prototype.markFocused - * @type {Blockly.Workspace} - */ -Blockly.mainWorkspace = null; - -/** - * Currently selected block. - * @type {Blockly.Block} - */ -Blockly.selected = null; - -/** - * All of the connections on blocks that are currently being dragged. - * @type {!Array.} - * @private - */ -Blockly.draggingConnections_ = []; - -/** - * Contents of the local clipboard. - * @type {Element} - * @private - */ -Blockly.clipboardXml_ = null; - -/** - * Source of the local clipboard. - * @type {Blockly.WorkspaceSvg} - * @private - */ -Blockly.clipboardSource_ = null; - -/** - * Cached value for whether 3D is supported. - * @type {!boolean} - * @private - */ -Blockly.cache3dSupported_ = null; - -/** - * Convert a hue (HSV model) into an RGB hex triplet. - * @param {number} hue Hue on a colour wheel (0-360). - * @return {string} RGB code, e.g. '#5ba65b'. - */ -Blockly.hueToRgb = function(hue) { - return goog.color.hsvToHex(hue, Blockly.HSV_SATURATION, - Blockly.HSV_VALUE * 255); -}; - -/** - * Returns the dimensions of the specified SVG image. - * @param {!Element} svg SVG image. - * @return {!Object} Contains width and height properties. - */ -Blockly.svgSize = function(svg) { - return { - width: svg.cachedWidth_, - height: svg.cachedHeight_ - }; -}; - -/** - * Size the workspace when the contents change. This also updates - * scrollbars accordingly. - * @param {!Blockly.WorkspaceSvg} workspace The workspace to resize. - */ -Blockly.resizeSvgContents = function(workspace) { - workspace.resizeContents(); -}; - -/** - * Size the SVG image to completely fill its container. Call this when the view - * actually changes sizes (e.g. on a window resize/device orientation change). - * See Blockly.resizeSvgContents to resize the workspace when the contents - * change (e.g. when a block is added or removed). - * Record the height/width of the SVG image. - * @param {!Blockly.WorkspaceSvg} workspace Any workspace in the SVG. - */ -Blockly.svgResize = function(workspace) { - var mainWorkspace = workspace; - while (mainWorkspace.options.parentWorkspace) { - mainWorkspace = mainWorkspace.options.parentWorkspace; - } - var svg = mainWorkspace.getParentSvg(); - var div = svg.parentNode; - if (!div) { - // Workspace deleted, or something. - return; - } - var width = div.offsetWidth; - var height = div.offsetHeight; - if (svg.cachedWidth_ != width) { - svg.setAttribute('width', width + 'px'); - svg.cachedWidth_ = width; - } - if (svg.cachedHeight_ != height) { - svg.setAttribute('height', height + 'px'); - svg.cachedHeight_ = height; - } - mainWorkspace.resize(); -}; - -/** - * Handle a key-down on SVG drawing surface. Does nothing if the main workspace is not visible. - * @param {!Event} e Key down event. - * @private - */ -// TODO (https://github.com/google/blockly/issues/1998) handle cases where there are multiple workspaces -// and non-main workspaces are able to accept input. -Blockly.onKeyDown_ = function(e) { - if (Blockly.mainWorkspace.options.readOnly || Blockly.utils.isTargetInput(e) - || (Blockly.mainWorkspace.rendered && !Blockly.mainWorkspace.isVisible())) { - // No key actions on readonly workspaces. - // When focused on an HTML text input widget, don't trap any keys. - // Ignore keypresses on rendered workspaces that have been explicitly - // hidden. - return; - } - var deleteBlock = false; - if (e.keyCode == 27) { - // Pressing esc closes the context menu and any drop-down - Blockly.hideChaff(); - Blockly.DropDownDiv.hide(); - } else if (e.keyCode == 8 || e.keyCode == 46) { - // Delete or backspace. - // Stop the browser from going back to the previous page. - // Do this first to prevent an error in the delete code from resulting in - // data loss. - e.preventDefault(); - // Don't delete while dragging. Jeez. - if (Blockly.mainWorkspace.isDragging()) { - return; - } - if (Blockly.selected && Blockly.selected.isDeletable()) { - deleteBlock = true; - } - } else if (e.altKey || e.ctrlKey || e.metaKey) { - // Don't use meta keys during drags. - if (Blockly.mainWorkspace.isDragging()) { - return; - } - if (Blockly.selected && - Blockly.selected.isDeletable() && Blockly.selected.isMovable()) { - // Don't allow copying immovable or undeletable blocks. The next step - // would be to paste, which would create additional undeletable/immovable - // blocks on the workspace. - if (e.keyCode == 67) { - // 'c' for copy. - Blockly.hideChaff(); - Blockly.copy_(Blockly.selected); - } else if (e.keyCode == 88 && !Blockly.selected.workspace.isFlyout) { - // 'x' for cut, but not in a flyout. - // Don't even copy the selected item in the flyout. - Blockly.copy_(Blockly.selected); - deleteBlock = true; - } - } - if (e.keyCode == 86) { - // 'v' for paste. - if (Blockly.clipboardXml_) { - Blockly.Events.setGroup(true); - // Pasting always pastes to the main workspace, even if the copy started - // in a flyout workspace. - var workspace = Blockly.clipboardSource_; - if (workspace.isFlyout) { - workspace = workspace.targetWorkspace; - } - workspace.paste(Blockly.clipboardXml_); - Blockly.Events.setGroup(false); - } - } else if (e.keyCode == 90) { - // 'z' for undo 'Z' is for redo. - Blockly.hideChaff(); - Blockly.mainWorkspace.undo(e.shiftKey); - } - } - // Common code for delete and cut. - // Don't delete in the flyout. - if (deleteBlock && !Blockly.selected.workspace.isFlyout) { - Blockly.Events.setGroup(true); - Blockly.hideChaff(); - Blockly.selected.dispose(/* heal */ true, true); - Blockly.Events.setGroup(false); - } -}; - -/** - * Copy a block or workspace comment onto the local clipboard. - * @param {!Blockly.Block | !Blockly.WorkspaceComment} toCopy Block or Workspace Comment - * to be copied. - * @private - */ -Blockly.copy_ = function(toCopy) { - if (toCopy.isComment) { - var xml = toCopy.toXmlWithXY(); - } else { - var xml = Blockly.Xml.blockToDom(toCopy); - // Encode start position in XML. - var xy = toCopy.getRelativeToSurfaceXY(); - xml.setAttribute('x', toCopy.RTL ? -xy.x : xy.x); - xml.setAttribute('y', xy.y); - } - Blockly.clipboardXml_ = xml; - Blockly.clipboardSource_ = toCopy.workspace; -}; - -/** - * Duplicate this block and its children, or a workspace comment. - * @param {!Blockly.Block | !Blockly.WorkspaceComment} toDuplicate Block or - * Workspace Comment to be copied. - * @private - */ -Blockly.duplicate_ = function(toDuplicate) { - // Save the clipboard. - var clipboardXml = Blockly.clipboardXml_; - var clipboardSource = Blockly.clipboardSource_; - - // Create a duplicate via a copy/paste operation. - Blockly.copy_(toDuplicate); - toDuplicate.workspace.paste(Blockly.clipboardXml_); - - // Restore the clipboard. - Blockly.clipboardXml_ = clipboardXml; - Blockly.clipboardSource_ = clipboardSource; -}; - -/** - * Cancel the native context menu, unless the focus is on an HTML input widget. - * @param {!Event} e Mouse down event. - * @private - */ -Blockly.onContextMenu_ = function(e) { - if (!Blockly.utils.isTargetInput(e)) { - // When focused on an HTML text input widget, don't cancel the context menu. - e.preventDefault(); - } -}; - -/** - * Close tooltips, context menus, dropdown selections, etc. - * @param {boolean=} opt_allowToolbox If true, don't close the toolbox. - */ -Blockly.hideChaff = function(opt_allowToolbox) { - Blockly.hideChaffInternal_(opt_allowToolbox); - Blockly.WidgetDiv.hide(true); -}; - -/** - * Close tooltips, context menus, dropdown selections, etc. - * For some elements (e.g. field text inputs), rather than hiding, it will - * move them. - * @param {boolean=} opt_allowToolbox If true, don't close the toolbox. - */ -Blockly.hideChaffOnResize = function(opt_allowToolbox) { - Blockly.hideChaffInternal_(opt_allowToolbox); - Blockly.WidgetDiv.repositionForWindowResize(); -}; - -/** - * Does a majority of the work for hideChaff including tooltips, dropdowns, - * toolbox, etc. It does not deal with the WidgetDiv. - * @param {boolean=} opt_allowToolbox If true, don't close the toolbox. - * @private - */ -Blockly.hideChaffInternal_ = function(opt_allowToolbox) { - Blockly.Tooltip.hide(); - Blockly.DropDownDiv.hideWithoutAnimation(); - if (!opt_allowToolbox) { - var workspace = Blockly.getMainWorkspace(); - if (workspace.toolbox_ && - workspace.toolbox_.flyout_ && - workspace.toolbox_.flyout_.autoClose) { - workspace.toolbox_.clearSelection(); - } - } -}; - -/** - * Returns the main workspace. Returns the last used main workspace (based on - * focus). Try not to use this function, particularly if there are multiple - * Blockly instances on a page. - * @return {!Blockly.Workspace} The main workspace. - */ -Blockly.getMainWorkspace = function() { - return Blockly.mainWorkspace; -}; - -/** - * Wrapper to window.alert() that app developers may override to - * provide alternatives to the modal browser window. - * @param {string} message The message to display to the user. - * @param {function()=} opt_callback The callback when the alert is dismissed. - */ -Blockly.alert = function(message, opt_callback) { - window.alert(message); - if (opt_callback) { - opt_callback(); - } -}; - -/** - * Wrapper to window.confirm() that app developers may override to - * provide alternatives to the modal browser window. - * @param {string} message The message to display to the user. - * @param {!function(boolean)} callback The callback for handling user response. - */ -Blockly.confirm = function(message, callback) { - callback(window.confirm(message)); -}; - -/** - * Wrapper to window.prompt() that app developers may override to provide - * alternatives to the modal browser window. Built-in browser prompts are - * often used for better text input experience on mobile device. We strongly - * recommend testing mobile when overriding this. - * @param {string} message The message to display to the user. - * @param {string} defaultValue The value to initialize the prompt with. - * @param {!function(string)} callback The callback for handling user response. - * @param {?string} _opt_title An optional title for the prompt. - * @param {?string} _opt_varType An optional variable type for variable specific - * prompt behavior. - */ -Blockly.prompt = function(message, defaultValue, callback, _opt_title, - _opt_varType) { - // opt_title and opt_varType are unused because we only need them to pass - // information to the scratch-gui, which overwrites this function - callback(window.prompt(message, defaultValue)); -}; - -/** - * A callback for status buttons. The window.alert is here for testing and - * should be overridden. - * @param {string} id An identifier. - */ -Blockly.statusButtonCallback = function(id) { - window.alert('status button was pressed for ' + id); -}; - -/** - * Refresh the visual state of a status button in all extension category headers. - * @param {Blockly.Workspace} workspace A workspace. - */ -Blockly.refreshStatusButtons = function(workspace) { - var buttons = workspace.getFlyout().buttons_; - for (var i = 0; i < buttons.length; i++) { - if (buttons[i] instanceof Blockly.FlyoutExtensionCategoryHeader) { - buttons[i].refreshStatus(); - } - } -}; - -/** - * Helper function for defining a block from JSON. The resulting function has - * the correct value of jsonDef at the point in code where jsonInit is called. - * @param {!Object} jsonDef The JSON definition of a block. - * @return {function()} A function that calls jsonInit with the correct value - * of jsonDef. - * @private - */ -Blockly.jsonInitFactory_ = function(jsonDef) { - return function() { - this.jsonInit(jsonDef); - }; -}; - -/** - * Define blocks from an array of JSON block definitions, as might be generated - * by the Blockly Developer Tools. - * @param {!Array.} jsonArray An array of JSON block definitions. - */ -Blockly.defineBlocksWithJsonArray = function(jsonArray) { - for (var i = 0; i < jsonArray.length; i++) { - var elem = jsonArray[i]; - if (!elem) { - console.warn( - 'Block definition #' + i + ' in JSON array is ' + elem + '. ' + - 'Skipping.'); - } else { - var typename = elem.type; - if (typename == null || typename === '') { - console.warn( - 'Block definition #' + i + - ' in JSON array is missing a type attribute. Skipping.'); - } else { - if (Blockly.Blocks[typename]) { - console.warn( - 'Block definition #' + i + ' in JSON array' + - ' overwrites prior definition of "' + typename + '".'); - } - Blockly.Blocks[typename] = { - init: Blockly.jsonInitFactory_(elem) - }; - } - } - } -}; - -/** - * Bind an event to a function call. When calling the function, verifies that - * it belongs to the touch stream that is currently being processed, and splits - * multitouch events into multiple events as needed. - * @param {!EventTarget} node Node upon which to listen. - * @param {string} name Event name to listen to (e.g. 'mousedown'). - * @param {Object} thisObject The value of 'this' in the function. - * @param {!Function} func Function to call when event is triggered. - * @param {boolean=} opt_noCaptureIdentifier True if triggering on this event - * should not block execution of other event handlers on this touch or other - * simultaneous touches. - * @param {boolean=} opt_noPreventDefault True if triggering on this event - * should prevent the default handler. False by default. If - * opt_noPreventDefault is provided, opt_noCaptureIdentifier must also be - * provided. - * @return {!Array.} Opaque data that can be passed to unbindEvent_. - */ -Blockly.bindEventWithChecks_ = function(node, name, thisObject, func, - opt_noCaptureIdentifier, opt_noPreventDefault) { - var handled = false; - var wrapFunc = function(e) { - var captureIdentifier = !opt_noCaptureIdentifier; - // Handle each touch point separately. If the event was a mouse event, this - // will hand back an array with one element, which we're fine handling. - var events = Blockly.Touch.splitEventByTouches(e); - for (var i = 0, event; event = events[i]; i++) { - if (captureIdentifier && !Blockly.Touch.shouldHandleEvent(event)) { - continue; - } - Blockly.Touch.setClientFromTouch(event); - if (thisObject) { - func.call(thisObject, event); - } else { - func(event); - } - handled = true; - } - }; - - node.addEventListener(name, wrapFunc, false); - var bindData = [[node, name, wrapFunc]]; - - // Add equivalent touch event. - if (name in Blockly.Touch.TOUCH_MAP) { - var touchWrapFunc = function(e) { - wrapFunc(e); - // Calling preventDefault stops the browser from scrolling/zooming the - // page. - var preventDef = !opt_noPreventDefault; - if (handled && preventDef) { - e.preventDefault(); - } - }; - for (var i = 0, type; type = Blockly.Touch.TOUCH_MAP[name][i]; i++) { - node.addEventListener(type, touchWrapFunc, false); - bindData.push([node, type, touchWrapFunc]); - } - } - return bindData; -}; - - -/** - * Bind an event to a function call. Handles multitouch events by using the - * coordinates of the first changed touch, and doesn't do any safety checks for - * simultaneous event processing. - * @deprecated in favor of bindEventWithChecks_, but preserved for external - * users. - * @param {!EventTarget} node Node upon which to listen. - * @param {string} name Event name to listen to (e.g. 'mousedown'). - * @param {Object} thisObject The value of 'this' in the function. - * @param {!Function} func Function to call when event is triggered. - * @return {!Array.} Opaque data that can be passed to unbindEvent_. - * @private - */ -Blockly.bindEvent_ = function(node, name, thisObject, func) { - var wrapFunc = function(e) { - if (thisObject) { - func.call(thisObject, e); - } else { - func(e); - } - }; - - node.addEventListener(name, wrapFunc, false); - var bindData = [[node, name, wrapFunc]]; - - // Add equivalent touch event. - if (name in Blockly.Touch.TOUCH_MAP) { - var touchWrapFunc = function(e) { - // Punt on multitouch events. - if (e.changedTouches.length == 1) { - // Map the touch event's properties to the event. - var touchPoint = e.changedTouches[0]; - e.clientX = touchPoint.clientX; - e.clientY = touchPoint.clientY; - } - wrapFunc(e); - - // Stop the browser from scrolling/zooming the page. - e.preventDefault(); - }; - for (var i = 0, type; type = Blockly.Touch.TOUCH_MAP[name][i]; i++) { - node.addEventListener(type, touchWrapFunc, false); - bindData.push([node, type, touchWrapFunc]); - } - } - return bindData; -}; - -/** - * Unbind one or more events event from a function call. - * @param {!Array.} bindData Opaque data from bindEvent_. - * This list is emptied during the course of calling this function. - * @return {!Function} The function call. - * @private - */ -Blockly.unbindEvent_ = function(bindData) { - while (bindData.length) { - var bindDatum = bindData.pop(); - var node = bindDatum[0]; - var name = bindDatum[1]; - var func = bindDatum[2]; - node.removeEventListener(name, func, false); - } - return func; -}; - -/** - * Is the given string a number (includes negative and decimals). - * @param {string} str Input string. - * @return {boolean} True if number, false otherwise. - */ -Blockly.isNumber = function(str) { - return !!str.match(/^\s*-?\d+(\.\d+)?\s*$/); -}; - -// IE9 does not have a console. Create a stub to stop errors. -if (!goog.global['console']) { - goog.global['console'] = { - 'log': function() {}, - 'warn': function() {} - }; -} - -// Export symbols that would otherwise be renamed by Closure compiler. -if (!goog.global['Blockly']) { - goog.global['Blockly'] = {}; -} -goog.global['Blockly']['getMainWorkspace'] = Blockly.getMainWorkspace; diff --git a/core/blocks.js b/core/blocks.js deleted file mode 100644 index c27be1d40d..0000000000 --- a/core/blocks.js +++ /dev/null @@ -1,37 +0,0 @@ -/** - * @license - * Visual Blocks Editor - * - * Copyright 2013 Google Inc. - * https://developers.google.com/blockly/ - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @fileoverview A mapping of block type names to block prototype objects. - * @author spertus@google.com (Ellen Spertus) - */ -'use strict'; - -/** - * A mapping of block type names to block prototype objects. - * @name Blockly.Blocks - */ -goog.provide('Blockly.Blocks'); - -/* - * A mapping of block type names to block prototype objects. - * @type {!Object.} - */ -Blockly.Blocks = new Object(null); diff --git a/core/bubble.js b/core/bubble.js deleted file mode 100644 index 9121554241..0000000000 --- a/core/bubble.js +++ /dev/null @@ -1,664 +0,0 @@ -/** - * @license - * Visual Blocks Editor - * - * Copyright 2012 Google Inc. - * https://developers.google.com/blockly/ - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @fileoverview Object representing a UI bubble. - * @author fraser@google.com (Neil Fraser) - */ -'use strict'; - -goog.provide('Blockly.Bubble'); - -goog.require('Blockly.Touch'); -goog.require('Blockly.Workspace'); -goog.require('goog.dom'); -goog.require('goog.math.Coordinate'); -goog.require('goog.userAgent'); - - -/** - * Class for UI bubble. - * @param {!Blockly.WorkspaceSvg} workspace The workspace on which to draw the - * bubble. - * @param {!Element} content SVG content for the bubble. - * @param {Element} shape SVG element to avoid eclipsing. - * @param {!goog.math.Coordinate} anchorXY Absolute position of bubble's anchor - * point. - * @param {?number} bubbleWidth Width of bubble, or null if not resizable. - * @param {?number} bubbleHeight Height of bubble, or null if not resizable. - * @constructor - */ -Blockly.Bubble = function(workspace, content, shape, anchorXY, - bubbleWidth, bubbleHeight) { - this.workspace_ = workspace; - this.content_ = content; - this.shape_ = shape; - - var angle = Blockly.Bubble.ARROW_ANGLE; - if (this.workspace_.RTL) { - angle = -angle; - } - this.arrow_radians_ = Blockly.utils.toRadians(angle); - - var canvas = workspace.getBubbleCanvas(); - canvas.appendChild(this.createDom_(content, !!(bubbleWidth && bubbleHeight))); - - this.setAnchorLocation(anchorXY); - if (!bubbleWidth || !bubbleHeight) { - var bBox = /** @type {SVGLocatable} */ (this.content_).getBBox(); - bubbleWidth = bBox.width + 2 * Blockly.Bubble.BORDER_WIDTH; - bubbleHeight = bBox.height + 2 * Blockly.Bubble.BORDER_WIDTH; - } - this.setBubbleSize(bubbleWidth, bubbleHeight); - - // Render the bubble. - this.positionBubble_(); - this.renderArrow_(); - this.rendered_ = true; - - if (!workspace.options.readOnly) { - Blockly.bindEventWithChecks_( - this.bubbleBack_, 'mousedown', this, this.bubbleMouseDown_); - if (this.resizeGroup_) { - Blockly.bindEventWithChecks_( - this.resizeGroup_, 'mousedown', this, this.resizeMouseDown_); - } - } -}; - -/** - * Width of the border around the bubble. - */ -Blockly.Bubble.BORDER_WIDTH = 6; - -/** - * Determines the thickness of the base of the arrow in relation to the size - * of the bubble. Higher numbers result in thinner arrows. - */ -Blockly.Bubble.ARROW_THICKNESS = 5; - -/** - * The number of degrees that the arrow bends counter-clockwise. - */ -Blockly.Bubble.ARROW_ANGLE = 20; - -/** - * The sharpness of the arrow's bend. Higher numbers result in smoother arrows. - */ -Blockly.Bubble.ARROW_BEND = 4; - -/** - * Distance between arrow point and anchor point. - */ -Blockly.Bubble.ANCHOR_RADIUS = 8; - -/** - * Wrapper function called when a mouseUp occurs during a drag operation. - * @type {Array.} - * @private - */ -Blockly.Bubble.onMouseUpWrapper_ = null; - -/** - * Wrapper function called when a mouseMove occurs during a drag operation. - * @type {Array.} - * @private - */ -Blockly.Bubble.onMouseMoveWrapper_ = null; - -/** - * Function to call on resize of bubble. - * @type {Function} - */ -Blockly.Bubble.prototype.resizeCallback_ = null; - -/** - * Stop binding to the global mouseup and mousemove events. - * @private - */ -Blockly.Bubble.unbindDragEvents_ = function() { - if (Blockly.Bubble.onMouseUpWrapper_) { - Blockly.unbindEvent_(Blockly.Bubble.onMouseUpWrapper_); - Blockly.Bubble.onMouseUpWrapper_ = null; - } - if (Blockly.Bubble.onMouseMoveWrapper_) { - Blockly.unbindEvent_(Blockly.Bubble.onMouseMoveWrapper_); - Blockly.Bubble.onMouseMoveWrapper_ = null; - } -}; - -/* - * Handle a mouse-up event while dragging a bubble's border or resize handle. - * @param {!Event} e Mouse up event. - * @private - */ -Blockly.Bubble.bubbleMouseUp_ = function(/*e*/) { - Blockly.Touch.clearTouchIdentifier(); - Blockly.Bubble.unbindDragEvents_(); -}; - -/** - * Flag to stop incremental rendering during construction. - * @private - */ -Blockly.Bubble.prototype.rendered_ = false; - -/** - * Absolute coordinate of anchor point, in workspace coordinates. - * @type {goog.math.Coordinate} - * @private - */ -Blockly.Bubble.prototype.anchorXY_ = null; - -/** - * Relative X coordinate of bubble with respect to the anchor's centre, - * in workspace units. - * In RTL mode the initial value is negated. - * @private - */ -Blockly.Bubble.prototype.relativeLeft_ = 0; - -/** - * Relative Y coordinate of bubble with respect to the anchor's centre. - * @private - */ -Blockly.Bubble.prototype.relativeTop_ = 0; - -/** - * Width of bubble. - * @private - */ -Blockly.Bubble.prototype.width_ = 0; - -/** - * Height of bubble. - * @private - */ -Blockly.Bubble.prototype.height_ = 0; - -/** - * Automatically position and reposition the bubble. - * @private - */ -Blockly.Bubble.prototype.autoLayout_ = true; - -/** - * Create the bubble's DOM. - * @param {!Element} content SVG content for the bubble. - * @param {boolean} hasResize Add diagonal resize gripper if true. - * @return {!Element} The bubble's SVG group. - * @private - */ -Blockly.Bubble.prototype.createDom_ = function(content, hasResize) { - /* Create the bubble. Here's the markup that will be generated: - - - - - - - - - - - [...content goes here...] - - */ - this.bubbleGroup_ = Blockly.utils.createSvgElement('g', {}, null); - var filter = - {'filter': 'url(#' + this.workspace_.options.embossFilterId + ')'}; - if (goog.userAgent.getUserAgentString().indexOf('JavaFX') != -1) { - // Multiple reports that JavaFX can't handle filters. UserAgent: - // Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.44 - // (KHTML, like Gecko) JavaFX/8.0 Safari/537.44 - // https://github.com/google/blockly/issues/99 - filter = {}; - } - var bubbleEmboss = Blockly.utils.createSvgElement('g', - filter, this.bubbleGroup_); - this.bubbleArrow_ = Blockly.utils.createSvgElement('path', {}, bubbleEmboss); - this.bubbleBack_ = Blockly.utils.createSvgElement('rect', - { - 'class': 'blocklyDraggable', - 'x': 0, - 'y': 0, - 'rx': Blockly.Bubble.BORDER_WIDTH, - 'ry': Blockly.Bubble.BORDER_WIDTH - }, - bubbleEmboss); - if (hasResize) { - this.resizeGroup_ = Blockly.utils.createSvgElement('g', - {'class': this.workspace_.RTL ? - 'blocklyResizeSW' : 'blocklyResizeSE'}, - this.bubbleGroup_); - var resizeSize = 2 * Blockly.Bubble.BORDER_WIDTH; - Blockly.utils.createSvgElement('polygon', - {'points': '0,x x,x x,0'.replace(/x/g, resizeSize.toString())}, - this.resizeGroup_); - Blockly.utils.createSvgElement('line', - { - 'class': 'blocklyResizeLine', - 'x1': resizeSize / 3, 'y1': resizeSize - 1, - 'x2': resizeSize - 1, 'y2': resizeSize / 3 - }, this.resizeGroup_); - Blockly.utils.createSvgElement('line', - { - 'class': 'blocklyResizeLine', - 'x1': resizeSize * 2 / 3, - 'y1': resizeSize - 1, - 'x2': resizeSize - 1, - 'y2': resizeSize * 2 / 3 - }, this.resizeGroup_); - } else { - this.resizeGroup_ = null; - } - this.bubbleGroup_.appendChild(content); - return this.bubbleGroup_; -}; - -/** - * Return the root node of the bubble's SVG group. - * @return {Element} The root SVG node of the bubble's group. - */ -Blockly.Bubble.prototype.getSvgRoot = function() { - return this.bubbleGroup_; -}; - -/** - * Expose the block's ID on the bubble's top-level SVG group. - * @param {string} id ID of block. - */ -Blockly.Bubble.prototype.setSvgId = function(id) { - if (this.bubbleGroup_.dataset) { - this.bubbleGroup_.dataset.blockId = id; - } -}; - -/** - * Handle a mouse-down on bubble's border. - * @param {!Event} e Mouse down event. - * @private - */ -Blockly.Bubble.prototype.bubbleMouseDown_ = function(e) { - var gesture = this.workspace_.getGesture(e); - if (gesture) { - gesture.handleBubbleStart(e, this); - } -}; - -/** - * Show the context menu for this bubble. - * @param {!Event} _e Mouse event. - * @private - */ -Blockly.Bubble.prototype.showContextMenu_ = function(_e) { - // NOP on bubbles, but used by the bubble dragger to pass events to - // workspace comments. -}; - -/** - * Get whether this bubble is deletable or not. - * @return {boolean} True if deletable. - * @package - */ -Blockly.Bubble.prototype.isDeletable = function() { - return false; -}; - -/** - * Handle a mouse-down on bubble's resize corner. - * @param {!Event} e Mouse down event. - * @private - */ -Blockly.Bubble.prototype.resizeMouseDown_ = function(e) { - this.promote_(); - Blockly.Bubble.unbindDragEvents_(); - if (Blockly.utils.isRightButton(e)) { - // No right-click. - e.stopPropagation(); - return; - } - // Left-click (or middle click) - this.workspace_.startDrag(e, new goog.math.Coordinate( - this.workspace_.RTL ? -this.width_ : this.width_, this.height_)); - - Blockly.Bubble.onMouseUpWrapper_ = Blockly.bindEventWithChecks_(document, - 'mouseup', this, Blockly.Bubble.bubbleMouseUp_); - Blockly.Bubble.onMouseMoveWrapper_ = Blockly.bindEventWithChecks_(document, - 'mousemove', this, this.resizeMouseMove_); - Blockly.hideChaff(); - // This event has been handled. No need to bubble up to the document. - e.stopPropagation(); -}; - -/** - * Resize this bubble to follow the mouse. - * @param {!Event} e Mouse move event. - * @private - */ -Blockly.Bubble.prototype.resizeMouseMove_ = function(e) { - this.autoLayout_ = false; - var newXY = this.workspace_.moveDrag(e); - this.setBubbleSize(this.workspace_.RTL ? -newXY.x : newXY.x, newXY.y); - if (this.workspace_.RTL) { - // RTL requires the bubble to move its left edge. - this.positionBubble_(); - } -}; - -/** - * Register a function as a callback event for when the bubble is resized. - * @param {!Function} callback The function to call on resize. - */ -Blockly.Bubble.prototype.registerResizeEvent = function(callback) { - this.resizeCallback_ = callback; -}; - -/** - * Move this bubble to the top of the stack. - * @return {!boolean} Whether or not the bubble has been moved. - * @private - */ -Blockly.Bubble.prototype.promote_ = function() { - var svgGroup = this.bubbleGroup_.parentNode; - if (svgGroup.lastChild !== this.bubbleGroup_) { - svgGroup.appendChild(this.bubbleGroup_); - return true; - } - return false; -}; - -/** - * Notification that the anchor has moved. - * Update the arrow and bubble accordingly. - * @param {!goog.math.Coordinate} xy Absolute location. - */ -Blockly.Bubble.prototype.setAnchorLocation = function(xy) { - this.anchorXY_ = xy; - if (this.rendered_) { - this.positionBubble_(); - } -}; - -/** - * Position the bubble so that it does not fall off-screen. - * @private - */ -Blockly.Bubble.prototype.layoutBubble_ = function() { - // Compute the preferred bubble location. - var relativeLeft = -this.width_ / 4; - var relativeTop = -this.height_ - Blockly.BlockSvg.MIN_BLOCK_Y; - // Prevent the bubble from being off-screen. - var metrics = this.workspace_.getMetrics(); - metrics.viewWidth /= this.workspace_.scale; - metrics.viewLeft /= this.workspace_.scale; - var anchorX = this.anchorXY_.x; - if (this.workspace_.RTL) { - if (anchorX - metrics.viewLeft - relativeLeft - this.width_ < - Blockly.Scrollbar.scrollbarThickness) { - // Slide the bubble right until it is onscreen. - relativeLeft = anchorX - metrics.viewLeft - this.width_ - - Blockly.Scrollbar.scrollbarThickness; - } else if (anchorX - metrics.viewLeft - relativeLeft > - metrics.viewWidth) { - // Slide the bubble left until it is onscreen. - relativeLeft = anchorX - metrics.viewLeft - metrics.viewWidth; - } - } else { - if (anchorX + relativeLeft < metrics.viewLeft) { - // Slide the bubble right until it is onscreen. - relativeLeft = metrics.viewLeft - anchorX; - } else if (metrics.viewLeft + metrics.viewWidth < - anchorX + relativeLeft + this.width_ + - Blockly.BlockSvg.SEP_SPACE_X + - Blockly.Scrollbar.scrollbarThickness) { - // Slide the bubble left until it is onscreen. - relativeLeft = metrics.viewLeft + metrics.viewWidth - anchorX - - this.width_ - Blockly.Scrollbar.scrollbarThickness; - } - } - if (this.anchorXY_.y + relativeTop < metrics.viewTop) { - // Slide the bubble below the block. - var bBox = /** @type {SVGLocatable} */ (this.shape_).getBBox(); - relativeTop = bBox.height; - } - this.relativeLeft_ = relativeLeft; - this.relativeTop_ = relativeTop; -}; - -/** - * Move the bubble to a location relative to the anchor's centre. - * @private - */ -Blockly.Bubble.prototype.positionBubble_ = function() { - var left = this.anchorXY_.x; - if (this.workspace_.RTL) { - left -= this.relativeLeft_ ; - } else { - left += this.relativeLeft_; - } - var top = this.relativeTop_ + this.anchorXY_.y; - this.moveTo(left, top); -}; - -/** - * Move the bubble group to the specified location in workspace coordinates. - * @param {number} x The x position to move to. - * @param {number} y The y position to move to. - * @package - */ -Blockly.Bubble.prototype.moveTo = function(x, y) { - this.bubbleGroup_.setAttribute('transform', 'translate(' + x + ',' + y + ')'); -}; - -/** - * Get the dimensions of this bubble. - * @return {!Object} Object with width and height properties. - */ -Blockly.Bubble.prototype.getBubbleSize = function() { - return {width: this.width_, height: this.height_}; -}; - -/** - * Size this bubble. - * @param {number} width Width of the bubble. - * @param {number} height Height of the bubble. - */ -Blockly.Bubble.prototype.setBubbleSize = function(width, height) { - var doubleBorderWidth = 2 * Blockly.Bubble.BORDER_WIDTH; - // Minimum size of a bubble. - width = Math.max(width, doubleBorderWidth + 45); - height = Math.max(height, doubleBorderWidth + 20); - this.width_ = width; - this.height_ = height; - this.bubbleBack_.setAttribute('width', width); - this.bubbleBack_.setAttribute('height', height); - if (this.resizeGroup_) { - if (this.workspace_.RTL) { - // Mirror the resize group. - var resizeSize = 2 * Blockly.Bubble.BORDER_WIDTH; - this.resizeGroup_.setAttribute('transform', 'translate(' + - resizeSize + ',' + (height - doubleBorderWidth) + ') scale(-1 1)'); - } else { - this.resizeGroup_.setAttribute('transform', 'translate(' + - (width - doubleBorderWidth) + ',' + - (height - doubleBorderWidth) + ')'); - } - } - if (this.rendered_) { - if (this.autoLayout_) { - this.layoutBubble_(); - } - this.positionBubble_(); - this.renderArrow_(); - } - // Allow the contents to resize. - if (this.resizeCallback_) { - this.resizeCallback_(); - } -}; - -/** - * Draw the arrow between the bubble and the origin. - * @private - */ -Blockly.Bubble.prototype.renderArrow_ = function() { - var steps = []; - // Find the relative coordinates of the center of the bubble. - var relBubbleX = this.width_ / 2; - var relBubbleY = this.height_ / 2; - // Find the relative coordinates of the center of the anchor. - var relAnchorX = -this.relativeLeft_; - var relAnchorY = -this.relativeTop_; - if (relBubbleX == relAnchorX && relBubbleY == relAnchorY) { - // Null case. Bubble is directly on top of the anchor. - // Short circuit this rather than wade through divide by zeros. - steps.push('M ' + relBubbleX + ',' + relBubbleY); - } else { - // Compute the angle of the arrow's line. - var rise = relAnchorY - relBubbleY; - var run = relAnchorX - relBubbleX; - if (this.workspace_.RTL) { - run *= -1; - } - var hypotenuse = Math.sqrt(rise * rise + run * run); - var angle = Math.acos(run / hypotenuse); - if (rise < 0) { - angle = 2 * Math.PI - angle; - } - // Compute a line perpendicular to the arrow. - var rightAngle = angle + Math.PI / 2; - if (rightAngle > Math.PI * 2) { - rightAngle -= Math.PI * 2; - } - var rightRise = Math.sin(rightAngle); - var rightRun = Math.cos(rightAngle); - - // Calculate the thickness of the base of the arrow. - var bubbleSize = this.getBubbleSize(); - var thickness = (bubbleSize.width + bubbleSize.height) / - Blockly.Bubble.ARROW_THICKNESS; - thickness = Math.min(thickness, bubbleSize.width, bubbleSize.height) / 4; - - // Back the tip of the arrow off of the anchor. - var backoffRatio = 1 - Blockly.Bubble.ANCHOR_RADIUS / hypotenuse; - relAnchorX = relBubbleX + backoffRatio * run; - relAnchorY = relBubbleY + backoffRatio * rise; - - // Coordinates for the base of the arrow. - var baseX1 = relBubbleX + thickness * rightRun; - var baseY1 = relBubbleY + thickness * rightRise; - var baseX2 = relBubbleX - thickness * rightRun; - var baseY2 = relBubbleY - thickness * rightRise; - - // Distortion to curve the arrow. - var swirlAngle = angle + this.arrow_radians_; - if (swirlAngle > Math.PI * 2) { - swirlAngle -= Math.PI * 2; - } - var swirlRise = Math.sin(swirlAngle) * - hypotenuse / Blockly.Bubble.ARROW_BEND; - var swirlRun = Math.cos(swirlAngle) * - hypotenuse / Blockly.Bubble.ARROW_BEND; - - steps.push('M' + baseX1 + ',' + baseY1); - steps.push('C' + (baseX1 + swirlRun) + ',' + (baseY1 + swirlRise) + - ' ' + relAnchorX + ',' + relAnchorY + - ' ' + relAnchorX + ',' + relAnchorY); - steps.push('C' + relAnchorX + ',' + relAnchorY + - ' ' + (baseX2 + swirlRun) + ',' + (baseY2 + swirlRise) + - ' ' + baseX2 + ',' + baseY2); - } - steps.push('z'); - this.bubbleArrow_.setAttribute('d', steps.join(' ')); -}; - -/** - * Change the colour of a bubble. - * @param {string} hexColour Hex code of colour. - */ -Blockly.Bubble.prototype.setColour = function(hexColour) { - this.bubbleBack_.setAttribute('fill', hexColour); - this.bubbleArrow_.setAttribute('fill', hexColour); -}; - -/** - * Dispose of this bubble. - */ -Blockly.Bubble.prototype.dispose = function() { - Blockly.Bubble.unbindDragEvents_(); - // Dispose of and unlink the bubble. - goog.dom.removeNode(this.bubbleGroup_); - this.bubbleGroup_ = null; - this.bubbleArrow_ = null; - this.bubbleBack_ = null; - this.resizeGroup_ = null; - this.workspace_ = null; - this.content_ = null; - this.shape_ = null; -}; - -/** - * Move this bubble during a drag, taking into account whether or not there is - * a drag surface. - * @param {?Blockly.BlockDragSurfaceSvg} dragSurface The surface that carries - * rendered items during a drag, or null if no drag surface is in use. - * @param {!goog.math.Coordinate} newLoc The location to translate to, in - * workspace coordinates. - * @package - */ -Blockly.Bubble.prototype.moveDuringDrag = function(dragSurface, newLoc) { - if (dragSurface) { - dragSurface.translateSurface(newLoc.x, newLoc.y); - } else { - this.moveTo(newLoc.x, newLoc.y); - } - if (this.workspace_.RTL) { - this.relativeLeft_ = this.anchorXY_.x - newLoc.x - this.width_; - } else { - this.relativeLeft_ = newLoc.x - this.anchorXY_.x; - } - this.relativeTop_ = newLoc.y - this.anchorXY_.y; - this.renderArrow_(); -}; - -/** - * Return the coordinates of the top corner of this bubble's starting edge (e.g. - * top left corner in LTR and top right corner in RTL) relative - * to the drawing surface's origin (0,0), in workspace units. - * @return {!goog.math.Coordinate} Object with .x and .y properties. - */ -Blockly.Bubble.prototype.getRelativeToSurfaceXY = function() { - return new goog.math.Coordinate( - this.workspace_.RTL ? this.anchorXY_.x - this.relativeLeft_ : this.anchorXY_.x + this.relativeLeft_, - this.anchorXY_.y + this.relativeTop_); -}; - -/** - * Set whether auto-layout of this bubble is enabled. The first time a bubble - * is shown it positions itself to not cover any blocks. Once a user has - * dragged it to reposition, it renders where the user put it. - * @param {boolean} enable True if auto-layout should be enabled, false - * otherwise. - * @package - */ -Blockly.Bubble.prototype.setAutoLayout = function(enable) { - this.autoLayout_ = enable; -}; diff --git a/core/bubble_dragger.js b/core/bubble_dragger.js deleted file mode 100644 index 2366581e8c..0000000000 --- a/core/bubble_dragger.js +++ /dev/null @@ -1,285 +0,0 @@ -/** - * @license - * Visual Blocks Editor - * - * Copyright 2018 Google Inc. - * https://developers.google.com/blockly/ - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @fileoverview Methods for dragging a bubble visually. - * @author fenichel@google.com (Rachel Fenichel) - */ -'use strict'; - -goog.provide('Blockly.BubbleDragger'); - -goog.require('Blockly.Bubble'); -goog.require('Blockly.Events.CommentMove'); -goog.require('Blockly.WorkspaceCommentSvg'); - -goog.require('goog.math.Coordinate'); -goog.require('goog.asserts'); - - -/** - * Class for a bubble dragger. It moves things on the bubble canvas around the - * workspace when they are being dragged by a mouse or touch. These can be - * block comments, mutators, warnings, or workspace comments. - * @param {!Blockly.Bubble|!Blockly.WorkspaceCommentSvg} bubble The item on the - * bubble canvas to drag. - * @param {!Blockly.WorkspaceSvg} workspace The workspace to drag on. - * @constructor - */ -Blockly.BubbleDragger = function(bubble, workspace) { - /** - * The item on the bubble canvas that is being dragged. - * @type {!Blockly.Bubble|!Blockly.WorkspaceCommentSvg} - * @private - */ - this.draggingBubble_ = bubble; - - /** - * The workspace on which the bubble is being dragged. - * @type {!Blockly.WorkspaceSvg} - * @private - */ - this.workspace_ = workspace; - - /** - * Which delete area the mouse pointer is over, if any. - * One of {@link Blockly.DELETE_AREA_TRASH}, - * {@link Blockly.DELETE_AREA_TOOLBOX}, or {@link Blockly.DELETE_AREA_NONE}. - * @type {?number} - * @private - */ - this.deleteArea_ = null; - - /** - * Whether the bubble would be deleted if dropped immediately. - * @type {boolean} - * @private - */ - this.wouldDeleteBubble_ = false; - - /** - * The location of the top left corner of the dragging bubble's body at the - * beginning of the drag, in workspace coordinates. - * @type {!goog.math.Coordinate} - * @private - */ - this.startXY_ = this.draggingBubble_.getRelativeToSurfaceXY(); - - /** - * The drag surface to move bubbles to during a drag, or null if none should - * be used. Block dragging and bubble dragging use the same surface. - * @type {?Blockly.BlockDragSurfaceSvg} - * @private - */ - this.dragSurface_ = - Blockly.utils.is3dSupported() && !!workspace.getBlockDragSurface() ? - workspace.getBlockDragSurface() : null; -}; - -/** - * Sever all links from this object. - * @package - */ -Blockly.BubbleDragger.prototype.dispose = function() { - this.draggingBubble_ = null; - this.workspace_ = null; - this.dragSurface_ = null; -}; - -/** - * Start dragging a bubble. This includes moving it to the drag surface. - * @package - */ -Blockly.BubbleDragger.prototype.startBubbleDrag = function() { - if (!Blockly.Events.getGroup()) { - Blockly.Events.setGroup(true); - } - - this.workspace_.setResizesEnabled(false); - this.draggingBubble_.setAutoLayout(false); - if (this.dragSurface_) { - this.moveToDragSurface_(); - } - - this.draggingBubble_.setDragging && this.draggingBubble_.setDragging(true); - - var toolbox = this.workspace_.getToolbox(); - if (toolbox) { - var style = this.draggingBubble_.isDeletable() ? 'blocklyToolboxDelete' : - 'blocklyToolboxGrab'; - toolbox.addStyle(style); - } -}; - -/** - * Execute a step of bubble dragging, based on the given event. Update the - * display accordingly. - * @param {!Event} e The most recent move event. - * @param {!goog.math.Coordinate} currentDragDeltaXY How far the pointer has - * moved from the position at the start of the drag, in pixel units. - * @package - */ -Blockly.BubbleDragger.prototype.dragBubble = function(e, currentDragDeltaXY) { - var delta = this.pixelsToWorkspaceUnits_(currentDragDeltaXY); - var newLoc = goog.math.Coordinate.sum(this.startXY_, delta); - - this.draggingBubble_.moveDuringDrag(this.dragSurface_, newLoc); - - if (this.draggingBubble_.isDeletable()) { - this.deleteArea_ = this.workspace_.isDeleteArea(e); - this.updateCursorDuringBubbleDrag_(); - } -}; - -/** - * Shut the trash can and, if necessary, delete the dragging bubble. - * Should be called at the end of a bubble drag. - * @return {boolean} whether the bubble was deleted. - * @private - */ -Blockly.BubbleDragger.prototype.maybeDeleteBubble_ = function() { - var trashcan = this.workspace_.trashcan; - - if (this.wouldDeleteBubble_) { - if (trashcan) { - setTimeout(trashcan.close.bind(trashcan), 100); - } - // Fire a move event, so we know where to go back to for an undo. - this.fireMoveEvent_(); - this.draggingBubble_.dispose(false, true); - } else if (trashcan) { - // Make sure the trash can is closed. - trashcan.close(); - } - return this.wouldDeleteBubble_; -}; - -/** - * Update the cursor (and possibly the trash can lid) to reflect whether the - * dragging bubble would be deleted if released immediately. - * @private - */ -Blockly.BubbleDragger.prototype.updateCursorDuringBubbleDrag_ = function() { - this.wouldDeleteBubble_ = this.deleteArea_ != Blockly.DELETE_AREA_NONE; - var trashcan = this.workspace_.trashcan; - if (this.wouldDeleteBubble_) { - this.draggingBubble_.setDeleteStyle(true); - if (this.deleteArea_ == Blockly.DELETE_AREA_TRASH && trashcan) { - trashcan.setOpen_(true); - } - } else { - this.draggingBubble_.setDeleteStyle(false); - if (trashcan) { - trashcan.setOpen_(false); - } - } -}; - -/** - * Finish a bubble drag and put the bubble back on the workspace. - * @param {!Event} e The mouseup/touchend event. - * @param {!goog.math.Coordinate} currentDragDeltaXY How far the pointer has - * moved from the position at the start of the drag, in pixel units. - * @package - */ -Blockly.BubbleDragger.prototype.endBubbleDrag = function( - e, currentDragDeltaXY) { - // Make sure internal state is fresh. - this.dragBubble(e, currentDragDeltaXY); - - var delta = this.pixelsToWorkspaceUnits_(currentDragDeltaXY); - var newLoc = goog.math.Coordinate.sum(this.startXY_, delta); - - // Move the bubble to its final location. - this.draggingBubble_.moveTo(newLoc.x, newLoc.y); - var deleted = this.maybeDeleteBubble_(); - - if (!deleted) { - // Put everything back onto the bubble canvas. - if (this.dragSurface_) { - this.dragSurface_.clearAndHide(this.workspace_.getBubbleCanvas()); - } - - this.draggingBubble_.setDragging && this.draggingBubble_.setDragging(false); - this.fireMoveEvent_(); - } - this.workspace_.setResizesEnabled(true); - - if (this.workspace_.toolbox_) { - var style = this.draggingBubble_.isDeletable() ? 'blocklyToolboxDelete' : - 'blocklyToolboxGrab'; - this.workspace_.toolbox_.removeStyle(style); - } - Blockly.Events.setGroup(false); -}; - -/** - * Fire a move event at the end of a bubble drag. - * @private - */ -Blockly.BubbleDragger.prototype.fireMoveEvent_ = function() { - var event = null; - if (this.draggingBubble_.isComment) { - event = new Blockly.Events.CommentMove(this.draggingBubble_); - } else if (this.draggingBubble_ instanceof Blockly.ScratchBubble) { - event = new Blockly.Events.CommentMove(this.draggingBubble_.comment); - } else { - return; - } - event.setOldCoordinate(this.startXY_); - event.recordNew(); - Blockly.Events.fire(event); -}; - -/** - * Convert a coordinate object from pixels to workspace units, including a - * correction for mutator workspaces. - * This function does not consider differing origins. It simply scales the - * input's x and y values. - * @param {!goog.math.Coordinate} pixelCoord A coordinate with x and y values - * in css pixel units. - * @return {!goog.math.Coordinate} The input coordinate divided by the workspace - * scale. - * @private - */ -Blockly.BubbleDragger.prototype.pixelsToWorkspaceUnits_ = function(pixelCoord) { - var result = new goog.math.Coordinate(pixelCoord.x / this.workspace_.scale, - pixelCoord.y / this.workspace_.scale); - if (this.workspace_.isMutator) { - // If we're in a mutator, its scale is always 1, purely because of some - // oddities in our rendering optimizations. The actual scale is the same as - // the scale on the parent workspace. - // Fix that for dragging. - var mainScale = this.workspace_.options.parentWorkspace.scale; - result = result.scale(1 / mainScale); - } - return result; -}; -/** - * Move the bubble onto the drag surface at the beginning of a drag. Move the - * drag surface to preserve the apparent location of the bubble. - * @private - */ -Blockly.BubbleDragger.prototype.moveToDragSurface_ = function() { - this.draggingBubble_.moveTo(0, 0); - this.dragSurface_.translateSurface(this.startXY_.x, this.startXY_.y); - // Execute the move on the top-level SVG component. - this.dragSurface_.setBlocksAndShow(this.draggingBubble_.getSvgRoot()); -}; diff --git a/core/comment.js b/core/comment.js deleted file mode 100644 index 65e1bceca9..0000000000 --- a/core/comment.js +++ /dev/null @@ -1,293 +0,0 @@ -/** - * @license - * Visual Blocks Editor - * - * Copyright 2011 Google Inc. - * https://developers.google.com/blockly/ - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @fileoverview Object representing a code comment. - * @author fraser@google.com (Neil Fraser) - */ -'use strict'; - -goog.provide('Blockly.Comment'); - -goog.require('Blockly.Bubble'); -goog.require('Blockly.Events.BlockChange'); -goog.require('Blockly.Events.Ui'); -goog.require('Blockly.Icon'); -goog.require('goog.userAgent'); - - -/** - * Class for a comment. - * @param {!Blockly.Block} block The block associated with this comment. - * @extends {Blockly.Icon} - * @constructor - */ -Blockly.Comment = function(block) { - Blockly.Comment.superClass_.constructor.call(this, block); - this.createIcon(); -}; -goog.inherits(Blockly.Comment, Blockly.Icon); - -/** - * Comment text (if bubble is not visible). - * @private - */ -Blockly.Comment.prototype.text_ = ''; - -/** - * Width of bubble. - * @private - */ -Blockly.Comment.prototype.width_ = 160; - -/** - * Height of bubble. - * @private - */ -Blockly.Comment.prototype.height_ = 80; - -/** - * Draw the comment icon. - * @param {!Element} group The icon group. - * @private - */ -Blockly.Comment.prototype.drawIcon_ = function(group) { - // Circle. - Blockly.utils.createSvgElement('circle', - {'class': 'blocklyIconShape', 'r': '8', 'cx': '8', 'cy': '8'}, - group); - // Can't use a real '?' text character since different browsers and operating - // systems render it differently. - // Body of question mark. - Blockly.utils.createSvgElement('path', - { - 'class': 'blocklyIconSymbol', - 'd': 'm6.8,10h2c0.003,-0.617 0.271,-0.962 0.633,-1.266 2.875,-2.405' + - '0.607,-5.534 -3.765,-3.874v1.7c3.12,-1.657 3.698,0.118 2.336,1.25' + - '-1.201,0.998 -1.201,1.528 -1.204,2.19z' - }, - group); - // Dot of question mark. - Blockly.utils.createSvgElement('rect', - { - 'class': 'blocklyIconSymbol', - 'x': '6.8', - 'y': '10.78', - 'height': '2', - 'width': '2' - }, - group); -}; - -/** - * Create the editor for the comment's bubble. - * @return {!Element} The top-level node of the editor. - * @private - */ -Blockly.Comment.prototype.createEditor_ = function() { - /* Create the editor. Here's the markup that will be generated: - - - - - - */ - this.foreignObject_ = Blockly.utils.createSvgElement('foreignObject', - {'x': Blockly.Bubble.BORDER_WIDTH, 'y': Blockly.Bubble.BORDER_WIDTH}, - null); - var body = document.createElementNS(Blockly.HTML_NS, 'body'); - body.setAttribute('xmlns', Blockly.HTML_NS); - body.className = 'blocklyMinimalBody'; - var textarea = document.createElementNS(Blockly.HTML_NS, 'textarea'); - textarea.className = 'blocklyCommentTextarea'; - textarea.setAttribute('dir', this.block_.RTL ? 'RTL' : 'LTR'); - body.appendChild(textarea); - this.textarea_ = textarea; - this.foreignObject_.appendChild(body); - Blockly.bindEventWithChecks_(textarea, 'mouseup', this, this.textareaFocus_); - // Don't zoom with mousewheel. - Blockly.bindEventWithChecks_(textarea, 'wheel', this, function(e) { - e.stopPropagation(); - }); - Blockly.bindEventWithChecks_(textarea, 'change', this, function(_e) { - if (this.text_ != textarea.value) { - Blockly.Events.fire(new Blockly.Events.BlockChange( - this.block_, 'comment', null, this.text_, textarea.value)); - this.text_ = textarea.value; - } - }); - setTimeout(function() { - textarea.focus(); - }, 0); - return this.foreignObject_; -}; - -/** - * Add or remove editability of the comment. - * @override - */ -Blockly.Comment.prototype.updateEditable = function() { - if (this.isVisible()) { - // Toggling visibility will force a rerendering. - this.setVisible(false); - this.setVisible(true); - } - // Allow the icon to update. - Blockly.Icon.prototype.updateEditable.call(this); -}; - -/** - * Callback function triggered when the bubble has resized. - * Resize the text area accordingly. - * @private - */ -Blockly.Comment.prototype.resizeBubble_ = function() { - if (this.isVisible()) { - var size = this.bubble_.getBubbleSize(); - var doubleBorderWidth = 2 * Blockly.Bubble.BORDER_WIDTH; - this.foreignObject_.setAttribute('width', size.width - doubleBorderWidth); - this.foreignObject_.setAttribute('height', size.height - doubleBorderWidth); - this.textarea_.style.width = (size.width - doubleBorderWidth - 4) + 'px'; - this.textarea_.style.height = (size.height - doubleBorderWidth - 4) + 'px'; - } -}; - -/** - * Show or hide the comment bubble. - * @param {boolean} visible True if the bubble should be visible. - */ -Blockly.Comment.prototype.setVisible = function(visible) { - if (visible == this.isVisible()) { - // No change. - return; - } - Blockly.Events.fire( - new Blockly.Events.Ui(this.block_, 'commentOpen', !visible, visible)); - if ((!this.block_.isEditable() && !this.textarea_) || goog.userAgent.IE) { - // Steal the code from warnings to make an uneditable text bubble. - // MSIE does not support foreignobject; textareas are impossible. - // http://msdn.microsoft.com/en-us/library/hh834675%28v=vs.85%29.aspx - // Always treat comments in IE as uneditable. - Blockly.Warning.prototype.setVisible.call(this, visible); - return; - } - // Save the bubble stats before the visibility switch. - var text = this.getText(); - var size = this.getBubbleSize(); - if (visible) { - // Create the bubble. - this.bubble_ = new Blockly.Bubble( - /** @type {!Blockly.WorkspaceSvg} */ (this.block_.workspace), - this.createEditor_(), this.block_.svgPath_, - this.iconXY_, this.width_, this.height_); - // Expose this comment's block's ID on its top-level SVG group. - this.bubble_.setSvgId(this.block_.id); - this.bubble_.registerResizeEvent(this.resizeBubble_.bind(this)); - this.updateColour(); - } else { - // Dispose of the bubble. - this.bubble_.dispose(); - this.bubble_ = null; - this.textarea_ = null; - this.foreignObject_ = null; - } - // Restore the bubble stats after the visibility switch. - this.setText(text); - this.setBubbleSize(size.width, size.height); -}; - -/** - * Bring the comment to the top of the stack when clicked on. - * @param {!Event} _e Mouse up event. - * @private - */ -Blockly.Comment.prototype.textareaFocus_ = function(_e) { - // Ideally this would be hooked to the focus event for the comment. - // This is tied to mousedown, however doing so in Firefox swallows the cursor - // for unknown reasons. - // See https://github.com/LLK/scratch-blocks/issues/1631 for more history. - if (this.bubble_.promote_()) { - // Since the act of moving this node within the DOM causes a loss of focus, - // we need to reapply the focus. - this.textarea_.focus(); - } -}; - -/** - * Get the dimensions of this comment's bubble. - * @return {!Object} Object with width and height properties. - */ -Blockly.Comment.prototype.getBubbleSize = function() { - if (this.isVisible()) { - return this.bubble_.getBubbleSize(); - } else { - return {width: this.width_, height: this.height_}; - } -}; - -/** - * Size this comment's bubble. - * @param {number} width Width of the bubble. - * @param {number} height Height of the bubble. - */ -Blockly.Comment.prototype.setBubbleSize = function(width, height) { - if (this.textarea_) { - this.bubble_.setBubbleSize(width, height); - } else { - this.width_ = width; - this.height_ = height; - } -}; - -/** - * Returns this comment's text. - * @return {string} Comment text. - */ -Blockly.Comment.prototype.getText = function() { - return this.textarea_ ? this.textarea_.value : this.text_; -}; - -/** - * Set this comment's text. - * @param {string} text Comment text. - */ -Blockly.Comment.prototype.setText = function(text) { - if (this.text_ != text) { - Blockly.Events.fire(new Blockly.Events.BlockChange( - this.block_, 'comment', null, this.text_, text)); - this.text_ = text; - } - if (this.textarea_) { - this.textarea_.value = text; - } -}; - -/** - * Dispose of this comment. - */ -Blockly.Comment.prototype.dispose = function() { - if (Blockly.Events.isEnabled()) { - this.setText(''); // Fire event to delete comment. - } - this.block_.comment = null; - Blockly.Icon.prototype.dispose.call(this); -}; diff --git a/core/comment_events.js b/core/comment_events.js deleted file mode 100644 index d9a13c7f2d..0000000000 --- a/core/comment_events.js +++ /dev/null @@ -1,539 +0,0 @@ -/** - * @license - * Visual Blocks Editor - * - * Copyright 2018 Google Inc. - * https://developers.google.com/blockly/ - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @fileoverview Classes for all comment events. - * @author fenichel@google.com (Rachel Fenichel) - */ -'use strict'; - -goog.provide('Blockly.Events.CommentBase'); -goog.provide('Blockly.Events.CommentChange'); -goog.provide('Blockly.Events.CommentCreate'); -goog.provide('Blockly.Events.CommentDelete'); -goog.provide('Blockly.Events.CommentMove'); - -goog.require('Blockly.Events'); -goog.require('Blockly.Events.Abstract'); - -goog.require('goog.math.Coordinate'); - - -/** - * Abstract class for a comment event. - * @param {Blockly.WorkspaceComment | Blockly.ScratchBlockComment} comment - * The comment this event corresponds to. - * @extends {Blockly.Events.Abstract} - * @constructor - */ -Blockly.Events.CommentBase = function(comment) { - /** - * The ID of the comment this event pertains to. - * @type {string} - */ - this.commentId = comment.id; - - /** - * The workspace identifier for this event. - * @type {string} - */ - this.workspaceId = comment.workspace.id; - - /** - * The ID of the block this comment belongs to or null if it is not a block - * comment. - * @type {string} - */ - this.blockId = comment.blockId || null; - - /** - * The event group id for the group this event belongs to. Groups define - * events that should be treated as an single action from the user's - * perspective, and should be undone together. - * @type {string} - */ - this.group = Blockly.Events.group_; - - /** - * Sets whether the event should be added to the undo stack. - * @type {boolean} - */ - this.recordUndo = Blockly.Events.recordUndo; -}; -goog.inherits(Blockly.Events.CommentBase, Blockly.Events.Abstract); - -/** - * Encode the event as JSON. - * @return {!Object} JSON representation. - */ -Blockly.Events.CommentBase.prototype.toJson = function() { - var json = { - 'type': this.type - }; - if (this.group) { - json['group'] = this.group; - } - if (this.commentId) { - json['commentId'] = this.commentId; - } - if (this.blockId) { - json['blockId'] = this.blockId; - } - return json; -}; - -/** - * Decode the JSON event. - * @param {!Object} json JSON representation. - */ -Blockly.Events.CommentBase.prototype.fromJson = function(json) { - this.commentId = json['commentId']; - this.group = json['group']; - this.blockId = json['blockId']; -}; - -/** - * Helper function for finding the comment this event pertains to. - * @return {?(Blockly.WorkspaceComment | Blockly.ScratchBlockComment)} - * The comment this event pertains to, or null if it no longer exists. - * @private - */ -Blockly.Events.CommentBase.prototype.getComment_ = function() { - var workspace = this.getEventWorkspace_(); - return workspace.getCommentById(this.commentId); -}; - -/** - * Class for a comment change event. - * @param {Blockly.WorkspaceComment | Blockly.ScratchBlockComment} comment - * The comment that is being changed. Null for a blank event. - * @param {!object} oldContents Object containing previous state of a comment's - * properties. The possible properties can be: 'minimized', 'text', or - * 'width' and 'height' together. Must contain the same property (or in the - * case of 'width' and 'height' properties) as the 'newContents' param. - * @param {!object} newContents Object containing the new state of a comment's - * properties. The possible properties can be: 'minimized', 'text', or - * 'width' and 'height' together. Must contain the same property (or in the - * case of 'width' and 'height' properties) as the 'oldContents' param. - * @extends {Blockly.Events.CommentBase} - * @constructor - */ -Blockly.Events.CommentChange = function(comment, oldContents, newContents) { - if (!comment) { - return; // Blank event to be populated by fromJson. - } - Blockly.Events.CommentChange.superClass_.constructor.call(this, comment); - this.oldContents_ = oldContents; - this.newContents_ = newContents; -}; -goog.inherits(Blockly.Events.CommentChange, Blockly.Events.CommentBase); - -/** - * Type of this event. - * @type {string} - */ -Blockly.Events.CommentChange.prototype.type = Blockly.Events.COMMENT_CHANGE; - -/** - * Encode the event as JSON. - * @return {!Object} JSON representation. - */ -Blockly.Events.CommentChange.prototype.toJson = function() { - var json = Blockly.Events.CommentChange.superClass_.toJson.call(this); - json['newContents'] = this.newContents_; - return json; -}; - -/** - * Decode the JSON event. - * @param {!Object} json JSON representation. - */ -Blockly.Events.CommentChange.prototype.fromJson = function(json) { - Blockly.Events.CommentChange.superClass_.fromJson.call(this, json); - this.newContents_ = json['newValue']; -}; - -/** - * Does this event record any change of state? - * @return {boolean} False if something changed. - */ -Blockly.Events.CommentChange.prototype.isNull = function() { - return this.oldContents_ == this.newContents_; -}; - -/** - * Run a change event. - * @param {boolean} forward True if run forward, false if run backward (undo). - */ -Blockly.Events.CommentChange.prototype.run = function(forward) { - var comment = this.getComment_(); - if (!comment) { - console.warn('Can\'t change non-existent comment: ' + this.commentId); - return; - } - var contents = forward ? this.newContents_ : this.oldContents_; - - if (contents.hasOwnProperty('minimized')) { - comment.setMinimized(contents.minimized); - } - if (contents.hasOwnProperty('width') && contents.hasOwnProperty('height')) { - comment.setSize(contents.width, contents.height); - } - if (contents.hasOwnProperty('text')) { - comment.setText(contents.text); - } -}; - -/** - * Class for a comment creation event. - * @param {Blockly.WorkspaceComment | Blockly.ScratchBlockComment} comment - * The created comment. Null for a blank event. - * @param {string=} opt_blockId Optional id for the block this comment belongs - * to, if it is a block comment. - * @extends {Blockly.Events.CommentBase} - * @constructor - */ -Blockly.Events.CommentCreate = function(comment) { - if (!comment) { - return; // Blank event to be populated by fromJson. - } - Blockly.Events.CommentCreate.superClass_.constructor.call(this, comment); - - /** - * The text content of this comment. - * @type {string} - */ - this.text = comment.getText(); - - /** - * The XY position of this comment on the workspace. - * @type {goog.math.Coordinate} - */ - this.xy = comment.getXY(); - - var hw = comment.getHeightWidth(); - - /** - * The width of this comment when it is full size. - * @type {number} - */ - this.width = hw.width; - - /** - * The height of this comment when it is full size. - * @type {number} - */ - this.height = hw.height; - - /** - * Whether or not this comment is minimized. - * @type {boolean} - */ - this.minimized = comment.isMinimized() || false; - - this.xml = comment.toXmlWithXY(); -}; -goog.inherits(Blockly.Events.CommentCreate, Blockly.Events.CommentBase); - -/** - * Type of this event. - * @type {string} - */ -Blockly.Events.CommentCreate.prototype.type = Blockly.Events.COMMENT_CREATE; - -/** - * Encode the event as JSON. - * TODO (github.com/google/blockly/issues/1266): "Full" and "minimal" - * serialization. - * @return {!Object} JSON representation. - */ -Blockly.Events.CommentCreate.prototype.toJson = function() { - var json = Blockly.Events.CommentCreate.superClass_.toJson.call(this); - json['xml'] = Blockly.Xml.domToText(this.xml); - return json; -}; - -/** - * Decode the JSON event. - * @param {!Object} json JSON representation. - */ -Blockly.Events.CommentCreate.prototype.fromJson = function(json) { - Blockly.Events.CommentCreate.superClass_.fromJson.call(this, json); - this.xml = Blockly.Xml.textToDom('' + json['xml'] + '').firstChild; -}; - -/** - * Run a creation event. - * @param {boolean} forward True if run forward, false if run backward (undo). - */ -Blockly.Events.CommentCreate.prototype.run = function(forward) { - if (forward) { - var workspace = this.getEventWorkspace_(); - if (this.blockId) { - var block = workspace.getBlockById(this.blockId); - if (block) { - block.setCommentText('', this.commentId, this.xy.x, this.xy.y, this.minimized); - } - } else { - var xml = goog.dom.createDom('xml'); - xml.appendChild(this.xml); - Blockly.Xml.domToWorkspace(xml, workspace); - } - } else { - var comment = this.getComment_(); - if (comment) { - comment.dispose(false, false); - } else { - // Only complain about root-level block. - console.warn("Can't uncreate non-existent comment: " + this.commentId); - } - } -}; - -/** - * Class for a comment deletion event. - * @param {Blockly.WorkspaceComment | Blockly.ScratchBlockComment} comment - * The deleted comment. Null for a blank event. - * @extends {Blockly.Events.CommentBase} - * @constructor - */ -Blockly.Events.CommentDelete = function(comment) { - if (!comment) { - return; // Blank event to be populated by fromJson. - } - Blockly.Events.CommentDelete.superClass_.constructor.call(this, comment); - this.xy = comment.getXY(); - this.minimized = comment.isMinimized() || false; - this.text = comment.getText(); - var hw = comment.getHeightWidth(); - this.height = hw.height; - this.width = hw.width; - - this.xml = comment.toXmlWithXY(); -}; -goog.inherits(Blockly.Events.CommentDelete, Blockly.Events.CommentBase); - -/** - * Type of this event. - * @type {string} - */ -Blockly.Events.CommentDelete.prototype.type = Blockly.Events.COMMENT_DELETE; - -/** - * Encode the event as JSON. - * TODO (github.com/google/blockly/issues/1266): "Full" and "minimal" - * serialization. - * @return {!Object} JSON representation. - */ -Blockly.Events.CommentDelete.prototype.toJson = function() { - var json = Blockly.Events.CommentDelete.superClass_.toJson.call(this); - return json; -}; - -/** - * Decode the JSON event. - * @param {!Object} json JSON representation. - */ -Blockly.Events.CommentDelete.prototype.fromJson = function(json) { - Blockly.Events.CommentDelete.superClass_.fromJson.call(this, json); -}; - -/** - * Run a creation event. - * @param {boolean} forward True if run forward, false if run backward (undo). - */ -Blockly.Events.CommentDelete.prototype.run = function(forward) { - if (forward) { - var comment = this.getComment_(); - if (comment) { - comment.dispose(false, false); - } else { - // Only complain about root-level block. - console.warn("Can't delete non-existent comment: " + this.commentId); - } - } else { - var workspace = this.getEventWorkspace_(); - if (this.blockId) { - var block = workspace.getBlockById(this.blockId); - block.setCommentText(this.text, this.commentId, this.xy.x, this.xy.y, this.minimized); - block.comment.setSize(this.width, this.height); - } else { - var xml = goog.dom.createDom('xml'); - xml.appendChild(this.xml); - Blockly.Xml.domToWorkspace(xml, workspace); - } - } -}; - -/** - * Class for a comment move event. Created before the move. - * @param {Blockly.WorkspaceComment | Blockly.ScratchBlockComment} comment - * The comment that is being moved. Null for a blank event. - * @extends {Blockly.Events.CommentBase} - * @constructor - */ -Blockly.Events.CommentMove = function(comment) { - if (!comment) { - return; // Blank event to be populated by fromJson. - } - Blockly.Events.CommentMove.superClass_.constructor.call(this, comment); - - /** - * The comment that is being moved. Will be cleared after recording the new - * location. - * @type {?Blockly.WorkspaceComment | Blockly.ScratchBlockComment} - */ - this.comment_ = comment; - - this.workspaceWidth_ = comment.workspace.getWidth(); - /** - * The location before the move, in workspace coordinates. - * @type {!goog.math.Coordinate} - */ - this.oldCoordinate_ = this.currentLocation_(); - - /** - * The location after the move, in workspace coordinates. - * @type {!goog.math.Coordinate} - */ - this.newCoordinate_ = null; -}; -goog.inherits(Blockly.Events.CommentMove, Blockly.Events.CommentBase); - -/** - * Calculate the current, language agnostic location of the comment. - * This value should not report different numbers in LTR vs. RTL. - * @return {goog.math.Coordinate} The location of the comment. - * @private - */ -Blockly.Events.CommentMove.prototype.currentLocation_ = function() { - var xy = this.comment_.getXY(); - if (!this.comment_.workspace.RTL) { - return xy; - } - - var rtlAwareX; - if (this.comment_ instanceof Blockly.ScratchBlockComment) { - var commentWidth = this.comment_.getBubbleSize().width; - rtlAwareX = this.workspaceWidth_ - xy.x - commentWidth; - } else { - rtlAwareX = this.workspaceWidth_ - xy.x; - } - return new goog.math.Coordinate(rtlAwareX, xy.y); -}; - -/** - * Record the comment's new location. Called after the move. Can only be - * called once. - */ -Blockly.Events.CommentMove.prototype.recordNew = function() { - if (!this.comment_) { - throw new Error('Tried to record the new position of a comment on the ' + - 'same event twice.'); - } - this.newCoordinate_ = this.currentLocation_(); - this.comment_ = null; -}; - -/** - * Type of this event. - * @type {string} - */ -Blockly.Events.CommentMove.prototype.type = Blockly.Events.COMMENT_MOVE; - -/** - * Override the location before the move. Use this if you don't create the - * event until the end of the move, but you know the original location. - * @param {!goog.math.Coordinate} xy The location before the move, in workspace - * coordinates. - */ -Blockly.Events.CommentMove.prototype.setOldCoordinate = function(xy) { - this.oldCoordinate_ = new goog.math.Coordinate(this.comment_.workspace.RTL ? - this.workspaceWidth_ - xy.x : xy.x, xy.y); -}; - -/** - * Encode the event as JSON. - * TODO (github.com/google/blockly/issues/1266): "Full" and "minimal" - * serialization. - * @return {!Object} JSON representation. - */ -Blockly.Events.CommentMove.prototype.toJson = function() { - var json = Blockly.Events.CommentMove.superClass_.toJson.call(this); - if (this.newCoordinate_) { - json['newCoordinate'] = Math.round(this.newCoordinate_.x) + ',' + - Math.round(this.newCoordinate_.y); - } - return json; -}; - -/** - * Decode the JSON event. - * @param {!Object} json JSON representation. - */ -Blockly.Events.CommentMove.prototype.fromJson = function(json) { - Blockly.Events.CommentMove.superClass_.fromJson.call(this, json); - - if (json['newCoordinate']) { - var xy = json['newCoordinate'].split(','); - this.newCoordinate_ = - new goog.math.Coordinate(parseFloat(xy[0]), parseFloat(xy[1])); - } -}; - -/** - * Does this event record any change of state? - * @return {boolean} False if something changed. - */ -Blockly.Events.CommentMove.prototype.isNull = function() { - return goog.math.Coordinate.equals(this.oldCoordinate_, this.newCoordinate_); -}; - -/** - * Run a move event. - * @param {boolean} forward True if run forward, false if run backward (undo). - */ -Blockly.Events.CommentMove.prototype.run = function(forward) { - var comment = this.getComment_(); - if (!comment) { - console.warn('Can\'t move non-existent comment: ' + this.commentId); - return; - } - - var target = forward ? this.newCoordinate_ : this.oldCoordinate_; - - if (comment instanceof Blockly.ScratchBlockComment) { - if (comment.workspace.RTL) { - comment.moveTo(this.workspaceWidth_ - target.x, target.y); - } else { - comment.moveTo(target.x, target.y); - } - } else { - // TODO: Check if the comment is being dragged, and give up if so. - var current = comment.getXY(); - if (comment.workspace.RTL) { - var deltaX = target.x - (this.workspaceWidth_ - current.x); - comment.moveBy(-deltaX, target.y - current.y); - } else { - comment.moveBy(target.x - current.x, target.y - current.y); - } - - } -}; diff --git a/core/connection.js b/core/connection.js deleted file mode 100644 index cfc0f779c3..0000000000 --- a/core/connection.js +++ /dev/null @@ -1,766 +0,0 @@ -/** - * @license - * Visual Blocks Editor - * - * Copyright 2011 Google Inc. - * https://developers.google.com/blockly/ - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @fileoverview Components for creating connections between blocks. - * @author fraser@google.com (Neil Fraser) - */ -'use strict'; - -goog.provide('Blockly.Connection'); - -goog.require('Blockly.Events.BlockMove'); - -goog.require('goog.asserts'); -goog.require('goog.dom'); - - -/** - * Class for a connection between blocks. - * @param {!Blockly.Block} source The block establishing this connection. - * @param {number} type The type of the connection. - * @constructor - */ -Blockly.Connection = function(source, type) { - /** - * @type {!Blockly.Block} - * @protected - */ - this.sourceBlock_ = source; - /** @type {number} */ - this.type = type; - // Shortcut for the databases for this connection's workspace. - if (source.workspace.connectionDBList) { - this.db_ = source.workspace.connectionDBList[type]; - this.dbOpposite_ = - source.workspace.connectionDBList[Blockly.OPPOSITE_TYPE[type]]; - this.hidden_ = !this.db_; - } -}; - -/** - * Constants for checking whether two connections are compatible. - */ -Blockly.Connection.CAN_CONNECT = 0; -Blockly.Connection.REASON_SELF_CONNECTION = 1; -Blockly.Connection.REASON_WRONG_TYPE = 2; -Blockly.Connection.REASON_TARGET_NULL = 3; -Blockly.Connection.REASON_CHECKS_FAILED = 4; -Blockly.Connection.REASON_DIFFERENT_WORKSPACES = 5; -Blockly.Connection.REASON_SHADOW_PARENT = 6; -// Fixes #1127, but may be the wrong solution. -Blockly.Connection.REASON_CUSTOM_PROCEDURE = 7; - -/** - * Connection this connection connects to. Null if not connected. - * @type {Blockly.Connection} - */ -Blockly.Connection.prototype.targetConnection = null; - -/** - * List of compatible value types. Null if all types are compatible. - * @type {Array} - * @private - */ -Blockly.Connection.prototype.check_ = null; - -/** - * DOM representation of a shadow block, or null if none. - * @type {Element} - * @private - */ -Blockly.Connection.prototype.shadowDom_ = null; - -/** - * Horizontal location of this connection. - * @type {number} - * @protected - */ -Blockly.Connection.prototype.x_ = 0; - -/** - * Vertical location of this connection. - * @type {number} - * @protected - */ -Blockly.Connection.prototype.y_ = 0; - -/** - * Has this connection been added to the connection database? - * @type {boolean} - * @protected - */ -Blockly.Connection.prototype.inDB_ = false; - -/** - * Connection database for connections of this type on the current workspace. - * @type {Blockly.ConnectionDB} - * @protected - */ -Blockly.Connection.prototype.db_ = null; - -/** - * Connection database for connections compatible with this type on the - * current workspace. - * @type {Blockly.ConnectionDB} - * @protected - */ -Blockly.Connection.prototype.dbOpposite_ = null; - -/** - * Whether this connections is hidden (not tracked in a database) or not. - * @type {boolean} - * @protected - */ -Blockly.Connection.prototype.hidden_ = null; - -/** - * Connect two connections together. This is the connection on the superior - * block. - * @param {!Blockly.Connection} childConnection Connection on inferior block. - * @protected - */ -Blockly.Connection.prototype.connect_ = function(childConnection) { - var parentConnection = this; - var parentBlock = parentConnection.getSourceBlock(); - var childBlock = childConnection.getSourceBlock(); - var isSurroundingC = false; - if (parentConnection == parentBlock.getFirstStatementConnection()) { - isSurroundingC = true; - } - // Disconnect any existing parent on the child connection. - if (childConnection.isConnected()) { - // Scratch-specific behaviour: - // If we're using a c-shaped block to surround a stack, remember where the - // stack used to be connected. - if (isSurroundingC) { - var previousParentConnection = childConnection.targetConnection; - } - childConnection.disconnect(); - } - if (parentConnection.isConnected()) { - // Other connection is already connected to something. - // Disconnect it and reattach it or bump it as needed. - var orphanBlock = parentConnection.targetBlock(); - var shadowDom = parentConnection.getShadowDom(); - // Temporarily set the shadow DOM to null so it does not respawn. - parentConnection.setShadowDom(null); - // Displaced shadow blocks dissolve rather than reattaching or bumping. - if (orphanBlock.isShadow()) { - // Save the shadow block so that field values are preserved. - shadowDom = Blockly.Xml.blockToDom(orphanBlock); - orphanBlock.dispose(); - orphanBlock = null; - } else if (parentConnection.type == Blockly.NEXT_STATEMENT) { - // Statement connections. - // Statement blocks may be inserted into the middle of a stack. - // Split the stack. - if (!orphanBlock.previousConnection) { - throw 'Orphan block does not have a previous connection.'; - } - // Attempt to reattach the orphan at the bottom of the newly inserted - // block. Since this block may be a stack, walk down to the end. - var newBlock = childBlock; - while (newBlock.nextConnection) { - var nextBlock = newBlock.getNextBlock(); - if (nextBlock && !nextBlock.isShadow()) { - newBlock = nextBlock; - } else { - if (orphanBlock.previousConnection.checkType_( - newBlock.nextConnection)) { - newBlock.nextConnection.connect(orphanBlock.previousConnection); - orphanBlock = null; - } - break; - } - } - } - if (orphanBlock) { - // Unable to reattach orphan. - parentConnection.disconnect(); - if (Blockly.Events.recordUndo) { - // Bump it off to the side after a moment. - var group = Blockly.Events.getGroup(); - setTimeout(function() { - // Verify orphan hasn't been deleted or reconnected (user on meth). - if (orphanBlock.workspace && !orphanBlock.getParent()) { - Blockly.Events.setGroup(group); - if (orphanBlock.outputConnection) { - orphanBlock.outputConnection.bumpAwayFrom_(parentConnection); - } else if (orphanBlock.previousConnection) { - orphanBlock.previousConnection.bumpAwayFrom_(parentConnection); - } - Blockly.Events.setGroup(false); - } - }, Blockly.BUMP_DELAY); - } - } - // Restore the shadow DOM. - parentConnection.setShadowDom(shadowDom); - } - - if (isSurroundingC && previousParentConnection) { - previousParentConnection.connect(parentBlock.previousConnection); - } - - var event; - if (Blockly.Events.isEnabled()) { - event = new Blockly.Events.BlockMove(childBlock); - } - // Establish the connections. - Blockly.Connection.connectReciprocally_(parentConnection, childConnection); - // Demote the inferior block so that one is a child of the superior one. - childBlock.setParent(parentBlock); - if (event) { - event.recordNew(); - Blockly.Events.fire(event); - } -}; - -/** - * Sever all links to this connection (not including from the source object). - */ -Blockly.Connection.prototype.dispose = function() { - if (this.isConnected()) { - throw 'Disconnect connection before disposing of it.'; - } - if (this.inDB_) { - this.db_.removeConnection_(this); - } - this.db_ = null; - this.dbOpposite_ = null; -}; - -/** - * @return {boolean} true if the connection is not connected or is connected to - * an insertion marker, false otherwise. - */ -Blockly.Connection.prototype.isConnectedToNonInsertionMarker = function() { - return this.targetConnection && !this.targetBlock().isInsertionMarker(); -}; - -/** - * Get the source block for this connection. - * @return {Blockly.Block} The source block, or null if there is none. - */ -Blockly.Connection.prototype.getSourceBlock = function() { - return this.sourceBlock_; -}; - -/** - * Does the connection belong to a superior block (higher in the source stack)? - * @return {boolean} True if connection faces down or right. - */ -Blockly.Connection.prototype.isSuperior = function() { - return this.type == Blockly.INPUT_VALUE || - this.type == Blockly.NEXT_STATEMENT; -}; - -/** - * Is the connection connected? - * @return {boolean} True if connection is connected to another connection. - */ -Blockly.Connection.prototype.isConnected = function() { - return !!this.targetConnection; -}; - -/** - * Checks whether the current connection can connect with the target - * connection. - * @param {Blockly.Connection} target Connection to check compatibility with. - * @return {number} Blockly.Connection.CAN_CONNECT if the connection is legal, - * an error code otherwise. - * @private - */ -Blockly.Connection.prototype.canConnectWithReason_ = function(target) { - if (!target) { - return Blockly.Connection.REASON_TARGET_NULL; - } - if (this.isSuperior()) { - var blockA = this.sourceBlock_; - var blockB = target.getSourceBlock(); - var superiorConn = this; - } else { - var blockB = this.sourceBlock_; - var blockA = target.getSourceBlock(); - var superiorConn = target; - } - if (blockA && blockA == blockB) { - return Blockly.Connection.REASON_SELF_CONNECTION; - } else if (target.type != Blockly.OPPOSITE_TYPE[this.type]) { - return Blockly.Connection.REASON_WRONG_TYPE; - } else if (blockA && blockB && blockA.workspace !== blockB.workspace) { - return Blockly.Connection.REASON_DIFFERENT_WORKSPACES; - } else if (!this.checkType_(target)) { - return Blockly.Connection.REASON_CHECKS_FAILED; - } else if (blockA.isShadow() && !blockB.isShadow()) { - return Blockly.Connection.REASON_SHADOW_PARENT; - } else if ((blockA.type == Blockly.PROCEDURES_DEFINITION_BLOCK_TYPE && - blockB.type != Blockly.PROCEDURES_PROTOTYPE_BLOCK_TYPE && - superiorConn == blockA.getInput('custom_block').connection) || - (blockB.type == Blockly.PROCEDURES_PROTOTYPE_BLOCK_TYPE && - blockA.type != Blockly.PROCEDURES_DEFINITION_BLOCK_TYPE)) { - // Hack to fix #1127: Fail attempts to connect to the custom_block input - // on a defnoreturn block, unless the connecting block is a specific type. - // And hack to fix #1534: Fail attempts to connect anything but a - // defnoreturn block to a prototype block. - return Blockly.Connection.REASON_CUSTOM_PROCEDURE; - } - return Blockly.Connection.CAN_CONNECT; -}; - -/** - * Checks whether the current connection and target connection are compatible - * and throws an exception if they are not. - * @param {Blockly.Connection} target The connection to check compatibility - * with. - * @private - */ -Blockly.Connection.prototype.checkConnection_ = function(target) { - switch (this.canConnectWithReason_(target)) { - case Blockly.Connection.CAN_CONNECT: - break; - case Blockly.Connection.REASON_SELF_CONNECTION: - throw 'Attempted to connect a block to itself.'; - case Blockly.Connection.REASON_DIFFERENT_WORKSPACES: - // Usually this means one block has been deleted. - throw 'Blocks not on same workspace.'; - case Blockly.Connection.REASON_WRONG_TYPE: - throw 'Attempt to connect incompatible types.'; - case Blockly.Connection.REASON_TARGET_NULL: - throw 'Target connection is null.'; - case Blockly.Connection.REASON_CHECKS_FAILED: - var msg = 'Connection checks failed. '; - msg += this + ' expected ' + this.check_ + ', found ' + target.check_; - throw msg; - case Blockly.Connection.REASON_SHADOW_PARENT: - throw 'Connecting non-shadow to shadow block.'; - case Blockly.Connection.REASON_CUSTOM_PROCEDURE: - throw 'Trying to replace a shadow on a custom procedure definition.'; - default: - throw 'Unknown connection failure: this should never happen!'; - } -}; - -/** - * Check if the two connections can be dragged to connect to each other. - * This is used by the connection database when searching for the closest - * connection. - * @param {!Blockly.Connection} candidate A nearby connection to check, which - * must be a previous connection. - * @return {boolean} True if the connection is allowed, false otherwise. - */ -Blockly.Connection.prototype.canConnectToPrevious_ = function(candidate) { - if (this.targetConnection) { - // This connection is already occupied. - // A next connection will never disconnect itself mid-drag. - return false; - } - - // Don't let blocks try to connect to themselves or ones they nest. - if (Blockly.draggingConnections_.indexOf(candidate) != -1) { - return false; - } - - var firstStatementConnection = - this.sourceBlock_.getFirstStatementConnection(); - // Is it a C-shaped (e.g. repeat) or E-shaped (e.g. if-else) block? - var isComplexStatement = firstStatementConnection != null; - var isFirstStatementConnection = this == firstStatementConnection; - var isNextConnection = this == this.sourceBlock_.nextConnection; - - // Scratch-specific behaviour: can connect to the first statement input of a - // C-shaped or E-shaped block, or to the next connection of any statement - // block, but not to the second statement input of an E-shaped block. - if (isComplexStatement && !isFirstStatementConnection && !isNextConnection) { - return false; - } - - // Complex blocks with no previous connection will not be allowed to connect - // mid-stack. - var sourceHasPreviousConn = this.sourceBlock_.previousConnection != null; - - if (isFirstStatementConnection && sourceHasPreviousConn) { - return true; - } - - if (isNextConnection || - (isFirstStatementConnection && !sourceHasPreviousConn)) { - // If the candidate is the first connection in a stack, we can connect. - if (!candidate.targetConnection) { - return true; - } - - var targetBlock = candidate.targetBlock(); - // If it is connected a real block, game over. - if (!targetBlock.isInsertionMarker()) { - return false; - } - // If it's connected to an insertion marker but that insertion marker - // is the first block in a stack, it's still fine. If that insertion - // marker is in the middle of a stack, it won't work. - return !targetBlock.getPreviousBlock(); - } -}; - -/** - * Check if the two connections can be dragged to connect to each other. - * This is used by the connection database when searching for the closest - * connection. - * @param {!Blockly.Connection} candidate A nearby connection to check. - * @return {boolean} True if the connection is allowed, false otherwise. - */ -Blockly.Connection.prototype.isConnectionAllowed = function(candidate) { - - // Don't consider insertion markers. - if (candidate.sourceBlock_.isInsertionMarker()) { - return false; - } - - // Type checking. - var canConnect = this.canConnectWithReason_(candidate); - if (canConnect != Blockly.Connection.CAN_CONNECT) { - return false; - } - - var firstStatementConnection = - this.sourceBlock_.getFirstStatementConnection(); - switch (candidate.type) { - case Blockly.PREVIOUS_STATEMENT: - return this.canConnectToPrevious_(candidate); - case Blockly.OUTPUT_VALUE: { - // Can't drag an input to an output--you have to move the inferior block. - return false; - } - case Blockly.INPUT_VALUE: { - // Offering to connect the left (male) of a value block to an already - // connected value pair is ok, we'll splice it in. - // However, don't offer to splice into an unmovable block. - if (candidate.targetConnection && - !candidate.targetBlock().isMovable() && - !candidate.targetBlock().isShadow()) { - return false; - } - break; - } - case Blockly.NEXT_STATEMENT: { - // Scratch-specific behaviour: - // If this is a c-block, we can't connect this block's - // previous connection unless we're connecting to the end of the last - // block on a stack or there's already a block connected inside the c. - if (firstStatementConnection && - this == this.sourceBlock_.previousConnection && - candidate.isConnectedToNonInsertionMarker() && - !firstStatementConnection.targetConnection) { - return false; - } - // Don't let a block with no next connection bump other blocks out of the - // stack. But covering up a shadow block or stack of shadow blocks is - // fine. Similarly, replacing a terminal statement with another terminal - // statement is allowed. - if (candidate.isConnectedToNonInsertionMarker() && - !this.sourceBlock_.nextConnection && - !candidate.targetBlock().isShadow() && - candidate.targetBlock().nextConnection) { - return false; - } - break; - } - default: - throw 'Unknown connection type in isConnectionAllowed'; - } - - // Don't let blocks try to connect to themselves or ones they nest. - if (Blockly.draggingConnections_.indexOf(candidate) != -1) { - return false; - } - - return true; -}; - -/** - * Connect this connection to another connection. - * @param {!Blockly.Connection} otherConnection Connection to connect to. - */ -Blockly.Connection.prototype.connect = function(otherConnection) { - if (this.targetConnection == otherConnection) { - // Already connected together. NOP. - return; - } - this.checkConnection_(otherConnection); - // Determine which block is superior (higher in the source stack). - if (this.isSuperior()) { - // Superior block. - this.connect_(otherConnection); - } else { - // Inferior block. - otherConnection.connect_(this); - } -}; - -/** - * Update two connections to target each other. - * @param {Blockly.Connection} first The first connection to update. - * @param {Blockly.Connection} second The second connection to update. - * @private - */ -Blockly.Connection.connectReciprocally_ = function(first, second) { - goog.asserts.assert(first && second, 'Cannot connect null connections.'); - first.targetConnection = second; - second.targetConnection = first; -}; - -/** - * Does the given block have one and only one connection point that will accept - * an orphaned block? - * @param {!Blockly.Block} block The superior block. - * @param {!Blockly.Block} orphanBlock The inferior block. - * @return {Blockly.Connection} The suitable connection point on 'block', - * or null. - * @private - */ -Blockly.Connection.singleConnection_ = function(block, orphanBlock) { - var connection = false; - for (var i = 0; i < block.inputList.length; i++) { - var thisConnection = block.inputList[i].connection; - if (thisConnection && thisConnection.type == Blockly.INPUT_VALUE && - orphanBlock.outputConnection.checkType_(thisConnection)) { - if (connection) { - return null; // More than one connection. - } - connection = thisConnection; - } - } - return connection; -}; - -/** - * Disconnect this connection. - */ -Blockly.Connection.prototype.disconnect = function() { - var otherConnection = this.targetConnection; - goog.asserts.assert(otherConnection, 'Source connection not connected.'); - goog.asserts.assert(otherConnection.targetConnection == this, - 'Target connection not connected to source connection.'); - - var parentBlock, childBlock, parentConnection; - if (this.isSuperior()) { - // Superior block. - parentBlock = this.sourceBlock_; - childBlock = otherConnection.getSourceBlock(); - parentConnection = this; - } else { - // Inferior block. - parentBlock = otherConnection.getSourceBlock(); - childBlock = this.sourceBlock_; - parentConnection = otherConnection; - } - this.disconnectInternal_(parentBlock, childBlock); - parentConnection.respawnShadow_(); -}; - -/** - * Disconnect two blocks that are connected by this connection. - * @param {!Blockly.Block} parentBlock The superior block. - * @param {!Blockly.Block} childBlock The inferior block. - * @protected - */ -Blockly.Connection.prototype.disconnectInternal_ = function(parentBlock, - childBlock) { - var event; - if (Blockly.Events.isEnabled()) { - event = new Blockly.Events.BlockMove(childBlock); - } - var otherConnection = this.targetConnection; - otherConnection.targetConnection = null; - this.targetConnection = null; - childBlock.setParent(null); - if (event) { - event.recordNew(); - Blockly.Events.fire(event); - } -}; - -/** - * Respawn the shadow block if there was one connected to the this connection. - * @protected - */ -Blockly.Connection.prototype.respawnShadow_ = function() { - var parentBlock = this.getSourceBlock(); - var shadow = this.getShadowDom(); - if (parentBlock.workspace && shadow && Blockly.Events.recordUndo) { - var blockShadow = - Blockly.Xml.domToBlock(shadow, parentBlock.workspace); - if (blockShadow.outputConnection) { - this.connect(blockShadow.outputConnection); - } else if (blockShadow.previousConnection) { - this.connect(blockShadow.previousConnection); - } else { - throw 'Child block does not have output or previous statement.'; - } - } -}; - -/** - * Returns the block that this connection connects to. - * @return {Blockly.Block} The connected block or null if none is connected. - */ -Blockly.Connection.prototype.targetBlock = function() { - if (this.isConnected()) { - return this.targetConnection.getSourceBlock(); - } - return null; -}; - -/** - * Is this connection compatible with another connection with respect to the - * value type system. E.g. square_root("Hello") is not compatible. - * @param {!Blockly.Connection} otherConnection Connection to compare against. - * @return {boolean} True if the connections share a type. - * @protected - */ -Blockly.Connection.prototype.checkType_ = function(otherConnection) { - if (!this.check_ || !otherConnection.check_) { - // One or both sides are promiscuous enough that anything will fit. - return true; - } - // Find any intersection in the check lists. - for (var i = 0; i < this.check_.length; i++) { - if (otherConnection.check_.indexOf(this.check_[i]) != -1) { - return true; - } - } - // No intersection. - return false; -}; - -/** - * Function to be called when this connection's compatible types have changed. - * @private - */ -Blockly.Connection.prototype.onCheckChanged_ = function() { - // The new value type may not be compatible with the existing connection. - if (this.isConnected() && !this.checkType_(this.targetConnection)) { - var child = this.isSuperior() ? this.targetBlock() : this.sourceBlock_; - child.unplug(); - } -}; - -/** - * Change a connection's compatibility. - * @param {*} check Compatible value type or list of value types. - * Null if all types are compatible. - * @return {!Blockly.Connection} The connection being modified - * (to allow chaining). - */ -Blockly.Connection.prototype.setCheck = function(check) { - if (check) { - // Ensure that check is in an array. - if (!goog.isArray(check)) { - check = [check]; - } - this.check_ = check; - this.onCheckChanged_(); - } else { - this.check_ = null; - } - return this; -}; - -/** - * Returns a shape enum for this connection. - * Used in scratch-blocks to draw unoccupied inputs. - * @return {number} Enum representing shape. - */ -Blockly.Connection.prototype.getOutputShape = function() { - if (!this.check_) return Blockly.OUTPUT_SHAPE_ROUND; - if (this.check_.indexOf('Boolean') !== -1) { - return Blockly.OUTPUT_SHAPE_HEXAGONAL; - } - if (this.check_.indexOf('Number') !== -1) { - return Blockly.OUTPUT_SHAPE_ROUND; - } - if (this.check_.indexOf('String') !== -1) { - return Blockly.OUTPUT_SHAPE_SQUARE; - } - return Blockly.OUTPUT_SHAPE_ROUND; -}; - -/** - * Change a connection's shadow block. - * @param {Element} shadow DOM representation of a block or null. - */ -Blockly.Connection.prototype.setShadowDom = function(shadow) { - this.shadowDom_ = shadow; -}; - -/** - * Return a connection's shadow block. - * @return {Element} shadow DOM representation of a block or null. - */ -Blockly.Connection.prototype.getShadowDom = function() { - return this.shadowDom_; -}; - -/** - * Find all nearby compatible connections to this connection. - * Type checking does not apply, since this function is used for bumping. - * - * Headless configurations (the default) do not have neighboring connection, - * and always return an empty list (the default). - * {@link Blockly.RenderedConnection} overrides this behavior with a list - * computed from the rendered positioning. - * @param {number} maxLimit The maximum radius to another connection. - * @return {!Array.} List of connections. - * @private - */ -Blockly.Connection.prototype.neighbours_ = function(/* maxLimit */) { - return []; -}; - -/** - * This method returns a string describing this Connection in developer terms - * (English only). Intended to on be used in console logs and errors. - * @return {string} The description. - */ -Blockly.Connection.prototype.toString = function() { - var msg; - var block = this.sourceBlock_; - if (!block) { - return 'Orphan Connection'; - } else if (block.outputConnection == this) { - msg = 'Output Connection of '; - } else if (block.previousConnection == this) { - msg = 'Previous Connection of '; - } else if (block.nextConnection == this) { - msg = 'Next Connection of '; - } else { - var parentInput = goog.array.find(block.inputList, function(input) { - return input.connection == this; - }, this); - if (parentInput) { - msg = 'Input "' + parentInput.name + '" connection on '; - } else { - console.warn('Connection not actually connected to sourceBlock_'); - return 'Orphan Connection'; - } - } - return msg + block.toDevString(); -}; diff --git a/core/connection_db.js b/core/connection_db.js deleted file mode 100644 index 476b824bbc..0000000000 --- a/core/connection_db.js +++ /dev/null @@ -1,300 +0,0 @@ -/** - * @license - * Visual Blocks Editor - * - * Copyright 2011 Google Inc. - * https://developers.google.com/blockly/ - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @fileoverview Components for managing connections between blocks. - * @author fraser@google.com (Neil Fraser) - */ -'use strict'; - -goog.provide('Blockly.ConnectionDB'); - -goog.require('Blockly.Connection'); - - -/** - * Database of connections. - * Connections are stored in order of their vertical component. This way - * connections in an area may be looked up quickly using a binary search. - * @constructor - */ -Blockly.ConnectionDB = function() { - /** - * Array of connections sorted by y coordinate. - * @type {!Array.} - * @private - */ - this.connections_ = []; -}; - -/** - * Add a connection to the database. Must not already exist in DB. - * @param {!Blockly.Connection} connection The connection to be added. - */ -Blockly.ConnectionDB.prototype.addConnection = function(connection) { - if (connection.inDB_) { - throw Error('Connection already in database.'); - } - if (connection.getSourceBlock().isInFlyout) { - // Don't bother maintaining a database of connections in a flyout. - return; - } - var position = this.findPositionForConnection_(connection); - this.connections_.splice(position, 0, connection); - connection.inDB_ = true; -}; - -/** - * Find the given connection. - * Starts by doing a binary search to find the approximate location, then - * linearly searches nearby for the exact connection. - * @param {!Blockly.Connection} conn The connection to find. - * @return {number} The index of the connection, or -1 if the connection was - * not found. - */ -Blockly.ConnectionDB.prototype.findConnection = function(conn) { - if (!this.connections_.length) { - return -1; - } - - var bestGuess = this.findPositionForConnection_(conn); - if (bestGuess >= this.connections_.length) { - // Not in list - return -1; - } - - var yPos = conn.y_; - // Walk forward and back on the y axis looking for the connection. - var pointerMin = bestGuess; - var pointerMax = bestGuess; - while (pointerMin >= 0 && this.connections_[pointerMin].y_ == yPos) { - if (this.connections_[pointerMin] == conn) { - return pointerMin; - } - pointerMin--; - } - - while (pointerMax < this.connections_.length && - this.connections_[pointerMax].y_ == yPos) { - if (this.connections_[pointerMax] == conn) { - return pointerMax; - } - pointerMax++; - } - return -1; -}; - -/** - * Finds a candidate position for inserting this connection into the list. - * This will be in the correct y order but makes no guarantees about ordering in - * the x axis. - * @param {!Blockly.Connection} connection The connection to insert. - * @return {number} The candidate index. - * @private - */ -Blockly.ConnectionDB.prototype.findPositionForConnection_ = function( - connection) { - if (!this.connections_.length) { - return 0; - } - var pointerMin = 0; - var pointerMax = this.connections_.length; - while (pointerMin < pointerMax) { - var pointerMid = Math.floor((pointerMin + pointerMax) / 2); - if (this.connections_[pointerMid].y_ < connection.y_) { - pointerMin = pointerMid + 1; - } else if (this.connections_[pointerMid].y_ > connection.y_) { - pointerMax = pointerMid; - } else { - pointerMin = pointerMid; - break; - } - } - return pointerMin; -}; - -/** - * Remove a connection from the database. Must already exist in DB. - * @param {!Blockly.Connection} connection The connection to be removed. - * @private - */ -Blockly.ConnectionDB.prototype.removeConnection_ = function(connection) { - if (!connection.inDB_) { - throw Error('Connection not in database.'); - } - var removalIndex = this.findConnection(connection); - if (removalIndex == -1) { - throw Error('Unable to find connection in connectionDB.'); - } - connection.inDB_ = false; - this.connections_.splice(removalIndex, 1); -}; - -/** - * Find all nearby connections to the given connection. - * Type checking does not apply, since this function is used for bumping. - * @param {!Blockly.Connection} connection The connection whose neighbours - * should be returned. - * @param {number} maxRadius The maximum radius to another connection. - * @return {!Array.} List of connections. - */ -Blockly.ConnectionDB.prototype.getNeighbours = function(connection, maxRadius) { - var db = this.connections_; - var currentX = connection.x_; - var currentY = connection.y_; - - // Binary search to find the closest y location. - var pointerMin = 0; - var pointerMax = db.length - 2; - var pointerMid = pointerMax; - while (pointerMin < pointerMid) { - if (db[pointerMid].y_ < currentY) { - pointerMin = pointerMid; - } else { - pointerMax = pointerMid; - } - pointerMid = Math.floor((pointerMin + pointerMax) / 2); - } - - var neighbours = []; - /** - * Computes if the current connection is within the allowed radius of another - * connection. - * This function is a closure and has access to outside variables. - * @param {number} yIndex The other connection's index in the database. - * @return {boolean} True if the current connection's vertical distance from - * the other connection is less than the allowed radius. - */ - function checkConnection_(yIndex) { - var dx = currentX - db[yIndex].x_; - var dy = currentY - db[yIndex].y_; - var r = Math.sqrt(dx * dx + dy * dy); - if (r <= maxRadius) { - neighbours.push(db[yIndex]); - } - return dy < maxRadius; - } - - // Walk forward and back on the y axis looking for the closest x,y point. - pointerMin = pointerMid; - pointerMax = pointerMid; - if (db.length) { - while (pointerMin >= 0 && checkConnection_(pointerMin)) { - pointerMin--; - } - do { - pointerMax++; - } while (pointerMax < db.length && checkConnection_(pointerMax)); - } - - return neighbours; -}; - - -/** - * Is the candidate connection close to the reference connection. - * Extremely fast; only looks at Y distance. - * @param {number} index Index in database of candidate connection. - * @param {number} baseY Reference connection's Y value. - * @param {number} maxRadius The maximum radius to another connection. - * @return {boolean} True if connection is in range. - * @private - */ -Blockly.ConnectionDB.prototype.isInYRange_ = function(index, baseY, maxRadius) { - return (Math.abs(this.connections_[index].y_ - baseY) <= maxRadius); -}; - -/** - * Find the closest compatible connection to this connection. - * @param {!Blockly.Connection} conn The connection searching for a compatible - * mate. - * @param {number} maxRadius The maximum radius to another connection. - * @param {!goog.math.Coordinate} dxy Offset between this connection's location - * in the database and the current location (as a result of dragging). - * @return {!{connection: ?Blockly.Connection, radius: number}} Contains two - * properties:' connection' which is either another connection or null, - * and 'radius' which is the distance. - */ -Blockly.ConnectionDB.prototype.searchForClosest = function(conn, maxRadius, - dxy) { - // Don't bother. - if (!this.connections_.length) { - return {connection: null, radius: maxRadius}; - } - - // Stash the values of x and y from before the drag. - var baseY = conn.y_; - var baseX = conn.x_; - - conn.x_ = baseX + dxy.x; - conn.y_ = baseY + dxy.y; - - // findPositionForConnection finds an index for insertion, which is always - // after any block with the same y index. We want to search both forward - // and back, so search on both sides of the index. - var closestIndex = this.findPositionForConnection_(conn); - - var bestConnection = null; - var bestRadius = maxRadius; - var temp; - - // Walk forward and back on the y axis looking for the closest x,y point. - var pointerMin = closestIndex - 1; - while (pointerMin >= 0 && this.isInYRange_(pointerMin, conn.y_, maxRadius)) { - temp = this.connections_[pointerMin]; - if (conn.isConnectionAllowed(temp, bestRadius)) { - bestConnection = temp; - bestRadius = temp.distanceFrom(conn); - } - pointerMin--; - } - - var pointerMax = closestIndex; - while (pointerMax < this.connections_.length && - this.isInYRange_(pointerMax, conn.y_, maxRadius)) { - temp = this.connections_[pointerMax]; - if (conn.isConnectionAllowed(temp, bestRadius)) { - bestConnection = temp; - bestRadius = temp.distanceFrom(conn); - } - pointerMax++; - } - - // Reset the values of x and y. - conn.x_ = baseX; - conn.y_ = baseY; - - // If there were no valid connections, bestConnection will be null. - return {connection: bestConnection, radius: bestRadius}; -}; - -/** - * Initialize a set of connection DBs for a specified workspace. - * @param {!Blockly.Workspace} workspace The workspace this DB is for. - */ -Blockly.ConnectionDB.init = function(workspace) { - // Create four databases, one for each connection type. - var dbList = []; - dbList[Blockly.INPUT_VALUE] = new Blockly.ConnectionDB(); - dbList[Blockly.OUTPUT_VALUE] = new Blockly.ConnectionDB(); - dbList[Blockly.NEXT_STATEMENT] = new Blockly.ConnectionDB(); - dbList[Blockly.PREVIOUS_STATEMENT] = new Blockly.ConnectionDB(); - workspace.connectionDBList = dbList; -}; diff --git a/core/constants.js b/core/constants.js deleted file mode 100644 index 2b6d653586..0000000000 --- a/core/constants.js +++ /dev/null @@ -1,387 +0,0 @@ -/** - * @license - * Visual Blocks Editor - * - * Copyright 2016 Google Inc. - * https://developers.google.com/blockly/ - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @fileoverview Blockly constants. - * @author fenichel@google.com (Rachel Fenichel) - */ -'use strict'; - -goog.provide('Blockly.constants'); - - -/** - * Number of pixels the mouse must move before a drag starts. - */ -Blockly.DRAG_RADIUS = 3; - -/** - * Number of pixels the mouse must move before a drag/scroll starts from the - * flyout. Because the drag-intention is determined when this is reached, it is - * larger than Blockly.DRAG_RADIUS so that the drag-direction is clearer. - */ -Blockly.FLYOUT_DRAG_RADIUS = 10; - -/** - * Maximum misalignment between connections for them to snap together. - */ -Blockly.SNAP_RADIUS = 48; - -/** - * Maximum misalignment between connections for them to snap together, - * when a connection is already highlighted. - */ -Blockly.CONNECTING_SNAP_RADIUS = 68; - -/** - * How much to prefer staying connected to the current connection over moving to - * a new connection. The current previewed connection is considered to be this - * much closer to the matching connection on the block than it actually is. - */ -Blockly.CURRENT_CONNECTION_PREFERENCE = 20; - -/** - * Delay in ms between trigger and bumping unconnected block out of alignment. - */ -Blockly.BUMP_DELAY = 0; - -/** - * Number of characters to truncate a collapsed block to. - */ -Blockly.COLLAPSE_CHARS = 30; - -/** - * Length in ms for a touch to become a long press. - */ -Blockly.LONGPRESS = 750; - -/** - * Distance to scroll when a mouse wheel event is received and its delta mode - * is line (0x1) instead of pixel (0x0). In these cases, a single "scroll" has - * a delta of 1, which makes the workspace scroll very slowly (just one pixel). - * To compensate, that delta is multiplied by this value. - * @const - * @package - */ -Blockly.LINE_SCROLL_MULTIPLIER = 15; - -/** - * Prevent a sound from playing if another sound preceded it within this many - * milliseconds. - */ -Blockly.SOUND_LIMIT = 100; - -/** - * When dragging a block out of a stack, split the stack in two (true), or drag - * out the block healing the stack (false). - */ -Blockly.DRAG_STACK = true; - -/** - * The richness of block colours, regardless of the hue. - * Must be in the range of 0 (inclusive) to 1 (exclusive). - */ -Blockly.HSV_SATURATION = 0.45; - -/** - * The intensity of block colours, regardless of the hue. - * Must be in the range of 0 (inclusive) to 1 (exclusive). - */ -Blockly.HSV_VALUE = 0.65; - -/** - * Sprited icons and images. - */ -Blockly.SPRITE = { - width: 96, - height: 124, - url: 'sprites.png' -}; - -// Constants below this point are not intended to be changed. - -/** - * Required name space for SVG elements. - * @const - */ -Blockly.SVG_NS = 'http://www.w3.org/2000/svg'; - -/** - * Required name space for HTML elements. - * @const - */ -Blockly.HTML_NS = 'http://www.w3.org/1999/xhtml'; - -/** - * ENUM for a right-facing value input. E.g. 'set item to' or 'return'. - * @const - */ -Blockly.INPUT_VALUE = 1; - -/** - * ENUM for a left-facing value output. E.g. 'random fraction'. - * @const - */ -Blockly.OUTPUT_VALUE = 2; - -/** - * ENUM for a down-facing block stack. E.g. 'if-do' or 'else'. - * @const - */ -Blockly.NEXT_STATEMENT = 3; - -/** - * ENUM for an up-facing block stack. E.g. 'break out of loop'. - * @const - */ -Blockly.PREVIOUS_STATEMENT = 4; - -/** - * ENUM for an dummy input. Used to add field(s) with no input. - * @const - */ -Blockly.DUMMY_INPUT = 5; - -/** - * ENUM for left alignment. - * @const - */ -Blockly.ALIGN_LEFT = -1; - -/** - * ENUM for centre alignment. - * @const - */ -Blockly.ALIGN_CENTRE = 0; - -/** - * ENUM for right alignment. - * @const - */ -Blockly.ALIGN_RIGHT = 1; - -/** - * ENUM for no drag operation. - * @const - */ -Blockly.DRAG_NONE = 0; - -/** - * ENUM for inside the sticky DRAG_RADIUS. - * @const - */ -Blockly.DRAG_STICKY = 1; - -/** - * ENUM for inside the non-sticky DRAG_RADIUS, for differentiating between - * clicks and drags. - * @const - */ -Blockly.DRAG_BEGIN = 1; - -/** - * ENUM for freely draggable (outside the DRAG_RADIUS, if one applies). - * @const - */ -Blockly.DRAG_FREE = 2; - -/** - * Lookup table for determining the opposite type of a connection. - * @const - */ -Blockly.OPPOSITE_TYPE = []; -Blockly.OPPOSITE_TYPE[Blockly.INPUT_VALUE] = Blockly.OUTPUT_VALUE; -Blockly.OPPOSITE_TYPE[Blockly.OUTPUT_VALUE] = Blockly.INPUT_VALUE; -Blockly.OPPOSITE_TYPE[Blockly.NEXT_STATEMENT] = Blockly.PREVIOUS_STATEMENT; -Blockly.OPPOSITE_TYPE[Blockly.PREVIOUS_STATEMENT] = Blockly.NEXT_STATEMENT; - -/** - * ENUM for toolbox and flyout at top of screen. - * @const - */ -Blockly.TOOLBOX_AT_TOP = 0; - -/** - * ENUM for toolbox and flyout at bottom of screen. - * @const - */ -Blockly.TOOLBOX_AT_BOTTOM = 1; - -/** - * ENUM for toolbox and flyout at left of screen. - * @const - */ -Blockly.TOOLBOX_AT_LEFT = 2; - -/** - * ENUM for toolbox and flyout at right of screen. - * @const - */ -Blockly.TOOLBOX_AT_RIGHT = 3; - -/** - * ENUM for output shape: hexagonal (booleans/predicates). - * @const - */ -Blockly.OUTPUT_SHAPE_HEXAGONAL = 1; - -/** - * ENUM for output shape: rounded (numbers). - * @const - */ -Blockly.OUTPUT_SHAPE_ROUND = 2; - -/** - * ENUM for output shape: squared (any/all values; strings). - * @const - */ -Blockly.OUTPUT_SHAPE_SQUARE = 3; - -/** - * ENUM for categories. - * @const - */ -Blockly.Categories = { - "motion": "motion", - "looks": "looks", - "sound": "sounds", - "pen": "pen", - "data": "data", - "dataLists": "data-lists", - "event": "events", - "control": "control", - "sensing": "sensing", - "operators": "operators", - "more": "more" -}; - -/** - * ENUM representing that an event is not in any delete areas. - * Null for backwards compatibility reasons. - * @const - */ -Blockly.DELETE_AREA_NONE = null; - -/** - * ENUM representing that an event is in the delete area of the trash can. - * @const - */ -Blockly.DELETE_AREA_TRASH = 1; - -/** - * ENUM representing that an event is in the delete area of the toolbox or - * flyout. - * @const - */ -Blockly.DELETE_AREA_TOOLBOX = 2; - -/** - * String for use in the "custom" attribute of a category in toolbox xml. - * This string indicates that the category should be dynamically populated with - * variable blocks. - * @const {string} - */ -Blockly.VARIABLE_CATEGORY_NAME = 'VARIABLE'; - -/** - * String for use in the "custom" attribute of a category in toolbox xml. - * This string indicates that the category should be dynamically populated with - * procedure blocks. - * @const {string} - */ -Blockly.PROCEDURE_CATEGORY_NAME = 'PROCEDURE'; - -/** - * String for use in the dropdown created in field_variable. - * This string indicates that this option in the dropdown is 'Rename - * variable...' and if selected, should trigger the prompt to rename a variable. - * @const {string} - */ -Blockly.RENAME_VARIABLE_ID = 'RENAME_VARIABLE_ID'; - -/** - * String for use in the dropdown created in field_variable. - * This string indicates that this option in the dropdown is 'Delete the "%1" - * variable' and if selected, should trigger the prompt to delete a variable. - * @const {string} - */ -Blockly.DELETE_VARIABLE_ID = 'DELETE_VARIABLE_ID'; - -/** - * String for use in the dropdown created in field_variable, - * specifically for broadcast messages. - * This string indicates that this option in the dropdown is 'New message...' - * and if selected, should trigger the prompt to create a new message. - * @const {string} - */ -Blockly.NEW_BROADCAST_MESSAGE_ID = 'NEW_BROADCAST_MESSAGE_ID'; - -/** - * String representing the variable type of broadcast message blocks. - * This string, for use in differentiating between types of variables, - * indicates that the current variable is a broadcast message. - * @const {string} - */ -Blockly.BROADCAST_MESSAGE_VARIABLE_TYPE = 'broadcast_msg'; - -/** - * String representing the variable type of list blocks. - * This string, for use in differentiating between types of variables, - * indicates that the current variable is a list. - * @const {string} - */ -Blockly.LIST_VARIABLE_TYPE = 'list'; - -// TODO (#1251) Replace '' below with 'scalar', and start using this constant -// everywhere. -/** - * String representing the variable type of scalar variables. - * This string, for use in differentiating between types of variables, - * indicates that the current variable is a scalar variable. - * @const {string} - */ -Blockly.SCALAR_VARIABLE_TYPE = ''; - -/** - * The type of all procedure definition blocks. - * @const {string} - */ -Blockly.PROCEDURES_DEFINITION_BLOCK_TYPE = 'procedures_definition'; - -/** - * The type of all procedure prototype blocks. - * @const {string} - */ -Blockly.PROCEDURES_PROTOTYPE_BLOCK_TYPE = 'procedures_prototype'; - -/** - * The type of all procedure call blocks. - * @const {string} - */ -Blockly.PROCEDURES_CALL_BLOCK_TYPE = 'procedures_call'; - -/** - * ENUM for flyout status button states. - * @const - */ -Blockly.StatusButtonState = { - "READY": "ready", - "NOT_READY": "not ready", -}; diff --git a/core/contextmenu.js b/core/contextmenu.js deleted file mode 100644 index 65401747e6..0000000000 --- a/core/contextmenu.js +++ /dev/null @@ -1,519 +0,0 @@ -/** - * @license - * Visual Blocks Editor - * - * Copyright 2011 Google Inc. - * https://developers.google.com/blockly/ - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @fileoverview Functionality for the right-click context menus. - * @author fraser@google.com (Neil Fraser) - */ -'use strict'; - -/** - * @name Blockly.ContextMenu - * @namespace - */ -goog.provide('Blockly.ContextMenu'); - -goog.require('Blockly.Events.BlockCreate'); -goog.require('Blockly.scratchBlocksUtils'); -goog.require('Blockly.utils'); -goog.require('Blockly.utils.uiMenu'); - -goog.require('goog.dom'); -goog.require('goog.events'); -goog.require('goog.style'); -goog.require('goog.ui.Menu'); -goog.require('goog.ui.MenuItem'); -goog.require('goog.userAgent'); - - -/** - * Which block is the context menu attached to? - * @type {Blockly.Block} - */ -Blockly.ContextMenu.currentBlock = null; - -/** - * Opaque data that can be passed to unbindEvent_. - * @type {Array.} - * @private - */ -Blockly.ContextMenu.eventWrapper_ = null; - -/** - * Construct the menu based on the list of options and show the menu. - * @param {!Event} e Mouse event. - * @param {!Array.} options Array of menu options. - * @param {boolean} rtl True if RTL, false if LTR. - */ -Blockly.ContextMenu.show = function(e, options, rtl) { - Blockly.WidgetDiv.show(Blockly.ContextMenu, rtl, null); - if (!options.length) { - Blockly.ContextMenu.hide(); - return; - } - var menu = Blockly.ContextMenu.populate_(options, rtl); - - goog.events.listen( - menu, goog.ui.Component.EventType.ACTION, Blockly.ContextMenu.hide); - - Blockly.ContextMenu.position_(menu, e, rtl); - // 1ms delay is required for focusing on context menus because some other - // mouse event is still waiting in the queue and clears focus. - setTimeout(function() {menu.getElement().focus();}, 1); - Blockly.ContextMenu.currentBlock = null; // May be set by Blockly.Block. -}; - -/** - * Create the context menu object and populate it with the given options. - * @param {!Array.} options Array of menu options. - * @param {boolean} rtl True if RTL, false if LTR. - * @return {!goog.ui.Menu} The menu that will be shown on right click. - * @private - */ -Blockly.ContextMenu.populate_ = function(options, rtl) { - /* Here's what one option object looks like: - {text: 'Make It So', - enabled: true, - callback: Blockly.MakeItSo} - */ - var menu = new goog.ui.Menu(); - menu.setRightToLeft(rtl); - for (var i = 0, option; option = options[i]; i++) { - var menuItem = new goog.ui.MenuItem(option.text); - menuItem.setRightToLeft(rtl); - menu.addChild(menuItem, true); - menuItem.setEnabled(option.enabled); - if (option.enabled) { - goog.events.listen( - menuItem, goog.ui.Component.EventType.ACTION, option.callback); - menuItem.handleContextMenu = function(/* e */) { - // Right-clicking on menu option should count as a click. - goog.events.dispatchEvent(this, goog.ui.Component.EventType.ACTION); - }; - } - } - return menu; -}; - -/** - * Add the menu to the page and position it correctly. - * @param {!goog.ui.Menu} menu The menu to add and position. - * @param {!Event} e Mouse event for the right click that is making the context - * menu appear. - * @param {boolean} rtl True if RTL, false if LTR. - * @private - */ -Blockly.ContextMenu.position_ = function(menu, e, rtl) { - // Record windowSize and scrollOffset before adding menu. - var viewportBBox = Blockly.utils.getViewportBBox(); - // This one is just a point, but we'll pretend that it's a rect so we can use - // some helper functions. - var anchorBBox = { - top: e.clientY + viewportBBox.top, - bottom: e.clientY + viewportBBox.top, - left: e.clientX + viewportBBox.left, - right: e.clientX + viewportBBox.left - }; - - Blockly.ContextMenu.createWidget_(menu); - var menuSize = Blockly.utils.uiMenu.getSize(menu); - - if (rtl) { - Blockly.utils.uiMenu.adjustBBoxesForRTL(viewportBBox, anchorBBox, menuSize); - } - - Blockly.WidgetDiv.positionWithAnchor(viewportBBox, anchorBBox, menuSize, rtl); - // Calling menuDom.focus() has to wait until after the menu has been placed - // correctly. Otherwise it will cause a page scroll to get the misplaced menu - // in view. See issue #1329. - menu.getElement().focus(); -}; - -/** - * Create and render the menu widget inside Blockly's widget div. - * @param {!goog.ui.Menu} menu The menu to add to the widget div. - * @private - */ -Blockly.ContextMenu.createWidget_ = function(menu) { - var div = Blockly.WidgetDiv.DIV; - menu.render(div); - var menuDom = menu.getElement(); - Blockly.utils.addClass(menuDom, 'blocklyContextMenu'); - // Prevent system context menu when right-clicking a Blockly context menu. - Blockly.bindEventWithChecks_( - menuDom, 'contextmenu', null, Blockly.utils.noEvent); - // Enable autofocus after the initial render to avoid issue #1329. - menu.setAllowAutoFocus(true); -}; - -/** - * Hide the context menu. - */ -Blockly.ContextMenu.hide = function() { - Blockly.WidgetDiv.hideIfOwner(Blockly.ContextMenu); - Blockly.ContextMenu.currentBlock = null; - if (Blockly.ContextMenu.eventWrapper_) { - Blockly.unbindEvent_(Blockly.ContextMenu.eventWrapper_); - } -}; - -/** - * Create a callback function that creates and configures a block, - * then places the new block next to the original. - * @param {!Blockly.Block} block Original block. - * @param {!Element} xml XML representation of new block. - * @return {!Function} Function that creates a block. - */ -Blockly.ContextMenu.callbackFactory = function(block, xml) { - return function() { - Blockly.Events.disable(); - try { - var newBlock = Blockly.Xml.domToBlock(xml, block.workspace); - // Move the new block next to the old block. - var xy = block.getRelativeToSurfaceXY(); - if (block.RTL) { - xy.x -= Blockly.SNAP_RADIUS; - } else { - xy.x += Blockly.SNAP_RADIUS; - } - xy.y += Blockly.SNAP_RADIUS * 2; - newBlock.moveBy(xy.x, xy.y); - } finally { - Blockly.Events.enable(); - } - if (Blockly.Events.isEnabled() && !newBlock.isShadow()) { - Blockly.Events.fire(new Blockly.Events.BlockCreate(newBlock)); - } - newBlock.select(); - }; -}; - -// Helper functions for creating context menu options. - -/** - * Make a context menu option for deleting the current block. - * @param {!Blockly.BlockSvg} block The block where the right-click originated. - * @return {!Object} A menu option, containing text, enabled, and a callback. - * @package - */ -Blockly.ContextMenu.blockDeleteOption = function(block) { - // Option to delete this block but not blocks lower in the stack. - // Count the number of blocks that are nested in this block, - // ignoring shadows and without ordering. - var descendantCount = block.getDescendants(false, true).length; - var nextBlock = block.getNextBlock(); - if (nextBlock) { - // Blocks in the current stack would survive this block's deletion. - descendantCount -= nextBlock.getDescendants(false, true).length; - } - var deleteOption = { - text: descendantCount == 1 ? Blockly.Msg.DELETE_BLOCK : - Blockly.Msg.DELETE_X_BLOCKS.replace('%1', String(descendantCount)), - enabled: true, - callback: function() { - Blockly.Events.setGroup(true); - block.dispose(true, true); - Blockly.Events.setGroup(false); - } - }; - return deleteOption; -}; - -/** - * Make a context menu option for showing help for the current block. - * @param {!Blockly.BlockSvg} block The block where the right-click originated. - * @return {!Object} A menu option, containing text, enabled, and a callback. - * @package - */ -Blockly.ContextMenu.blockHelpOption = function(block) { - var url = goog.isFunction(block.helpUrl) ? block.helpUrl() : block.helpUrl; - var helpOption = { - enabled: !!url, - text: Blockly.Msg.HELP, - callback: function() { - block.showHelp_(); - } - }; - return helpOption; -}; - -/** - * Make a context menu option for duplicating the current block. - * @param {!Blockly.BlockSvg} block The block where the right-click originated. - * @param {!Event} event Event that caused the context menu to open. - * @return {!Object} A menu option, containing text, enabled, and a callback. - * @package - */ -Blockly.ContextMenu.blockDuplicateOption = function(block, event) { - var duplicateOption = { - text: Blockly.Msg.DUPLICATE, - enabled: true, - callback: - Blockly.scratchBlocksUtils.duplicateAndDragCallback(block, event) - }; - return duplicateOption; -}; - -/** - * Make a context menu option for adding or removing comments on the current - * block. - * @param {!Blockly.BlockSvg} block The block where the right-click originated. - * @return {!Object} A menu option, containing text, enabled, and a callback. - * @package - */ -Blockly.ContextMenu.blockCommentOption = function(block) { - var commentOption = { - enabled: !goog.userAgent.IE - }; - // If there's already a comment, add an option to delete it. - if (block.comment) { - commentOption.text = Blockly.Msg.REMOVE_COMMENT; - commentOption.callback = function() { - block.setCommentText(null); - }; - } else { - // If there's no comment, add an option to create a comment. - commentOption.text = Blockly.Msg.ADD_COMMENT; - commentOption.callback = function() { - block.setCommentText(''); - block.comment.focus(); - }; - } - return commentOption; -}; - -/** - * Make a context menu option for undoing the most recent action on the - * workspace. - * @param {!Blockly.WorkspaceSvg} ws The workspace where the right-click - * originated. - * @return {!Object} A menu option, containing text, enabled, and a callback. - * @package - */ -Blockly.ContextMenu.wsUndoOption = function(ws) { - return { - text: Blockly.Msg.UNDO, - enabled: ws.hasUndoStack(), - callback: ws.undo.bind(ws, false) - }; -}; - -/** - * Make a context menu option for redoing the most recent action on the - * workspace. - * @param {!Blockly.WorkspaceSvg} ws The workspace where the right-click - * originated. - * @return {!Object} A menu option, containing text, enabled, and a callback. - * @package - */ -Blockly.ContextMenu.wsRedoOption = function(ws) { - return { - text: Blockly.Msg.REDO, - enabled: ws.hasRedoStack(), - callback: ws.undo.bind(ws, true) - }; -}; - -/** - * Make a context menu option for cleaning up blocks on the workspace, by - * aligning them vertically. - * @param {!Blockly.WorkspaceSvg} ws The workspace where the right-click - * originated. - * @param {number} numTopBlocks The number of top blocks on the workspace. - * @return {!Object} A menu option, containing text, enabled, and a callback. - * @package - */ -Blockly.ContextMenu.wsCleanupOption = function(ws, numTopBlocks) { - return { - text: Blockly.Msg.CLEAN_UP, - enabled: numTopBlocks > 1, - callback: ws.cleanUp.bind(ws, true) - }; -}; - -/** - * Helper function for toggling delete state on blocks on the workspace, to be - * called from a right-click menu. - * @param {!Array.} topBlocks The list of top blocks on the - * the workspace. - * @param {boolean} shouldCollapse True if the blocks should be collapsed, false - * if they should be expanded. - * @private - */ -Blockly.ContextMenu.toggleCollapseFn_ = function(topBlocks, shouldCollapse) { - // Add a little animation to collapsing and expanding. - var DELAY = 10; - var ms = 0; - for (var i = 0; i < topBlocks.length; i++) { - var block = topBlocks[i]; - while (block) { - setTimeout(block.setCollapsed.bind(block, shouldCollapse), ms); - block = block.getNextBlock(); - ms += DELAY; - } - } -}; - -/** - * Make a context menu option for collapsing all block stacks on the workspace. - * @param {boolean} hasExpandedBlocks Whether there are any non-collapsed blocks - * on the workspace. - * @param {!Array.} topBlocks The list of top blocks on the - * the workspace. - * @return {!Object} A menu option, containing text, enabled, and a callback. - * @package - */ -Blockly.ContextMenu.wsCollapseOption = function(hasExpandedBlocks, topBlocks) { - return { - enabled: hasExpandedBlocks, - text: Blockly.Msg.COLLAPSE_ALL, - callback: function() { - Blockly.ContextMenu.toggleCollapseFn_(topBlocks, true); - } - }; -}; - -/** - * Make a context menu option for expanding all block stacks on the workspace. - * @param {boolean} hasCollapsedBlocks Whether there are any collapsed blocks - * on the workspace. - * @param {!Array.} topBlocks The list of top blocks on the - * the workspace. - * @return {!Object} A menu option, containing text, enabled, and a callback. - * @package - */ -Blockly.ContextMenu.wsExpandOption = function(hasCollapsedBlocks, topBlocks) { - return { - enabled: hasCollapsedBlocks, - text: Blockly.Msg.EXPAND_ALL, - callback: function() { - Blockly.ContextMenu.toggleCollapseFn_(topBlocks, false); - } - }; -}; - -/** - * Make a context menu option for deleting the current workspace comment. - * @param {!Blockly.WorkspaceCommentSvg} comment The workspace comment where the - * right-click originated. - * @return {!Object} A menu option, containing text, enabled, and a callback. - * @package - */ -Blockly.ContextMenu.commentDeleteOption = function(comment) { - var deleteOption = { - text: Blockly.Msg.DELETE, - enabled: true, - callback: function() { - Blockly.Events.setGroup(true); - comment.dispose(true, true); - Blockly.Events.setGroup(false); - } - }; - return deleteOption; -}; - -/** - * Make a context menu option for duplicating the current workspace comment. - * @param {!Blockly.WorkspaceCommentSvg} comment The workspace comment where the - * right-click originated. - * @return {!Object} A menu option, containing text, enabled, and a callback. - * @package - */ -Blockly.ContextMenu.commentDuplicateOption = function(comment) { - var duplicateOption = { - text: Blockly.Msg.DUPLICATE, - enabled: true, - callback: function() { - Blockly.duplicate_(comment); - } - }; - return duplicateOption; -}; - -/** - * Make a context menu option for adding a comment on the workspace. - * @param {!Blockly.WorkspaceSvg} ws The workspace where the right-click - * originated. - * @param {!Event} e The right-click mouse event. - * @return {!Object} A menu option, containing text, enabled, and a callback. - * @package - */ -Blockly.ContextMenu.workspaceCommentOption = function(ws, e) { - // Helper function to create and position a comment correctly based on the - // location of the mouse event. - var addWsComment = function() { - // Disable events while this comment is getting created - // so that we can fire a single create event for this comment - // at the end (instead of CommentCreate followed by CommentMove, - // which results in unexpected undo behavior). - var disabled = false; - if (Blockly.Events.isEnabled()) { - Blockly.Events.disable(); - disabled = true; - } - var comment = new Blockly.WorkspaceCommentSvg( - ws, '', Blockly.WorkspaceCommentSvg.DEFAULT_SIZE, - Blockly.WorkspaceCommentSvg.DEFAULT_SIZE, false); - - var injectionDiv = ws.getInjectionDiv(); - // Bounding rect coordinates are in client coordinates, meaning that they - // are in pixels relative to the upper left corner of the visible browser - // window. These coordinates change when you scroll the browser window. - var boundingRect = injectionDiv.getBoundingClientRect(); - - // The client coordinates offset by the injection div's upper left corner. - var clientOffsetPixels = new goog.math.Coordinate( - e.clientX - boundingRect.left, e.clientY - boundingRect.top); - - // The offset in pixels between the main workspace's origin and the upper - // left corner of the injection div. - var mainOffsetPixels = ws.getOriginOffsetInPixels(); - - // The position of the new comment in pixels relative to the origin of the - // main workspace. - var finalOffsetPixels = goog.math.Coordinate.difference(clientOffsetPixels, - mainOffsetPixels); - - // The position of the new comment in main workspace coordinates. - var finalOffsetMainWs = finalOffsetPixels.scale(1 / ws.scale); - - var commentX = finalOffsetMainWs.x; - var commentY = finalOffsetMainWs.y; - comment.moveBy(commentX, commentY); - if (ws.rendered) { - comment.initSvg(); - comment.render(false); - comment.select(); - } - if (disabled) { - Blockly.Events.enable(); - } - Blockly.WorkspaceComment.fireCreateEvent(comment); - }; - - var wsCommentOption = {enabled: true}; - wsCommentOption.text = Blockly.Msg.ADD_COMMENT; - wsCommentOption.callback = function() { - addWsComment(); - }; - return wsCommentOption; -}; - -// End helper functions for creating context menu options. diff --git a/core/dragged_connection_manager.js b/core/dragged_connection_manager.js deleted file mode 100644 index 9727c0844f..0000000000 --- a/core/dragged_connection_manager.js +++ /dev/null @@ -1,260 +0,0 @@ -/** - * @license - * Visual Blocks Editor - * - * Copyright 2017 Google Inc. - * https://developers.google.com/blockly/ - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @fileoverview Class that controls updates to connections during drags. - * @author fenichel@google.com (Rachel Fenichel) - */ -'use strict'; - -goog.provide('Blockly.DraggedConnectionManager'); - -goog.require('Blockly.BlockAnimations'); -goog.require('Blockly.RenderedConnection'); - -goog.require('goog.math.Coordinate'); - - -/** - * Class that controls updates to connections during drags. It is primarily - * responsible for finding the closest eligible connection and highlighting or - * unhiglighting it as needed during a drag. - * @param {!Blockly.BlockSvg} block The top block in the stack being dragged. - * @constructor - */ -Blockly.DraggedConnectionManager = function(block) { - Blockly.selected = block; - - /** - * The top block in the stack being dragged. - * Does not change during a drag. - * @type {!Blockly.Block} - * @private - */ - this.topBlock_ = block; - - /** - * The workspace on which these connections are being dragged. - * Does not change during a drag. - * @type {!Blockly.WorkspaceSvg} - * @private - */ - this.workspace_ = block.workspace; - - /** - * The connections on the dragging blocks that are available to connect to - * other blocks. This includes all open connections on the top block, as well - * as the last connection on the block stack. - * Does not change during a drag. - * @type {!Array.} - * @private - */ - this.availableConnections_ = this.initAvailableConnections_(); - - /** - * The connection that this block would connect to if released immediately. - * Updated on every mouse move. - * @type {Blockly.RenderedConnection} - * @private - */ - this.closestConnection_ = null; - - /** - * The connection that would connect to this.closestConnection_ if this block - * were released immediately. - * Updated on every mouse move. - * @type {Blockly.RenderedConnection} - * @private - */ - this.localConnection_ = null; - - /** - * The distance between this.closestConnection_ and this.localConnection_, - * in workspace units. - * Updated on every mouse move. - * @type {number} - * @private - */ - this.radiusConnection_ = 0; - - /** - * Whether the block would be deleted if it were dropped immediately. - * Updated on every mouse move. - * @type {boolean} - * @private - */ - this.wouldDeleteBlock_ = false; -}; - -/** - * Sever all links from this object. - * @package - */ -Blockly.DraggedConnectionManager.prototype.dispose = function() { - this.topBlock_ = null; - this.workspace_ = null; - this.availableConnections_.length = 0; - this.closestConnection_ = null; - this.localConnection_ = null; -}; - -/** - * Return whether the block would be deleted if dropped immediately, based on - * information from the most recent move event. - * @return {boolean} true if the block would be deleted if dropped immediately. - * @package - */ -Blockly.DraggedConnectionManager.prototype.wouldDeleteBlock = function() { - return this.wouldDeleteBlock_; -}; - -/** - * Return whether the block would be connected if dropped immediately, based on - * information from the most recent move event. - * @return {boolean} true if the block would be connected if dropped immediately. - * @package - */ -Blockly.DraggedConnectionManager.prototype.wouldConnectBlock = function() { - return !!this.closestConnection_; -}; - -/** - * Connect to the closest connection and render the results. - * This should be called at the end of a drag. - * @package - */ -Blockly.DraggedConnectionManager.prototype.applyConnections = function() { - if (this.closestConnection_) { - // Connect two blocks together. - this.localConnection_.connect(this.closestConnection_); - if (this.topBlock_.rendered) { - // Trigger a connection animation. - // Determine which connection is inferior (lower in the source stack). - var inferiorConnection = this.localConnection_.isSuperior() ? - this.closestConnection_ : this.localConnection_; - Blockly.BlockAnimations.connectionUiEffect( - inferiorConnection.getSourceBlock()); - // Bring the just-edited stack to the front. - var rootBlock = this.topBlock_.getRootBlock(); - rootBlock.bringToFront(); - } - this.removeHighlighting_(); - } -}; - -/** - * Update highlighted connections based on the most recent move location. - * @param {!goog.math.Coordinate} dxy Position relative to drag start, - * in workspace units. - * @param {?number} deleteArea One of {@link Blockly.DELETE_AREA_TRASH}, - * {@link Blockly.DELETE_AREA_TOOLBOX}, or {@link Blockly.DELETE_AREA_NONE}. - * @param {?boolean} isOutside True if the drag is going outside the blocks workspace - * @package - */ -Blockly.DraggedConnectionManager.prototype.update = function(dxy, deleteArea, isOutside) { - var oldClosestConnection; - var closestConnectionChanged; - // If dragged outside, don't connect, since the connections aren't visible. - if (!isOutside) { - oldClosestConnection = this.closestConnection_; - closestConnectionChanged = this.updateClosest_(dxy); - if (closestConnectionChanged && oldClosestConnection) { - oldClosestConnection.unhighlight(); - } - } else if (this.closestConnection_) { - this.closestConnection_.unhighlight(); - this.closestConnection_ = null; - } - - // Prefer connecting over dropping into the trash can, but prefer dragging to - // the toolbox over connecting to other blocks. - var wouldConnect = !!this.closestConnection_ && - deleteArea != Blockly.DELETE_AREA_TOOLBOX; - var wouldDelete = !!deleteArea && !this.topBlock_.getParent() && - this.topBlock_.isDeletable(); - this.wouldDeleteBlock_ = wouldDelete && !wouldConnect; - - if (!this.wouldDeleteBlock_ && closestConnectionChanged && - this.closestConnection_) { - this.addHighlighting_(); - } -}; - -/** - * Remove highlighting from the currently highlighted connection, if it exists. - * @private - */ -Blockly.DraggedConnectionManager.prototype.removeHighlighting_ = function() { - if (this.closestConnection_) { - this.closestConnection_.unhighlight(); - } -}; - -/** - * Add highlighting to the closest connection, if it exists. - * @private - */ -Blockly.DraggedConnectionManager.prototype.addHighlighting_ = function() { - if (this.closestConnection_) { - this.closestConnection_.highlight(); - } -}; - -/** - * Populate the list of available connections on this block stack. This should - * only be called once, at the beginning of a drag. - * @return {!Array.} a list of available - * connections. - * @private - */ -Blockly.DraggedConnectionManager.prototype.initAvailableConnections_ = function() { - var available = this.topBlock_.getConnections_(false); - // Also check the last connection on this stack - var lastOnStack = this.topBlock_.lastConnectionInStack(); - if (lastOnStack && lastOnStack != this.topBlock_.nextConnection) { - available.push(lastOnStack); - } - return available; -}; - -/** - * Find the new closest connection, and update internal state in response. - * @param {!goog.math.Coordinate} dxy Position relative to the drag start, - * in workspace units. - * @return {boolean} Whether the closest connection has changed. - * @private - */ -Blockly.DraggedConnectionManager.prototype.updateClosest_ = function(dxy) { - var oldClosestConnection = this.closestConnection_; - - this.closestConnection_ = null; - this.localConnection_ = null; - this.radiusConnection_ = Blockly.SNAP_RADIUS; - for (var i = 0; i < this.availableConnections_.length; i++) { - var myConnection = this.availableConnections_[i]; - var neighbour = myConnection.closest(this.radiusConnection_, dxy); - if (neighbour.connection) { - this.closestConnection_ = neighbour.connection; - this.localConnection_ = myConnection; - this.radiusConnection_ = neighbour.radius; - } - } - return oldClosestConnection != this.closestConnection_; -}; diff --git a/core/dropdowndiv.js b/core/dropdowndiv.js deleted file mode 100644 index ea64b77ce6..0000000000 --- a/core/dropdowndiv.js +++ /dev/null @@ -1,408 +0,0 @@ -/** - * @license - * Visual Blocks Editor - * - * Copyright 2016 Massachusetts Institute of Technology - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @fileoverview A div that floats on top of the workspace, for drop-down menus. - * The drop-down can be kept inside the workspace, animate in/out, etc. - * @author tmickel@mit.edu (Tim Mickel) - */ - -'use strict'; - -goog.provide('Blockly.DropDownDiv'); - -goog.require('goog.dom'); -goog.require('goog.style'); - -/** - * Class for drop-down div. - * @constructor - */ -Blockly.DropDownDiv = function() { -}; - -/** - * The div element. Set once by Blockly.DropDownDiv.createDom. - * @type {Element} - * @private - */ -Blockly.DropDownDiv.DIV_ = null; - -/** - * Drop-downs will appear within the bounds of this element if possible. - * Set in Blockly.DropDownDiv.setBoundsElement. - * @type {Element} - * @private - */ -Blockly.DropDownDiv.boundsElement_ = null; - -/** - * The object currently using the drop-down. - * @type {Object} - * @private - */ -Blockly.DropDownDiv.owner_ = null; - -/** - * Arrow size in px. Should match the value in CSS (need to position pre-render). - * @type {number} - * @const - */ -Blockly.DropDownDiv.ARROW_SIZE = 16; - -/** - * Drop-down border size in px. Should match the value in CSS (need to position the arrow). - * @type {number} - * @const - */ -Blockly.DropDownDiv.BORDER_SIZE = 1; - -/** - * Amount the arrow must be kept away from the edges of the main drop-down div, in px. - * @type {number} - * @const - */ -Blockly.DropDownDiv.ARROW_HORIZONTAL_PADDING = 12; - -/** - * Amount drop-downs should be padded away from the source, in px. - * @type {number} - * @const - */ -Blockly.DropDownDiv.PADDING_Y = 20; - -/** - * Length of animations in seconds. - * @type {number} - * @const - */ -Blockly.DropDownDiv.ANIMATION_TIME = 0.25; - -/** - * Timer for animation out, to be cleared if we need to immediately hide - * without disrupting new shows. - * @type {number} - */ -Blockly.DropDownDiv.animateOutTimer_ = null; - -/** - * Callback for when the drop-down is hidden. - * @type {Function} - */ -Blockly.DropDownDiv.onHide_ = 0; - -/** - * Create and insert the DOM element for this div. - * @param {Element} container Element that the div should be contained in. - */ -Blockly.DropDownDiv.createDom = function() { - if (Blockly.DropDownDiv.DIV_) { - return; // Already created. - } - Blockly.DropDownDiv.DIV_ = goog.dom.createDom('div', 'blocklyDropDownDiv'); - document.body.appendChild(Blockly.DropDownDiv.DIV_); - Blockly.DropDownDiv.content_ = goog.dom.createDom('div', 'blocklyDropDownContent'); - Blockly.DropDownDiv.DIV_.appendChild(Blockly.DropDownDiv.content_); - Blockly.DropDownDiv.arrow_ = goog.dom.createDom('div', 'blocklyDropDownArrow'); - Blockly.DropDownDiv.DIV_.appendChild(Blockly.DropDownDiv.arrow_); - - // Transition animation for transform: translate() and opacity. - Blockly.DropDownDiv.DIV_.style.transition = 'transform ' + - Blockly.DropDownDiv.ANIMATION_TIME + 's, ' + - 'opacity ' + Blockly.DropDownDiv.ANIMATION_TIME + 's'; -}; - -/** - * Set an element to maintain bounds within. Drop-downs will appear - * within the box of this element if possible. - * @param {Element} boundsElement Element to bound drop-down to. - */ -Blockly.DropDownDiv.setBoundsElement = function(boundsElement) { - Blockly.DropDownDiv.boundsElement_ = boundsElement; -}; - -/** - * Provide the div for inserting content into the drop-down. - * @return {Element} Div to populate with content - */ -Blockly.DropDownDiv.getContentDiv = function() { - return Blockly.DropDownDiv.content_; -}; - -/** - * Clear the content of the drop-down. - */ -Blockly.DropDownDiv.clearContent = function() { - Blockly.DropDownDiv.content_.innerHTML = ''; - Blockly.DropDownDiv.content_.style.width = ''; -}; - -/** - * Set the colour for the drop-down. - * @param {string} backgroundColour Any CSS color for the background - * @param {string} borderColour Any CSS color for the border - */ -Blockly.DropDownDiv.setColour = function(backgroundColour, borderColour) { - Blockly.DropDownDiv.DIV_.style.backgroundColor = backgroundColour; - Blockly.DropDownDiv.DIV_.style.borderColor = borderColour; -}; - -/** - * Set the category for the drop-down. - * @param {string} category The new category for the drop-down. - */ -Blockly.DropDownDiv.setCategory = function(category) { - Blockly.DropDownDiv.DIV_.setAttribute('data-category', category); -}; - -/** - * Shortcut to show and place the drop-down with positioning determined - * by a particular block. The primary position will be below the block, - * and the secondary position above the block. Drop-down will be - * constrained to the block's workspace. - * @param {Object} owner The object showing the drop-down - * @param {!Blockly.Block} block Block to position the drop-down around. - * @param {Function=} opt_onHide Optional callback for when the drop-down is hidden. - * @param {Number} opt_secondaryYOffset Optional Y offset for above-block positioning. - * @return {boolean} True if the menu rendered below block; false if above. - */ -Blockly.DropDownDiv.showPositionedByBlock = function(owner, block, - opt_onHide, opt_secondaryYOffset) { - var scale = block.workspace.scale; - var bBox = {width: block.width, height: block.height}; - bBox.width *= scale; - bBox.height *= scale; - var position = block.getSvgRoot().getBoundingClientRect(); - // If we can fit it, render below the block. - var primaryX = position.left + bBox.width / 2; - var primaryY = position.top + bBox.height; - // If we can't fit it, render above the entire parent block. - var secondaryX = primaryX; - var secondaryY = position.top; - if (opt_secondaryYOffset) { - secondaryY += opt_secondaryYOffset; - } - // Set bounds to workspace; show the drop-down. - Blockly.DropDownDiv.setBoundsElement(block.workspace.getParentSvg().parentNode); - return Blockly.DropDownDiv.show(this, primaryX, primaryY, secondaryX, secondaryY, opt_onHide); -}; - -/** - * Show and place the drop-down. - * The drop-down is placed with an absolute "origin point" (x, y) - i.e., - * the arrow will point at this origin and box will positioned below or above it. - * If we can maintain the container bounds at the primary point, the arrow will - * point there, and the container will be positioned below it. - * If we can't maintain the container bounds at the primary point, fall-back to the - * secondary point and position above. - * @param {Object} owner The object showing the drop-down - * @param {number} primaryX Desired origin point x, in absolute px - * @param {number} primaryY Desired origin point y, in absolute px - * @param {number} secondaryX Secondary/alternative origin point x, in absolute px - * @param {number} secondaryY Secondary/alternative origin point y, in absolute px - * @param {Function=} opt_onHide Optional callback for when the drop-down is hidden - * @return {boolean} True if the menu rendered at the primary origin point. - */ -Blockly.DropDownDiv.show = function(owner, primaryX, primaryY, secondaryX, secondaryY, opt_onHide) { - Blockly.DropDownDiv.owner_ = owner; - Blockly.DropDownDiv.onHide_ = opt_onHide; - var div = Blockly.DropDownDiv.DIV_; - var metrics = Blockly.DropDownDiv.getPositionMetrics(primaryX, primaryY, secondaryX, secondaryY); - // Update arrow CSS - Blockly.DropDownDiv.arrow_.style.transform = 'translate(' + - metrics.arrowX + 'px,' + metrics.arrowY + 'px) rotate(45deg)'; - Blockly.DropDownDiv.arrow_.setAttribute('class', - metrics.arrowAtTop ? 'blocklyDropDownArrow arrowTop' : 'blocklyDropDownArrow arrowBottom'); - // Set direction based on owner's rtl - div.style.direction = owner.sourceBlock_ && owner.sourceBlock_.RTL ? 'rtl' : 'ltr'; - - // When we change `translate` multiple times in close succession, - // Chrome may choose to wait and apply them all at once. - // Since we want the translation to initial X, Y to be immediate, - // and the translation to final X, Y to be animated, - // we saw problems where both would be applied after animation was turned on, - // making the dropdown appear to fly in from (0, 0). - // Using both `left`, `top` for the initial translation and then `translate` - // for the animated transition to final X, Y is a workaround. - - // First apply initial translation. - div.style.left = metrics.initialX + 'px'; - div.style.top = metrics.initialY + 'px'; - // Show the div. - div.style.display = 'block'; - div.style.opacity = 1; - // Add final translate, animated through `transition`. - // Coordinates are relative to (initialX, initialY), - // where the drop-down is absolutely positioned. - var dx = (metrics.finalX - metrics.initialX); - var dy = (metrics.finalY - metrics.initialY); - div.style.transform = 'translate(' + dx + 'px,' + dy + 'px)'; - return metrics.arrowAtTop; -}; - -/** - * Helper to position the drop-down and the arrow, maintaining bounds. - * See explanation of origin points in Blockly.DropDownDiv.show. - * @param {number} primaryX Desired origin point x, in absolute px - * @param {number} primaryY Desired origin point y, in absolute px - * @param {number} secondaryX Secondary/alternative origin point x, in absolute px - * @param {number} secondaryY Secondary/alternative origin point y, in absolute px - * @returns {Object} Various final metrics, including rendered positions for drop-down and arrow. - */ -Blockly.DropDownDiv.getPositionMetrics = function(primaryX, primaryY, secondaryX, secondaryY) { - var div = Blockly.DropDownDiv.DIV_; - var boundPosition = Blockly.DropDownDiv.boundsElement_.getBoundingClientRect(); - - var boundSize = goog.style.getSize(Blockly.DropDownDiv.boundsElement_); - var divSize = goog.style.getSize(div); - - // First decide if we will render at primary or secondary position - // i.e., above or below - // renderX, renderY will eventually be the final rendered position of the box. - var renderX, renderY, renderedSecondary; - // Can the div fit inside the bounds if we render below the primary point? - if (primaryY + divSize.height > boundPosition.top + boundSize.height) { - // We can't fit below in terms of y. Can we fit above? - if (secondaryY - divSize.height < boundPosition.top) { - // We also can't fit above, so just render below anyway. - renderX = primaryX; - renderY = primaryY + Blockly.DropDownDiv.PADDING_Y; - renderedSecondary = false; - } else { - // We can fit above, render secondary - renderX = secondaryX; - renderY = secondaryY - divSize.height - Blockly.DropDownDiv.PADDING_Y; - renderedSecondary = true; - } - } else { - // We can fit below, render primary - renderX = primaryX; - renderY = primaryY + Blockly.DropDownDiv.PADDING_Y; - renderedSecondary = false; - } - // First calculate the absolute arrow X - // This needs to be done before positioning the div, since the arrow - // wants to be as close to the origin point as possible. - var arrowX = renderX - Blockly.DropDownDiv.ARROW_SIZE / 2; - // Keep in overall bounds - arrowX = Math.max(boundPosition.left, Math.min(arrowX, boundPosition.left + boundSize.width)); - - // Adjust the x-position of the drop-down so that the div is centered and within bounds. - var centerX = divSize.width / 2; - renderX -= centerX; - // Fit horizontally in the bounds. - renderX = Math.max( - boundPosition.left, - Math.min(renderX, boundPosition.left + boundSize.width - divSize.width) - ); - // After we've finished caclulating renderX, adjust the arrow to be relative to it. - arrowX -= renderX; - - // Pad the arrow by some pixels, primarily so that it doesn't render on top of a rounded border. - arrowX = Math.max( - Blockly.DropDownDiv.ARROW_HORIZONTAL_PADDING, - Math.min(arrowX, divSize.width - Blockly.DropDownDiv.ARROW_HORIZONTAL_PADDING - Blockly.DropDownDiv.ARROW_SIZE) - ); - - // Calculate arrow Y. If we rendered secondary, add on bottom. - // Extra pixels are added so that it covers the border of the div. - var arrowY = (renderedSecondary) ? divSize.height - Blockly.DropDownDiv.BORDER_SIZE : 0; - arrowY -= (Blockly.DropDownDiv.ARROW_SIZE / 2) + Blockly.DropDownDiv.BORDER_SIZE; - - // Initial position calculated without any padding to provide an animation point. - var initialX = renderX; // X position remains constant during animation. - var initialY; - if (renderedSecondary) { - initialY = secondaryY - divSize.height; // No padding on Y - } else { - initialY = primaryY; // No padding on Y - } - - return { - initialX: initialX, - initialY : initialY, - finalX: renderX, - finalY: renderY, - arrowX: arrowX, - arrowY: arrowY, - arrowAtTop: !renderedSecondary - }; -}; - -/** - * Is the container visible? - * @return {boolean} True if visible. - */ -Blockly.DropDownDiv.isVisible = function() { - return !!Blockly.DropDownDiv.owner_; -}; - -/** - * Hide the menu only if it is owned by the provided object. - * @param {Object} owner Object which must be owning the drop-down to hide - * @return {Boolean} True if hidden - */ -Blockly.DropDownDiv.hideIfOwner = function(owner) { - if (Blockly.DropDownDiv.owner_ === owner) { - Blockly.DropDownDiv.hide(); - return true; - } - return false; -}; - -/** - * Hide the menu, triggering animation. - */ -Blockly.DropDownDiv.hide = function() { - // Start the animation by setting the translation and fading out. - var div = Blockly.DropDownDiv.DIV_; - // Reset to (initialX, initialY) - i.e., no translation. - div.style.transform = 'translate(0px, 0px)'; - div.style.opacity = 0; - Blockly.DropDownDiv.animateOutTimer_ = setTimeout(function() { - // Finish animation - reset all values to default. - Blockly.DropDownDiv.hideWithoutAnimation(); - }, Blockly.DropDownDiv.ANIMATION_TIME * 1000); - if (Blockly.DropDownDiv.onHide_) { - Blockly.DropDownDiv.onHide_(); - Blockly.DropDownDiv.onHide_ = null; - } -}; - -/** - * Hide the menu, without animation. - */ -Blockly.DropDownDiv.hideWithoutAnimation = function() { - if (!Blockly.DropDownDiv.isVisible()) { - return; - } - var div = Blockly.DropDownDiv.DIV_; - Blockly.DropDownDiv.animateOutTimer_ && window.clearTimeout(Blockly.DropDownDiv.animateOutTimer_); - div.style.transform = ''; - div.style.top = ''; - div.style.left = ''; - div.style.display = 'none'; - Blockly.DropDownDiv.clearContent(); - Blockly.DropDownDiv.owner_ = null; - if (Blockly.DropDownDiv.onHide_) { - Blockly.DropDownDiv.onHide_(); - Blockly.DropDownDiv.onHide_ = null; - } -}; diff --git a/core/events.js b/core/events.js deleted file mode 100644 index 9dc046ba0e..0000000000 --- a/core/events.js +++ /dev/null @@ -1,429 +0,0 @@ -/** - * @license - * Visual Blocks Editor - * - * Copyright 2016 Google Inc. - * https://developers.google.com/blockly/ - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @fileoverview Events fired as a result of actions in Blockly's editor. - * @author fraser@google.com (Neil Fraser) - */ -'use strict'; - -/** - * Events fired as a result of actions in Blockly's editor. - * @namespace Blockly.Events - */ -goog.provide('Blockly.Events'); - -goog.require('goog.array'); -goog.require('goog.math.Coordinate'); - - -/** - * Group ID for new events. Grouped events are indivisible. - * @type {string} - * @private - */ -Blockly.Events.group_ = ''; - -/** - * Sets whether events should be added to the undo stack. - * @type {boolean} - */ -Blockly.Events.recordUndo = true; - -/** - * Allow change events to be created and fired. - * @type {number} - * @private - */ -Blockly.Events.disabled_ = 0; - -/** - * Name of event that creates a block. Will be deprecated for BLOCK_CREATE. - * @const - */ -Blockly.Events.CREATE = 'create'; - -/** - * Name of event that creates a block. - * @const - */ -Blockly.Events.BLOCK_CREATE = Blockly.Events.CREATE; - -/** - * Name of event that deletes a block. Will be deprecated for BLOCK_DELETE. - * @const - */ -Blockly.Events.DELETE = 'delete'; - -/** - * Name of event that deletes a block. - * @const - */ -Blockly.Events.BLOCK_DELETE = Blockly.Events.DELETE; - -/** - * Name of event that changes a block. Will be deprecated for BLOCK_CHANGE. - * @const - */ -Blockly.Events.CHANGE = 'change'; - -/** - * Name of event that changes a block. - * @const - */ -Blockly.Events.BLOCK_CHANGE = Blockly.Events.CHANGE; - -/** - * Name of event that moves a block. Will be deprecated for BLOCK_MOVE. - * @const - */ -Blockly.Events.MOVE = 'move'; - -/** - * Name of event that drags a block outside of or into the blocks workspace - * @const - */ -Blockly.Events.DRAG_OUTSIDE = 'dragOutside'; - -/** - * Name of event that ends a block drag - * @const - */ -Blockly.Events.END_DRAG = 'endDrag'; - -/** - * Name of event that moves a block. - * @const - */ -Blockly.Events.BLOCK_MOVE = Blockly.Events.MOVE; - -/** - * Name of event that creates a variable. - * @const - */ -Blockly.Events.VAR_CREATE = 'var_create'; - -/** - * Name of event that deletes a variable. - * @const - */ -Blockly.Events.VAR_DELETE = 'var_delete'; - -/** - * Name of event that renames a variable. - * @const - */ -Blockly.Events.VAR_RENAME = 'var_rename'; - -/** - * Name of event that creates a comment. - * @const - */ -Blockly.Events.COMMENT_CREATE = 'comment_create'; - -/** - * Name of event that moves a comment. - * @const - */ -Blockly.Events.COMMENT_MOVE = 'comment_move'; - -/** - * Name of event that changes a comment's property - * (text content, size, or minimized state). - * @const - */ -Blockly.Events.COMMENT_CHANGE = 'comment_change'; - -/** - * Name of event that deletes a comment. - * @const - */ -Blockly.Events.COMMENT_DELETE = 'comment_delete'; - -/** - * Name of event that records a UI change. - * @const - */ -Blockly.Events.UI = 'ui'; - -/** - * List of events queued for firing. - * @private - */ -Blockly.Events.FIRE_QUEUE_ = []; - -/** - * Create a custom event and fire it. - * @param {!Blockly.Events.Abstract} event Custom data for event. - */ -Blockly.Events.fire = function(event) { - if (!Blockly.Events.isEnabled()) { - return; - } - if (!Blockly.Events.FIRE_QUEUE_.length) { - // First event added; schedule a firing of the event queue. - setTimeout(Blockly.Events.fireNow_, 0); - } - Blockly.Events.FIRE_QUEUE_.push(event); -}; - -/** - * Fire all queued events. - * @private - */ -Blockly.Events.fireNow_ = function() { - var queue = Blockly.Events.filter(Blockly.Events.FIRE_QUEUE_, true); - Blockly.Events.FIRE_QUEUE_.length = 0; - for (var i = 0, event; event = queue[i]; i++) { - var workspace = Blockly.Workspace.getById(event.workspaceId); - if (workspace) { - workspace.fireChangeListener(event); - } - } -}; - -/** - * Filter the queued events and merge duplicates. - * @param {!Array.} queueIn Array of events. - * @param {boolean} forward True if forward (redo), false if backward (undo). - * @return {!Array.} Array of filtered events. - */ -Blockly.Events.filter = function(queueIn, forward) { - var queue = goog.array.clone(queueIn); - if (!forward) { - // Undo is merged in reverse order. - queue.reverse(); - } - var mergedQueue = []; - var hash = Object.create(null); - // Merge duplicates. - for (var i = 0, event; event = queue[i]; i++) { - if (!event.isNull()) { - var key = [event.type, event.blockId, event.workspaceId].join(' '); - - var lastEntry = hash[key]; - var lastEvent = lastEntry ? lastEntry.event : null; - if (!lastEntry) { - // Each item in the hash table has the event and the index of that event - // in the input array. This lets us make sure we only merge adjacent - // move events. - hash[key] = {event: event, index: i}; - mergedQueue.push(event); - } else if (event.type == Blockly.Events.MOVE && - lastEntry.index == i - 1) { - // Merge move events. - lastEvent.newParentId = event.newParentId; - lastEvent.newInputName = event.newInputName; - lastEvent.newCoordinate = event.newCoordinate; - lastEntry.index = i; - } else if (event.type == Blockly.Events.CHANGE && - event.element == lastEvent.element && - event.name == lastEvent.name) { - // Merge change events. - lastEvent.newValue = event.newValue; - } else if (event.type == Blockly.Events.UI && - event.element == 'click' && - (lastEvent.element == 'commentOpen' || - lastEvent.element == 'mutatorOpen' || - lastEvent.element == 'warningOpen')) { - // Merge click events. - lastEvent.newValue = event.newValue; - } else { - // Collision: newer events should merge into this event to maintain order - hash[key] = {event: event, index: 1}; - mergedQueue.push(event); - } - } - } - // Filter out any events that have become null due to merging. - queue = mergedQueue.filter(function(e) { return !e.isNull(); }); - if (!forward) { - // Restore undo order. - queue.reverse(); - } - // Move mutation events to the top of the queue. - // Intentionally skip first event. - for (var i = 1, event; event = queue[i]; i++) { - if (event.type == Blockly.Events.CHANGE && - event.element == 'mutation') { - queue.unshift(queue.splice(i, 1)[0]); - } - } - return queue; -}; - -/** - * Modify pending undo events so that when they are fired they don't land - * in the undo stack. Called by Blockly.Workspace.clearUndo. - */ -Blockly.Events.clearPendingUndo = function() { - for (var i = 0, event; event = Blockly.Events.FIRE_QUEUE_[i]; i++) { - event.recordUndo = false; - } -}; - -/** - * Stop sending events. Every call to this function MUST also call enable. - */ -Blockly.Events.disable = function() { - Blockly.Events.disabled_++; -}; - -/** - * Start sending events. Unless events were already disabled when the - * corresponding call to disable was made. - */ -Blockly.Events.enable = function() { - Blockly.Events.disabled_--; -}; - -/** - * Returns whether events may be fired or not. - * @return {boolean} True if enabled. - */ -Blockly.Events.isEnabled = function() { - return Blockly.Events.disabled_ == 0; -}; - -/** - * Current group. - * @return {string} ID string. - */ -Blockly.Events.getGroup = function() { - return Blockly.Events.group_; -}; - -/** - * Start or stop a group. - * @param {boolean|string} state True to start new group, false to end group. - * String to set group explicitly. - */ -Blockly.Events.setGroup = function(state) { - if (typeof state == 'boolean') { - Blockly.Events.group_ = state ? Blockly.utils.genUid() : ''; - } else { - Blockly.Events.group_ = state; - } -}; - -/** - * Compute a list of the IDs of the specified block and all its descendants. - * @param {!Blockly.Block} block The root block. - * @return {!Array.} List of block IDs. - * @private - */ -Blockly.Events.getDescendantIds_ = function(block) { - var ids = []; - var descendants = block.getDescendants(false); - for (var i = 0, descendant; descendant = descendants[i]; i++) { - ids[i] = descendant.id; - } - return ids; -}; - -/** - * Decode the JSON into an event. - * @param {!Object} json JSON representation. - * @param {!Blockly.Workspace} workspace Target workspace for event. - * @return {!Blockly.Events.Abstract} The event represented by the JSON. - */ -Blockly.Events.fromJson = function(json, workspace) { - var event; - switch (json.type) { - case Blockly.Events.CREATE: - event = new Blockly.Events.Create(null); - break; - case Blockly.Events.DELETE: - event = new Blockly.Events.Delete(null); - break; - case Blockly.Events.CHANGE: - event = new Blockly.Events.Change(null); - break; - case Blockly.Events.MOVE: - event = new Blockly.Events.Move(null); - break; - case Blockly.Events.VAR_CREATE: - event = new Blockly.Events.VarCreate(null); - break; - case Blockly.Events.VAR_DELETE: - event = new Blockly.Events.VarDelete(null); - break; - case Blockly.Events.VAR_RENAME: - event = new Blockly.Events.VarRename(null); - break; - case Blockly.Events.COMMENT_CREATE: - event = new Blockly.Events.CommentCreate(null); - break; - case Blockly.Events.COMMENT_CHANGE: - event = new Blockly.Events.CommentChange(null); - break; - case Blockly.Events.COMMENT_MOVE: - event = new Blockly.Events.CommentMove(null); - break; - case Blockly.Events.COMMENT_DELETE: - event = new Blockly.Events.CommentDelete(null); - break; - case Blockly.Events.UI: - event = new Blockly.Events.Ui(null); - break; - case Blockly.Events.DRAG_OUTSIDE: - event = new Blockly.Events.DragBlockOutside(null); - break; - case Blockly.Events.END_DRAG: - event = new Blockly.Events.EndBlockDrag(null, false); - break; - default: - throw 'Unknown event type.'; - } - event.fromJson(json); - event.workspaceId = workspace.id; - return event; -}; - -/** - * Enable/disable a block depending on whether it is properly connected. - * Use this on applications where all blocks should be connected to a top block. - * Recommend setting the 'disable' option to 'false' in the config so that - * users don't try to reenable disabled orphan blocks. - * @param {!Blockly.Events.Abstract} event Custom data for event. - */ -Blockly.Events.disableOrphans = function(event) { - if (event.type == Blockly.Events.MOVE || - event.type == Blockly.Events.CREATE) { - Blockly.Events.disable(); - var workspace = Blockly.Workspace.getById(event.workspaceId); - var block = workspace.getBlockById(event.blockId); - if (block) { - if (block.getParent() && !block.getParent().disabled) { - var children = block.getDescendants(false); - for (var i = 0, child; child = children[i]; i++) { - child.setDisabled(false); - } - } else if ((block.outputConnection || block.previousConnection) && - !workspace.isDragging()) { - do { - block.setDisabled(true); - block = block.getNextBlock(); - } while (block); - } - } - Blockly.Events.enable(); - } -}; diff --git a/core/events_abstract.js b/core/events_abstract.js deleted file mode 100644 index 2af78c3fc5..0000000000 --- a/core/events_abstract.js +++ /dev/null @@ -1,113 +0,0 @@ -/** - * @license - * Visual Blocks Editor - * - * Copyright 2018 Google Inc. - * https://developers.google.com/blockly/ - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @fileoverview Abstract class for events fired as a result of actions in - * Blockly's editor. - * @author fraser@google.com (Neil Fraser) - */ -'use strict'; - -goog.provide('Blockly.Events.Abstract'); - -goog.require('Blockly.Events'); -goog.require('goog.array'); -goog.require('goog.math.Coordinate'); - -/** - * Abstract class for an event. - * @constructor - */ -Blockly.Events.Abstract = function() { - /** - * The workspace identifier for this event. - * @type {string|undefined} - */ - this.workspaceId = undefined; - - /** - * The event group id for the group this event belongs to. Groups define - * events that should be treated as an single action from the user's - * perspective, and should be undone together. - * @type {string} - */ - this.group = Blockly.Events.group_; - - /** - * Sets whether the event should be added to the undo stack. - * @type {boolean} - */ - this.recordUndo = Blockly.Events.recordUndo; -}; - -/** - * Encode the event as JSON. - * @return {!Object} JSON representation. - */ -Blockly.Events.Abstract.prototype.toJson = function() { - var json = { - 'type': this.type - }; - if (this.group) { - json['group'] = this.group; - } - return json; -}; - -/** - * Decode the JSON event. - * @param {!Object} json JSON representation. - */ -Blockly.Events.Abstract.prototype.fromJson = function(json) { - this.group = json['group']; -}; - -/** - * Does this event record any change of state? - * By default we assume events are non-null. Subclasses may override to - * indicate that they do not change state. - * @return {boolean} False if something changed. - */ -Blockly.Events.Abstract.prototype.isNull = function() { - return false; -}; - -/** - * Run an event. - * @param {boolean} _forward True if run forward, false if run backward (undo). - */ -Blockly.Events.Abstract.prototype.run = function(_forward) { - // Defined by subclasses. -}; - -/** - * Get workspace the event belongs to. - * @return {Blockly.Workspace} The workspace the event belongs to. - * @throws {Error} if workspace is null. - * @protected - */ -Blockly.Events.Abstract.prototype.getEventWorkspace_ = function() { - var workspace = Blockly.Workspace.getById(this.workspaceId); - if (!workspace) { - throw Error('Workspace is null. Event must have been generated from real' + - ' Blockly events.'); - } - return workspace; -}; diff --git a/core/extensions.js b/core/extensions.js deleted file mode 100644 index 1aabed1be0..0000000000 --- a/core/extensions.js +++ /dev/null @@ -1,450 +0,0 @@ -/** - * @license - * Visual Blocks Editor - * - * Copyright 2017 Google Inc. - * https://developers.google.com/blockly/ - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @fileoverview Extensions are functions that help initialize blocks, usually - * adding dynamic behavior such as onchange handlers and mutators. These - * are applied using Block.applyExtension(), or the JSON "extensions" - * array attribute. - * @author Anm@anm.me (Andrew n marshall) - */ -'use strict'; - -/** - * @name Blockly.Extensions - * @namespace - **/ -goog.provide('Blockly.Extensions'); - -goog.require('Blockly.Mutator'); -goog.require('Blockly.utils'); - -goog.require('goog.string'); - - -/** - * The set of all registered extensions, keyed by extension name/id. - * @private - */ -Blockly.Extensions.ALL_ = {}; - -/** - * Registers a new extension function. Extensions are functions that help - * initialize blocks, usually adding dynamic behavior such as onchange - * handlers and mutators. These are applied using Block.applyExtension(), or - * the JSON "extensions" array attribute. - * @param {string} name The name of this extension. - * @param {Function} initFn The function to initialize an extended block. - * @throws {Error} if the extension name is empty, the extension is already - * registered, or extensionFn is not a function. - */ -Blockly.Extensions.register = function(name, initFn) { - if (!goog.isString(name) || goog.string.isEmptyOrWhitespace(name)) { - throw new Error('Error: Invalid extension name "' + name + '"'); - } - if (Blockly.Extensions.ALL_[name]) { - throw new Error('Error: Extension "' + name + '" is already registered.'); - } - if (!goog.isFunction(initFn)) { - throw new Error('Error: Extension "' + name + '" must be a function'); - } - Blockly.Extensions.ALL_[name] = initFn; -}; - -/** - * Registers a new extension function that adds all key/value of mixinObj. - * @param {string} name The name of this extension. - * @param {!Object} mixinObj The values to mix in. - * @throws {Error} if the extension name is empty or the extension is already - * registered. - */ -Blockly.Extensions.registerMixin = function(name, mixinObj) { - if (!goog.isObject(mixinObj)){ - throw new Error('Error: Mixin "' + name + '" must be a object'); - } - Blockly.Extensions.register(name, function() { - this.mixin(mixinObj); - }); -}; - -/** - * Registers a new extension function that adds a mutator to the block. - * At register time this performs some basic sanity checks on the mutator. - * The wrapper may also add a mutator dialog to the block, if both compose and - * decompose are defined on the mixin. - * @param {string} name The name of this mutator extension. - * @param {!Object} mixinObj The values to mix in. - * @param {(function())=} opt_helperFn An optional function to apply after - * mixing in the object. - * @param {Array.=} opt_blockList A list of blocks to appear in the - * flyout of the mutator dialog. - * @throws {Error} if the mutation is invalid or can't be applied to the block. - */ -Blockly.Extensions.registerMutator = function(name, mixinObj, opt_helperFn, - opt_blockList) { - var errorPrefix = 'Error when registering mutator "' + name + '": '; - - // Sanity check the mixin object before registering it. - Blockly.Extensions.checkHasFunction_( - errorPrefix, mixinObj.domToMutation, 'domToMutation'); - Blockly.Extensions.checkHasFunction_( - errorPrefix, mixinObj.mutationToDom, 'mutationToDom'); - - var hasMutatorDialog = - Blockly.Extensions.checkMutatorDialog_(mixinObj, errorPrefix); - - if (opt_helperFn && !goog.isFunction(opt_helperFn)) { - throw new Error('Extension "' + name + '" is not a function'); - } - - // Sanity checks passed. - Blockly.Extensions.register(name, function() { - if (hasMutatorDialog) { - this.setMutator(new Blockly.Mutator(opt_blockList)); - } - // Mixin the object. - this.mixin(mixinObj); - - if (opt_helperFn) { - opt_helperFn.apply(this); - } - }); -}; - -/** - * Applies an extension method to a block. This should only be called during - * block construction. - * @param {string} name The name of the extension. - * @param {!Blockly.Block} block The block to apply the named extension to. - * @param {boolean} isMutator True if this extension defines a mutator. - * @throws {Error} if the extension is not found. - */ -Blockly.Extensions.apply = function(name, block, isMutator) { - var extensionFn = Blockly.Extensions.ALL_[name]; - if (!goog.isFunction(extensionFn)) { - throw new Error('Error: Extension "' + name + '" not found.'); - } - if (isMutator) { - // Fail early if the block already has mutation properties. - Blockly.Extensions.checkNoMutatorProperties_(name, block); - } else { - // Record the old properties so we can make sure they don't change after - // applying the extension. - var mutatorProperties = Blockly.Extensions.getMutatorProperties_(block); - } - extensionFn.apply(block); - - if (isMutator) { - var errorPrefix = 'Error after applying mutator "' + name + '": '; - Blockly.Extensions.checkBlockHasMutatorProperties_(errorPrefix, block); - } else { - if (!Blockly.Extensions.mutatorPropertiesMatch_(mutatorProperties, block)) { - throw new Error('Error when applying extension "' + name + '": ' + - 'mutation properties changed when applying a non-mutator extension.'); - } - } -}; - -/** - * Check that the given value is a function. - * @param {string} errorPrefix The string to prepend to any error message. - * @param {*} func Function to check. - * @param {string} propertyName Which property to check. - * @throws {Error} if the property does not exist or is not a function. - * @private - */ -Blockly.Extensions.checkHasFunction_ = function(errorPrefix, func, - propertyName) { - if (!func) { - throw new Error(errorPrefix + - 'missing required property "' + propertyName + '"'); - } else if (typeof func != 'function') { - throw new Error(errorPrefix + - '" required property "' + propertyName + '" must be a function'); - } -}; - -/** - * Check that the given block does not have any of the four mutator properties - * defined on it. This function should be called before applying a mutator - * extension to a block, to make sure we are not overwriting properties. - * @param {string} mutationName The name of the mutation to reference in error - * messages. - * @param {!Blockly.Block} block The block to check. - * @throws {Error} if any of the properties already exist on the block. - * @private - */ -Blockly.Extensions.checkNoMutatorProperties_ = function(mutationName, block) { - var properties = Blockly.Extensions.getMutatorProperties_(block); - if (properties.length) { - throw new Error('Error: tried to apply mutation "' + mutationName + - '" to a block that already has mutator functions.' + - ' Block id: ' + block.id); - } -}; - -/** - * Check that the given object has both or neither of the functions required - * to have a mutator dialog. - * These functions are 'compose' and 'decompose'. If a block has one, it must - * have both. - * @param {!Object} object The object to check. - * @param {string} errorPrefix The string to prepend to any error message. - * @return {boolean} True if the object has both functions. False if it has - * neither function. - * @throws {Error} if the object has only one of the functions. - * @private - */ -Blockly.Extensions.checkMutatorDialog_ = function(object, errorPrefix) { - var hasCompose = object.compose !== undefined; - var hasDecompose = object.decompose !== undefined; - - if (hasCompose && hasDecompose) { - if (typeof object.compose != 'function') { - throw new Error(errorPrefix + 'compose must be a function.'); - } else if (typeof object.decompose != 'function') { - throw new Error(errorPrefix + 'decompose must be a function.'); - } - return true; - } else if (!hasCompose && !hasDecompose) { - return false; - } else { - throw new Error(errorPrefix + - 'Must have both or neither of "compose" and "decompose"'); - } -}; - -/** - * Check that a block has required mutator properties. This should be called - * after applying a mutation extension. - * @param {string} errorPrefix The string to prepend to any error message. - * @param {!Blockly.Block} block The block to inspect. - * @private - */ -Blockly.Extensions.checkBlockHasMutatorProperties_ = function(errorPrefix, - block) { - if (typeof block.domToMutation !== 'function') { - throw new Error(errorPrefix + 'Applying a mutator didn\'t add "domToMutation"'); - } - if (typeof block.mutationToDom != 'function') { - throw new Error(errorPrefix + - 'Applying a mutator didn\'t add "mutationToDom"'); - } - - // A block with a mutator isn't required to have a mutation dialog, but - // it should still have both or neither of compose and decompose. - Blockly.Extensions.checkMutatorDialog_(block, errorPrefix); -}; - -/** - * Get a list of values of mutator properties on the given block. - * @param {!Blockly.Block} block The block to inspect. - * @return {!Array.} a list with all of the defined properties, which - * should be functions, but may be anything other than undefined. - * @private - */ -Blockly.Extensions.getMutatorProperties_ = function(block) { - var result = []; - // List each function explicitly by reference to allow for renaming - // during compilation. - if (block.domToMutation !== undefined) { - result.push(block.domToMutation); - } - if (block.mutationToDom !== undefined) { - result.push(block.mutationToDom); - } - if (block.compose !== undefined) { - result.push(block.compose); - } - if (block.decompose !== undefined) { - result.push(block.decompose); - } - return result; -}; - -/** - * Check that the current mutator properties match a list of old mutator - * properties. This should be called after applying a non-mutator extension, - * to verify that the extension didn't change properties it shouldn't. - * @param {!Array.} oldProperties The old values to compare to. - * @param {!Blockly.Block} block The block to inspect for new values. - * @return {boolean} True if the property lists match. - * @private - */ -Blockly.Extensions.mutatorPropertiesMatch_ = function(oldProperties, block) { - var newProperties = Blockly.Extensions.getMutatorProperties_(block); - if (newProperties.length != oldProperties.length) { - return false; - } - for (var i = 0; i < newProperties.length; i++) { - if (oldProperties[i] != newProperties[i]) { - return false; - } - } - return true; -}; - -/** - * Builds an extension function that will map a dropdown value to a tooltip - * string. - * - * This method includes multiple checks to ensure tooltips, dropdown options, - * and message references are aligned. This aims to catch errors as early as - * possible, without requiring developers to manually test tooltips under each - * option. After the page is loaded, each tooltip text string will be checked - * for matching message keys in the internationalized string table. Deferring - * this until the page is loaded decouples loading dependencies. Later, upon - * loading the first block of any given type, the extension will validate every - * dropdown option has a matching tooltip in the lookupTable. Errors are - * reported as warnings in the console, and are never fatal. - * @param {string} dropdownName The name of the field whose value is the key - * to the lookup table. - * @param {!Object.} lookupTable The table of field values to - * tooltip text. - * @return {Function} The extension function. - */ -Blockly.Extensions.buildTooltipForDropdown = function(dropdownName, - lookupTable) { - // List of block types already validated, to minimize duplicate warnings. - var blockTypesChecked = []; - - // Check the tooltip string messages for invalid references. - // Wait for load, in case Blockly.Msg is not yet populated. - // runAfterPageLoad() does not run in a Node.js environment due to lack of - // document object, in which case skip the validation. - if (document) { // Relies on document.readyState - Blockly.utils.runAfterPageLoad(function() { - for (var key in lookupTable) { - // Will print warnings is reference is missing. - Blockly.utils.checkMessageReferences(lookupTable[key]); - } - }); - } - - /** - * The actual extension. - * @this {Blockly.Block} - */ - var extensionFn = function() { - if (this.type && blockTypesChecked.indexOf(this.type) === -1) { - Blockly.Extensions.checkDropdownOptionsInTable_( - this, dropdownName, lookupTable); - blockTypesChecked.push(this.type); - } - - this.setTooltip(function() { - var value = this.getFieldValue(dropdownName); - var tooltip = lookupTable[value]; - if (tooltip == null) { - if (blockTypesChecked.indexOf(this.type) === -1) { - // Warn for missing values on generated tooltips. - var warning = 'No tooltip mapping for value ' + value + - ' of field ' + dropdownName; - if (this.type != null) { - warning += (' of block type ' + this.type); - } - console.warn(warning + '.'); - } - } else { - tooltip = Blockly.utils.replaceMessageReferences(tooltip); - } - return tooltip; - }.bind(this)); - }; - return extensionFn; -}; - -/** - * Checks all options keys are present in the provided string lookup table. - * Emits console warnings when they are not. - * @param {!Blockly.Block} block The block containing the dropdown - * @param {string} dropdownName The name of the dropdown - * @param {!Object.} lookupTable The string lookup table - * @private - */ -Blockly.Extensions.checkDropdownOptionsInTable_ = function(block, dropdownName, - lookupTable) { - // Validate all dropdown options have values. - var dropdown = block.getField(dropdownName); - if (!dropdown.isOptionListDynamic()) { - var options = dropdown.getOptions(); - for (var i = 0; i < options.length; ++i) { - var optionKey = options[i][1]; // label, then value - if (lookupTable[optionKey] == null) { - console.warn('No tooltip mapping for value ' + optionKey + - ' of field ' + dropdownName + ' of block type ' + block.type); - } - } - } -}; - -/** - * Builds an extension function that will install a dynamic tooltip. The - * tooltip message should include the string '%1' and that string will be - * replaced with the value of the named field. - * @param {string} msgTemplate The template form to of the message text, with - * %1 placeholder. - * @param {string} fieldName The field with the replacement value. - * @returns {Function} The extension function. - */ -Blockly.Extensions.buildTooltipWithFieldValue = - function(msgTemplate, fieldName) { - // Check the tooltip string messages for invalid references. - // Wait for load, in case Blockly.Msg is not yet populated. - // runAfterPageLoad() does not run in a Node.js environment due to lack of - // document object, in which case skip the validation. - if (document) { // Relies on document.readyState - Blockly.utils.runAfterPageLoad(function() { - // Will print warnings is reference is missing. - Blockly.utils.checkMessageReferences(msgTemplate); - }); - } - - /** - * The actual extension. - * @this {Blockly.Block} - */ - var extensionFn = function() { - this.setTooltip(function() { - return Blockly.utils.replaceMessageReferences(msgTemplate) - .replace('%1', this.getFieldValue(fieldName)); - }.bind(this)); - }; - return extensionFn; - }; - -/** - * Configures the tooltip to mimic the parent block when connected. Otherwise, - * uses the tooltip text at the time this extension is initialized. This takes - * advantage of the fact that all other values from JSON are initialized before - * extensions. - * @this {Blockly.Block} - * @private - */ -Blockly.Extensions.extensionParentTooltip_ = function() { - this.tooltipWhenNotConnected_ = this.tooltip; - this.setTooltip(function() { - var parent = this.getParent(); - return (parent && parent.getInputsInline() && parent.tooltip) || - this.tooltipWhenNotConnected_; - }.bind(this)); -}; -Blockly.Extensions.register('parent_tooltip_when_inline', - Blockly.Extensions.extensionParentTooltip_); diff --git a/core/field.js b/core/field.js deleted file mode 100644 index 692caa96a2..0000000000 --- a/core/field.js +++ /dev/null @@ -1,807 +0,0 @@ -/** - * @license - * Visual Blocks Editor - * - * Copyright 2012 Google Inc. - * https://developers.google.com/blockly/ - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @fileoverview Field. Used for editable titles, variables, etc. - * This is an abstract class that defines the UI on the block. Actual - * instances would be Blockly.FieldTextInput, Blockly.FieldDropdown, etc. - * @author fraser@google.com (Neil Fraser) - */ -'use strict'; - -goog.provide('Blockly.Field'); - -goog.require('Blockly.Events.BlockChange'); -goog.require('Blockly.Gesture'); - -goog.require('goog.asserts'); -goog.require('goog.dom'); -goog.require('goog.math.Size'); -goog.require('goog.style'); -goog.require('goog.userAgent'); - - -/** - * Abstract class for an editable field. - * @param {string} text The initial content of the field. - * @param {Function=} opt_validator An optional function that is called - * to validate any constraints on what the user entered. Takes the new - * text as an argument and returns either the accepted text, a replacement - * text, or null to abort the change. - * @constructor - */ -Blockly.Field = function(text, opt_validator) { - this.size_ = new goog.math.Size( - Blockly.BlockSvg.FIELD_WIDTH, - Blockly.BlockSvg.FIELD_HEIGHT); - this.setValue(text); - this.setValidator(opt_validator); - - /** - * Maximum characters of text to display before adding an ellipsis. - * Same for strings and numbers. - * @type {number} - */ - this.maxDisplayLength = Blockly.BlockSvg.MAX_DISPLAY_LENGTH; -}; - - -/** - * The set of all registered fields, keyed by field type as used in the JSON - * definition of a block. - * @type {!Object} - * @private - */ -Blockly.Field.TYPE_MAP_ = {}; - -/** - * Registers a field type. May also override an existing field type. - * Blockly.Field.fromJson uses this registry to find the appropriate field. - * @param {!string} type The field type name as used in the JSON definition. - * @param {!{fromJson: Function}} fieldClass The field class containing a - * fromJson function that can construct an instance of the field. - * @throws {Error} if the type name is empty, or the fieldClass is not an - * object containing a fromJson function. - */ -Blockly.Field.register = function(type, fieldClass) { - if (!goog.isString(type) || goog.string.isEmptyOrWhitespace(type)) { - throw new Error('Invalid field type "' + type + '"'); - } - if (!goog.isObject(fieldClass) || !goog.isFunction(fieldClass.fromJson)) { - throw new Error('Field "' + fieldClass + - '" must have a fromJson function'); - } - Blockly.Field.TYPE_MAP_[type] = fieldClass; -}; - -/** - * Construct a Field from a JSON arg object. - * Finds the appropriate registered field by the type name as registered using - * Blockly.Field.register. - * @param {!Object} options A JSON object with a type and options specific - * to the field type. - * @returns {?Blockly.Field} The new field instance or null if a field wasn't - * found with the given type name - * @package - */ -Blockly.Field.fromJson = function(options) { - var fieldClass = Blockly.Field.TYPE_MAP_[options['type']]; - if (fieldClass) { - return fieldClass.fromJson(options); - } - return null; -}; - -/** - * Temporary cache of text widths. - * @type {Object} - * @private - */ -Blockly.Field.cacheWidths_ = null; - -/** - * Number of current references to cache. - * @type {number} - * @private - */ -Blockly.Field.cacheReference_ = 0; - - -/** - * Name of field. Unique within each block. - * Static labels are usually unnamed. - * @type {string|undefined} - */ -Blockly.Field.prototype.name = undefined; - -/** - * CSS class name for the text element. - * @type {string} - * @package - */ -Blockly.Field.prototype.className_ = 'blocklyText'; - -/** - * Visible text to display. - * @type {string} - * @private - */ -Blockly.Field.prototype.text_ = ''; - -/** - * Block this field is attached to. Starts as null, then in set in init. - * @type {Blockly.Block} - * @private - */ -Blockly.Field.prototype.sourceBlock_ = null; - -/** - * Is the field visible, or hidden due to the block being collapsed? - * @type {boolean} - * @private - */ -Blockly.Field.prototype.visible_ = true; - -/** - * Null, or an array of the field's argTypes (for styling). - * @type {Array} - * @private - */ -Blockly.Field.prototype.argType_ = null; - -/** - * Validation function called when user edits an editable field. - * @type {Function} - * @private - */ -Blockly.Field.prototype.validator_ = null; - -/** - * Whether to assume user is using a touch device for interactions. - * Used to show different UI for touch interactions, e.g. - * @type {boolean} - * @private - */ -Blockly.Field.prototype.useTouchInteraction_ = false; - -/** - * Non-breaking space. - * @const - */ -Blockly.Field.NBSP = '\u00A0'; - -/** - * Text offset used for IE/Edge. - * @const - */ -Blockly.Field.IE_TEXT_OFFSET = '0.3em'; - -/** - * Editable fields usually show some sort of UI for the user to change them. - * @type {boolean} - * @public - */ -Blockly.Field.prototype.EDITABLE = true; - -/** - * Serializable fields are saved by the XML renderer, non-serializable fields - * are not. Editable fields should be serialized. - * @type {boolean} - * @public - */ -Blockly.Field.prototype.SERIALIZABLE = true; - -/** - * Attach this field to a block. - * @param {!Blockly.Block} block The block containing this field. - */ -Blockly.Field.prototype.setSourceBlock = function(block) { - goog.asserts.assert(!this.sourceBlock_, 'Field already bound to a block.'); - this.sourceBlock_ = block; -}; - -/** - * Install this field on a block. - */ -Blockly.Field.prototype.init = function() { - if (this.fieldGroup_) { - // Field has already been initialized once. - return; - } - // Build the DOM. - this.fieldGroup_ = Blockly.utils.createSvgElement('g', {}, null); - if (!this.visible_) { - this.fieldGroup_.style.display = 'none'; - } - // Add an attribute to cassify the type of field. - if (this.getArgTypes() !== null) { - if (this.sourceBlock_.isShadow()) { - this.sourceBlock_.svgGroup_.setAttribute('data-argument-type', - this.getArgTypes()); - } else { - // Fields without a shadow wrapper, like square dropdowns. - this.fieldGroup_.setAttribute('data-argument-type', this.getArgTypes()); - } - } - // Adjust X to be flipped for RTL. Position is relative to horizontal start of source block. - var size = this.getSize(); - var fieldX = (this.sourceBlock_.RTL) ? -size.width / 2 : size.width / 2; - /** @type {!Element} */ - this.textElement_ = Blockly.utils.createSvgElement('text', - { - 'class': this.className_, - 'x': fieldX, - 'y': size.height / 2 + Blockly.BlockSvg.FIELD_TOP_PADDING, - 'dominant-baseline': 'middle', - 'dy': goog.userAgent.EDGE_OR_IE ? Blockly.Field.IE_TEXT_OFFSET : '0', - 'text-anchor': 'middle' - }, this.fieldGroup_); - - this.updateEditable(); - this.sourceBlock_.getSvgRoot().appendChild(this.fieldGroup_); - // Force a render. - this.render_(); - this.size_.width = 0; - this.mouseDownWrapper_ = Blockly.bindEventWithChecks_( - this.getClickTarget_(), 'mousedown', this, this.onMouseDown_); -}; - -/** - * Initializes the model of the field after it has been installed on a block. - * No-op by default. - */ -Blockly.Field.prototype.initModel = function() { -}; - -/** - * Dispose of all DOM objects belonging to this editable field. - */ -Blockly.Field.prototype.dispose = function() { - if (this.mouseDownWrapper_) { - Blockly.unbindEvent_(this.mouseDownWrapper_); - this.mouseDownWrapper_ = null; - } - this.sourceBlock_ = null; - goog.dom.removeNode(this.fieldGroup_); - this.fieldGroup_ = null; - this.textElement_ = null; - this.validator_ = null; -}; - -/** - * Add or remove the UI indicating if this field is editable or not. - */ -Blockly.Field.prototype.updateEditable = function() { - var group = this.fieldGroup_; - if (!this.EDITABLE || !group) { - return; - } - if (this.sourceBlock_.isEditable()) { - Blockly.utils.addClass(group, 'blocklyEditableText'); - Blockly.utils.removeClass(group, 'blocklyNonEditableText'); - this.fieldGroup_.style.cursor = this.CURSOR; - } else { - Blockly.utils.addClass(group, 'blocklyNonEditableText'); - Blockly.utils.removeClass(group, 'blocklyEditableText'); - this.fieldGroup_.style.cursor = ''; - } -}; - -/** - * Check whether this field is currently editable. Some fields are never - * editable (e.g. text labels). Those fields are not serialized to XML. Other - * fields may be editable, and therefore serialized, but may exist on - * non-editable blocks. - * @return {boolean} whether this field is editable and on an editable block - */ -Blockly.Field.prototype.isCurrentlyEditable = function() { - return this.EDITABLE && !!this.sourceBlock_ && this.sourceBlock_.isEditable(); -}; - -/** - * Gets whether this editable field is visible or not. - * @return {boolean} True if visible. - */ -Blockly.Field.prototype.isVisible = function() { - return this.visible_; -}; - -/** - * Sets whether this editable field is visible or not. - * @param {boolean} visible True if visible. - */ -Blockly.Field.prototype.setVisible = function(visible) { - if (this.visible_ == visible) { - return; - } - this.visible_ = visible; - var root = this.getSvgRoot(); - if (root) { - root.style.display = visible ? 'block' : 'none'; - this.render_(); - } -}; - -/** - * Adds a string to the field's array of argTypes (used for styling). - * @param {string} argType New argType. - */ -Blockly.Field.prototype.addArgType = function(argType) { - if (this.argType_ == null) { - this.argType_ = []; - } - this.argType_.push(argType); -}; - -/** - * Gets the field's argTypes joined as a string, or returns null (used for styling). - * @return {string} argType string, or null. - */ -Blockly.Field.prototype.getArgTypes = function() { - if (this.argType_ === null || this.argType_.length === 0) { - return null; - } else { - return this.argType_.join(' '); - } -}; - -/** - * Sets a new validation function for editable fields. - * @param {Function} handler New validation function, or null. - */ -Blockly.Field.prototype.setValidator = function(handler) { - this.validator_ = handler; -}; - -/** - * Gets the validation function for editable fields. - * @return {Function} Validation function, or null. - */ -Blockly.Field.prototype.getValidator = function() { - return this.validator_; -}; - -/** - * Validates a change. Does nothing. Subclasses may override this. - * @param {string} text The user's text. - * @return {string} No change needed. - */ -Blockly.Field.prototype.classValidator = function(text) { - return text; -}; - -/** - * Calls the validation function for this field, as well as all the validation - * function for the field's class and its parents. - * @param {string} text Proposed text. - * @return {?string} Revised text, or null if invalid. - */ -Blockly.Field.prototype.callValidator = function(text) { - var classResult = this.classValidator(text); - if (classResult === null) { - // Class validator rejects value. Game over. - return null; - } else if (classResult !== undefined) { - text = classResult; - } - var userValidator = this.getValidator(); - if (userValidator) { - var userResult = userValidator.call(this, text); - if (userResult === null) { - // User validator rejects value. Game over. - return null; - } else if (userResult !== undefined) { - text = userResult; - } - } - return text; -}; - -/** - * Gets the group element for this editable field. - * Used for measuring the size and for positioning. - * @return {!Element} The group element. - */ -Blockly.Field.prototype.getSvgRoot = function() { - return /** @type {!Element} */ (this.fieldGroup_); -}; - -/** - * Draws the border with the correct width. - * Saves the computed width in a property. - * @private - */ -Blockly.Field.prototype.render_ = function() { - if (this.visible_ && this.textElement_) { - // Replace the text. - this.textElement_.textContent = this.getDisplayText_(); - this.updateWidth(); - - // Update text centering, based on newly calculated width. - var centerTextX = (this.size_.width - this.arrowWidth_) / 2; - if (this.sourceBlock_.RTL) { - centerTextX += this.arrowWidth_; - } - - // In a text-editing shadow block's field, - // if half the text length is not at least center of - // visible field (FIELD_WIDTH), center it there instead, - // unless there is a drop-down arrow. - if (this.sourceBlock_.isShadow() && !this.positionArrow) { - var minOffset = Blockly.BlockSvg.FIELD_WIDTH / 2; - if (this.sourceBlock_.RTL) { - // X position starts at the left edge of the block, in both RTL and LTR. - // First offset by the width of the block to move to the right edge, - // and then subtract to move to the same position as LTR. - var minCenter = this.size_.width - minOffset; - centerTextX = Math.min(minCenter, centerTextX); - } else { - // (width / 2) should exceed Blockly.BlockSvg.FIELD_WIDTH / 2 - // if the text is longer. - centerTextX = Math.max(minOffset, centerTextX); - } - } - - // Apply new text element x position. - this.textElement_.setAttribute('x', centerTextX); - } - - // Update any drawn box to the correct width and height. - if (this.box_) { - this.box_.setAttribute('width', this.size_.width); - this.box_.setAttribute('height', this.size_.height); - } -}; - -/** - * Updates the width of the field. This calls getCachedWidth which won't cache - * the approximated width on IE/Edge when `getComputedTextLength` fails. Once - * it eventually does succeed, the result will be cached. - **/ -Blockly.Field.prototype.updateWidth = function() { - // Calculate width of field - var width = Blockly.Field.getCachedWidth(this.textElement_); - - // Add padding to left and right of text. - if (this.EDITABLE) { - width += Blockly.BlockSvg.EDITABLE_FIELD_PADDING; - } - - // Adjust width for drop-down arrows. - this.arrowWidth_ = 0; - if (this.positionArrow) { - this.arrowWidth_ = this.positionArrow(width); - width += this.arrowWidth_; - } - - // Add padding to any drawn box. - if (this.box_) { - width += 2 * Blockly.BlockSvg.BOX_FIELD_PADDING; - } - - // Set width of the field. - this.size_.width = width; -}; - -/** - * Gets the width of a text element, caching it in the process. - * @param {!Element} textElement An SVG 'text' element. - * @return {number} Width of element. - */ -Blockly.Field.getCachedWidth = function(textElement) { - var key = textElement.textContent + '\n' + textElement.className.baseVal; - var width; - - // Return the cached width if it exists. - if (Blockly.Field.cacheWidths_) { - width = Blockly.Field.cacheWidths_[key]; - if (width) { - return width; - } - } - - // Attempt to compute fetch the width of the SVG text element. - try { - if (goog.userAgent.IE || goog.userAgent.EDGE) { - width = textElement.getBBox().width; - } else { - width = textElement.getComputedTextLength(); - } - } catch (e) { - // In other cases where we fail to geth the computed text. Instead, use an - // approximation and do not cache the result. At some later point in time - // when the block is inserted into the visible DOM, this method will be - // called again and, at that point in time, will not throw an exception. - return textElement.textContent.length * 8; - } - - // Cache the computed width and return. - if (Blockly.Field.cacheWidths_) { - Blockly.Field.cacheWidths_[key] = width; - } - return width; -}; - -/** - * Start caching field widths. Every call to this function MUST also call - * stopCache. Caches must not survive between execution threads. - */ -Blockly.Field.startCache = function() { - Blockly.Field.cacheReference_++; - if (!Blockly.Field.cacheWidths_) { - Blockly.Field.cacheWidths_ = {}; - } -}; - -/** - * Stop caching field widths. Unless caching was already on when the - * corresponding call to startCache was made. - */ -Blockly.Field.stopCache = function() { - Blockly.Field.cacheReference_--; - if (!Blockly.Field.cacheReference_) { - Blockly.Field.cacheWidths_ = null; - } -}; - -/** - * Returns the height and width of the field. - * @return {!goog.math.Size} Height and width. - */ -Blockly.Field.prototype.getSize = function() { - if (!this.size_.width) { - this.render_(); - } - return this.size_; -}; - -/** - * Returns the bounding box of the rendered field, accounting for workspace - * scaling. - * @return {!Object} An object with top, bottom, left, and right in pixels - * relative to the top left corner of the page (window coordinates). - * @private - */ -Blockly.Field.prototype.getScaledBBox_ = function() { - var size = this.getSize(); - var scaledHeight = size.height * this.sourceBlock_.workspace.scale; - var scaledWidth = size.width * this.sourceBlock_.workspace.scale; - var xy = this.getAbsoluteXY_(); - return { - top: xy.y, - bottom: xy.y + scaledHeight, - left: xy.x, - right: xy.x + scaledWidth - }; -}; - -/** - * Get the text from this field as displayed on screen. May differ from getText - * due to ellipsis, and other formatting. - * @return {string} Currently displayed text. - * @private - */ -Blockly.Field.prototype.getDisplayText_ = function() { - var text = this.text_; - if (!text) { - // Prevent the field from disappearing if empty. - return Blockly.Field.NBSP; - } - if (text.length > this.maxDisplayLength) { - // Truncate displayed string and add an ellipsis ('...'). - text = text.substring(0, this.maxDisplayLength - 2) + '\u2026'; - } - // Replace whitespace with non-breaking spaces so the text doesn't collapse. - text = text.replace(/\s/g, Blockly.Field.NBSP); - if (this.sourceBlock_.RTL) { - // The SVG is LTR, force text to be RTL unless a number. - if (this.sourceBlock_.editable_ && this.sourceBlock_.type === 'math_number') { - text = '\u202A' + text + '\u202C'; - } else { - text = '\u202B' + text + '\u202C'; - } - } - return text; -}; - -/** - * Get the text from this field. - * @return {string} Current text. - */ -Blockly.Field.prototype.getText = function() { - return this.text_; -}; - -/** - * Set the text in this field. Trigger a rerender of the source block. - * @param {*} newText New text. - */ -Blockly.Field.prototype.setText = function(newText) { - if (newText === null) { - // No change if null. - return; - } - newText = String(newText); - if (newText === this.text_) { - // No change. - return; - } - this.text_ = newText; - this.forceRerender(); -}; - -/** - * Force a rerender of the block that this field is installed on, which will - * rerender this field and adjust for any sizing changes. - * Other fields on the same block will not rerender, because their sizes have - * already been recorded. - * @package - */ -Blockly.Field.prototype.forceRerender = function() { - // Set width to 0 to force a rerender of this field. - this.size_.width = 0; - - if (this.sourceBlock_ && this.sourceBlock_.rendered) { - this.sourceBlock_.render(); - this.sourceBlock_.bumpNeighbours_(); - } -}; - -/** - * Update the text node of this field to display the current text. - * @private - */ -Blockly.Field.prototype.updateTextNode_ = function() { - if (!this.textElement_) { - // Not rendered yet. - return; - } - var text = this.text_; - if (text.length > this.maxDisplayLength) { - // Truncate displayed string and add an ellipsis ('...'). - text = text.substring(0, this.maxDisplayLength - 2) + '\u2026'; - // Add special class for sizing font when truncated - this.textElement_.setAttribute('class', this.className_ + ' blocklyTextTruncated'); - } else { - this.textElement_.setAttribute('class', this.className_); - } - // Empty the text element. - goog.dom.removeChildren(/** @type {!Element} */ (this.textElement_)); - // Replace whitespace with non-breaking spaces so the text doesn't collapse. - text = text.replace(/\s/g, Blockly.Field.NBSP); - if (this.sourceBlock_.RTL && text) { - // The SVG is LTR, force text to be RTL. - if (this.sourceBlock_.editable_ && this.sourceBlock_.type === 'math_number') { - text = '\u202A' + text + '\u202C'; - } else { - text = '\u202B' + text + '\u202C'; - } - } - if (!text) { - // Prevent the field from disappearing if empty. - text = Blockly.Field.NBSP; - } - var textNode = document.createTextNode(text); - this.textElement_.appendChild(textNode); - - // Cached width is obsolete. Clear it. - this.size_.width = 0; -}; - -/** - * By default there is no difference between the human-readable text and - * the language-neutral values. Subclasses (such as dropdown) may define this. - * @return {string} Current value. - */ -Blockly.Field.prototype.getValue = function() { - return this.getText(); -}; - -/** - * By default there is no difference between the human-readable text and - * the language-neutral values. Subclasses (such as dropdown) may define this. - * @param {string} newValue New value. - */ -Blockly.Field.prototype.setValue = function(newValue) { - if (newValue === null) { - // No change if null. - return; - } - var oldValue = this.getValue(); - if (oldValue == newValue) { - return; - } - if (this.sourceBlock_ && Blockly.Events.isEnabled()) { - Blockly.Events.fire(new Blockly.Events.BlockChange( - this.sourceBlock_, 'field', this.name, oldValue, newValue)); - } - this.setText(newValue); -}; - -/** - * Handle a mouse down event on a field. - * @param {!Event} e Mouse down event. - * @private - */ -Blockly.Field.prototype.onMouseDown_ = function(e) { - if (!this.sourceBlock_ || !this.sourceBlock_.workspace) { - return; - } - var gesture = this.sourceBlock_.workspace.getGesture(e); - if (gesture) { - gesture.setStartField(this); - } - this.useTouchInteraction_ = Blockly.Touch.getTouchIdentifierFromEvent(event) !== 'mouse'; -}; - -/** - * Change the tooltip text for this field. - * @param {string|!Element} _newTip Text for tooltip or a parent element to - * link to for its tooltip. - * @abstract - */ -Blockly.Field.prototype.setTooltip = function(_newTip) { - // Non-abstract sub-classes may wish to implement this. See FieldLabel. -}; - -/** - * Select the element to bind the click handler to. When this element is - * clicked on an editable field, the editor will open. - * - * If the block has only one field and no output connection, we handle clicks - * over the whole block. Otherwise, handle clicks over the the group containing - * the field. - * - * @return {!Element} Element to bind click handler to. - * @private - */ -Blockly.Field.prototype.getClickTarget_ = function() { - var nFields = 0; - - for (var i = 0, input; input = this.sourceBlock_.inputList[i]; i++) { - nFields += input.fieldRow.length; - } - if (nFields <= 1 && this.sourceBlock_.outputConnection) { - return this.sourceBlock_.getSvgRoot(); - } else { - return this.getSvgRoot(); - } -}; - -/** - * Return the absolute coordinates of the top-left corner of this field. - * The origin (0,0) is the top-left corner of the page body. - * @return {!goog.math.Coordinate} Object with .x and .y properties. - * @private - */ -Blockly.Field.prototype.getAbsoluteXY_ = function() { - return goog.style.getPageOffset(this.getClickTarget_()); -}; - -/** - * Whether this field references any Blockly variables. If true it may need to - * be handled differently during serialization and deserialization. Subclasses - * may override this. - * @return {boolean} True if this field has any variable references. - * @package - */ -Blockly.Field.prototype.referencesVariables = function() { - return false; -}; diff --git a/core/field_checkbox.js b/core/field_checkbox.js deleted file mode 100644 index a20b4b16aa..0000000000 --- a/core/field_checkbox.js +++ /dev/null @@ -1,133 +0,0 @@ -/** - * @license - * Visual Blocks Editor - * - * Copyright 2012 Google Inc. - * https://developers.google.com/blockly/ - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @fileoverview Checkbox field. Checked or not checked. - * @author fraser@google.com (Neil Fraser) - */ -'use strict'; - -goog.provide('Blockly.FieldCheckbox'); - -goog.require('Blockly.Field'); - - -/** - * Class for a checkbox field. - * @param {string} state The initial state of the field ('TRUE' or 'FALSE'). - * @param {Function=} opt_validator A function that is executed when a new - * option is selected. Its sole argument is the new checkbox state. If - * it returns a value, this becomes the new checkbox state, unless the - * value is null, in which case the change is aborted. - * @extends {Blockly.Field} - * @constructor - */ -Blockly.FieldCheckbox = function(state, opt_validator) { - Blockly.FieldCheckbox.superClass_.constructor.call(this, '', opt_validator); - // Set the initial state. - this.setValue(state); - this.addArgType('checkbox'); -}; -goog.inherits(Blockly.FieldCheckbox, Blockly.Field); - -/** - * Construct a FieldCheckbox from a JSON arg object. - * @param {!Object} options A JSON object with options (checked). - * @returns {!Blockly.FieldCheckbox} The new field instance. - * @package - * @nocollapse - */ -Blockly.FieldCheckbox.fromJson = function(options) { - return new Blockly.FieldCheckbox(options['checked'] ? 'TRUE' : 'FALSE'); -}; - -/** - * Character for the checkmark. - */ -Blockly.FieldCheckbox.CHECK_CHAR = '\u2713'; - -/** - * Mouse cursor style when over the hotspot that initiates editability. - */ -Blockly.FieldCheckbox.prototype.CURSOR = 'default'; - -/** - * Install this checkbox on a block. - */ -Blockly.FieldCheckbox.prototype.init = function() { - if (this.fieldGroup_) { - // Checkbox has already been initialized once. - return; - } - Blockly.FieldCheckbox.superClass_.init.call(this); - // The checkbox doesn't use the inherited text element. - // Instead it uses a custom checkmark element that is either visible or not. - this.checkElement_ = Blockly.utils.createSvgElement('text', - {'class': 'blocklyText blocklyCheckbox', 'x': -3, 'y': 14}, - this.fieldGroup_); - var textNode = document.createTextNode(Blockly.FieldCheckbox.CHECK_CHAR); - this.checkElement_.appendChild(textNode); - this.checkElement_.style.display = this.state_ ? 'block' : 'none'; -}; - -/** - * Return 'TRUE' if the checkbox is checked, 'FALSE' otherwise. - * @return {string} Current state. - */ -Blockly.FieldCheckbox.prototype.getValue = function() { - return String(this.state_).toUpperCase(); -}; - -/** - * Set the checkbox to be checked if newBool is 'TRUE' or true, - * unchecks otherwise. - * @param {string|boolean} newBool New state. - */ -Blockly.FieldCheckbox.prototype.setValue = function(newBool) { - var newState = (typeof newBool == 'string') ? - (newBool.toUpperCase() == 'TRUE') : !!newBool; - if (this.state_ !== newState) { - if (this.sourceBlock_ && Blockly.Events.isEnabled()) { - Blockly.Events.fire(new Blockly.Events.BlockChange( - this.sourceBlock_, 'field', this.name, this.state_, newState)); - } - this.state_ = newState; - if (this.checkElement_) { - this.checkElement_.style.display = newState ? 'block' : 'none'; - } - } -}; - -/** - * Toggle the state of the checkbox. - * @private - */ -Blockly.FieldCheckbox.prototype.showEditor_ = function() { - var newState = !this.state_; - if (this.sourceBlock_) { - // Call any validation function, and allow it to override. - newState = this.callValidator(newState); - } - if (newState !== null) { - this.setValue(String(newState).toUpperCase()); - } -}; - -Blockly.Field.register('field_checkbox', Blockly.FieldCheckbox); diff --git a/core/field_colour.js b/core/field_colour.js deleted file mode 100644 index 6dab2e42a3..0000000000 --- a/core/field_colour.js +++ /dev/null @@ -1,253 +0,0 @@ -/** - * @license - * Visual Blocks Editor - * - * Copyright 2012 Google Inc. - * https://developers.google.com/blockly/ - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @fileoverview Colour input field. - * @author fraser@google.com (Neil Fraser) - */ -'use strict'; - -goog.provide('Blockly.FieldColour'); - -goog.require('Blockly.Field'); -goog.require('Blockly.utils'); - -goog.require('goog.dom'); -goog.require('goog.events'); -goog.require('goog.style'); -goog.require('goog.ui.ColorPicker'); - - -/** - * Class for a colour input field. - * @param {string} colour The initial colour in '#rrggbb' format. - * @param {Function=} opt_validator A function that is executed when a new - * colour is selected. Its sole argument is the new colour value. Its - * return value becomes the selected colour, unless it is undefined, in - * which case the new colour stands, or it is null, in which case the change - * is aborted. - * @extends {Blockly.Field} - * @constructor - */ -Blockly.FieldColour = function(colour, opt_validator) { - Blockly.FieldColour.superClass_.constructor.call(this, colour, opt_validator); - this.addArgType('colour'); -}; -goog.inherits(Blockly.FieldColour, Blockly.Field); - -/** - * Construct a FieldColour from a JSON arg object. - * @param {!Object} options A JSON object with options (colour). - * @returns {!Blockly.FieldColour} The new field instance. - * @package - * @nocollapse - */ -Blockly.FieldColour.fromJson = function(options) { - return new Blockly.FieldColour(options['colour']); -}; - -/** - * By default use the global constants for colours. - * @type {Array.} - * @private - */ -Blockly.FieldColour.prototype.colours_ = null; - -/** - * By default use the global constants for columns. - * @type {number} - * @private - */ -Blockly.FieldColour.prototype.columns_ = 0; - -/** - * Install this field on a block. - * @param {!Blockly.Block} block The block containing this field. - */ -Blockly.FieldColour.prototype.init = function(block) { - if (this.fieldGroup_) { - // Colour field has already been initialized once. - return; - } - Blockly.FieldColour.superClass_.init.call(this, block); - this.setValue(this.getValue()); -}; - -/** - * Mouse cursor style when over the hotspot that initiates the editor. - */ -Blockly.FieldColour.prototype.CURSOR = 'default'; - -/** - * Close the colour picker if this input is being deleted. - */ -Blockly.FieldColour.prototype.dispose = function() { - Blockly.WidgetDiv.hideIfOwner(this); - Blockly.FieldColour.superClass_.dispose.call(this); -}; - -/** - * Return the current colour. - * @return {string} Current colour in '#rrggbb' format. - */ -Blockly.FieldColour.prototype.getValue = function() { - return this.colour_; -}; - -/** - * Set the colour. - * @param {string} colour The new colour in '#rrggbb' format. - */ -Blockly.FieldColour.prototype.setValue = function(colour) { - if (this.sourceBlock_ && Blockly.Events.isEnabled() && - this.colour_ != colour) { - Blockly.Events.fire(new Blockly.Events.BlockChange( - this.sourceBlock_, 'field', this.name, this.colour_, colour)); - } - this.colour_ = colour; - if (this.sourceBlock_) { - // Set the primary, secondary, tertiary, and quaternary colour to this value. - // The renderer expects to be able to use the secondary color as the fill for a shadow. - this.sourceBlock_.setColour(colour, colour, colour, colour); - } -}; - -/** - * Get the text from this field. Used when the block is collapsed. - * @return {string} Current text. - */ -Blockly.FieldColour.prototype.getText = function() { - var colour = this.colour_; - // Try to use #rgb format if possible, rather than #rrggbb. - var m = colour.match(/^#(.)\1(.)\2(.)\3$/); - if (m) { - colour = '#' + m[1] + m[2] + m[3]; - } - return colour; -}; - -/** - * Returns the fixed height and width. - * @return {!goog.math.Size} Height and width. - */ -Blockly.FieldColour.prototype.getSize = function() { - return new goog.math.Size(Blockly.BlockSvg.FIELD_WIDTH, Blockly.BlockSvg.FIELD_HEIGHT); -}; - -/** - * An array of colour strings for the palette. - * See bottom of this page for the default: - * http://docs.closure-library.googlecode.com/git/closure_goog_ui_colorpicker.js.source.html - * @type {!Array.} - */ -Blockly.FieldColour.COLOURS = goog.ui.ColorPicker.SIMPLE_GRID_COLORS; - -/** - * Number of columns in the palette. - */ -Blockly.FieldColour.COLUMNS = 7; - -/** - * Set a custom colour grid for this field. - * @param {Array.} colours Array of colours for this block, - * or null to use default (Blockly.FieldColour.COLOURS). - * @return {!Blockly.FieldColour} Returns itself (for method chaining). - */ -Blockly.FieldColour.prototype.setColours = function(colours) { - this.colours_ = colours; - return this; -}; - -/** - * Set a custom grid size for this field. - * @param {number} columns Number of columns for this block, - * or 0 to use default (Blockly.FieldColour.COLUMNS). - * @return {!Blockly.FieldColour} Returns itself (for method chaining). - */ -Blockly.FieldColour.prototype.setColumns = function(columns) { - this.columns_ = columns; - return this; -}; - -/** - * Create a palette under the colour field. - * @private - */ -Blockly.FieldColour.prototype.showEditor_ = function() { - Blockly.WidgetDiv.show(this, this.sourceBlock_.RTL, - Blockly.FieldColour.widgetDispose_); - - // Record viewport dimensions before adding the widget. - var viewportBBox = Blockly.utils.getViewportBBox(); - var anchorBBox = this.getScaledBBox_(); - - // Create and add the colour picker, then record the size. - var picker = this.createWidget_(); - var paletteSize = goog.style.getSize(picker.getElement()); - - // Position the picker to line up with the field. - Blockly.WidgetDiv.positionWithAnchor(viewportBBox, anchorBBox, paletteSize, - this.sourceBlock_.RTL); - - // Configure event handler. - var thisField = this; - Blockly.FieldColour.changeEventKey_ = goog.events.listen(picker, - goog.ui.ColorPicker.EventType.CHANGE, - function(event) { - var colour = event.target.getSelectedColor() || '#000000'; - Blockly.WidgetDiv.hide(); - if (thisField.sourceBlock_) { - // Call any validation function, and allow it to override. - colour = thisField.callValidator(colour); - } - if (colour !== null) { - thisField.setValue(colour); - } - }); -}; - -/** - * Create a color picker widget and render it inside the widget div. - * @return {!goog.ui.ColorPicker} The newly created color picker. - * @private - */ -Blockly.FieldColour.prototype.createWidget_ = function() { - // Create the palette using Closure. - var picker = new goog.ui.ColorPicker(); - picker.setSize(this.columns_ || Blockly.FieldColour.COLUMNS); - picker.setColors(this.colours_ || Blockly.FieldColour.COLOURS); - var div = Blockly.WidgetDiv.DIV; - picker.render(div); - picker.setSelectedColor(this.getValue()); - return picker; -}; - -/** - * Hide the colour palette. - * @private - */ -Blockly.FieldColour.widgetDispose_ = function() { - if (Blockly.FieldColour.changeEventKey_) { - goog.events.unlistenByKey(Blockly.FieldColour.changeEventKey_); - } - Blockly.Events.setGroup(false); -}; - -Blockly.Field.register('field_colour', Blockly.FieldColour); diff --git a/core/field_date.js b/core/field_date.js deleted file mode 100644 index 253cbb4b83..0000000000 --- a/core/field_date.js +++ /dev/null @@ -1,353 +0,0 @@ -/** - * @license - * Visual Blocks Editor - * - * Copyright 2015 Google Inc. - * https://developers.google.com/blockly/ - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @fileoverview Date input field. - * @author pkendall64@gmail.com (Paul Kendall) - */ -'use strict'; - -goog.provide('Blockly.FieldDate'); - -goog.require('Blockly.Field'); -goog.require('Blockly.utils'); - -goog.require('goog.date'); -goog.require('goog.date.DateTime'); -goog.require('goog.dom'); -goog.require('goog.events'); -goog.require('goog.i18n.DateTimeSymbols'); -goog.require('goog.i18n.DateTimeSymbols_he'); -goog.require('goog.style'); -goog.require('goog.ui.DatePicker'); - - -/** - * Class for a date input field. - * @param {string} date The initial date. - * @param {Function=} opt_validator A function that is executed when a new - * date is selected. Its sole argument is the new date value. Its - * return value becomes the selected date, unless it is undefined, in - * which case the new date stands, or it is null, in which case the change - * is aborted. - * @extends {Blockly.Field} - * @constructor - */ -Blockly.FieldDate = function(date, opt_validator) { - if (!date) { - date = new goog.date.Date().toIsoString(true); - } - Blockly.FieldDate.superClass_.constructor.call(this, date, opt_validator); - this.setValue(date); - this.addArgType('date'); -}; -goog.inherits(Blockly.FieldDate, Blockly.Field); - -/** - * Construct a FieldDate from a JSON arg object. - * @param {!Object} options A JSON object with options (date). - * @returns {!Blockly.FieldDate} The new field instance. - * @package - * @nocollapse - */ -Blockly.FieldDate.fromJson = function(options) { - return new Blockly.FieldDate(options['date']); -}; - -/** - * Mouse cursor style when over the hotspot that initiates the editor. - */ -Blockly.FieldDate.prototype.CURSOR = 'text'; - -/** - * Close the colour picker if this input is being deleted. - */ -Blockly.FieldDate.prototype.dispose = function() { - Blockly.WidgetDiv.hideIfOwner(this); - Blockly.FieldDate.superClass_.dispose.call(this); -}; - -/** - * Return the current date. - * @return {string} Current date. - */ -Blockly.FieldDate.prototype.getValue = function() { - return this.date_; -}; - -/** - * Set the date. - * @param {string} date The new date. - */ -Blockly.FieldDate.prototype.setValue = function(date) { - if (this.sourceBlock_) { - var validated = this.callValidator(date); - // If the new date is invalid, validation returns null. - // In this case we still want to display the illegal result. - if (validated !== null) { - date = validated; - } - } - this.date_ = date; - Blockly.Field.prototype.setText.call(this, date); -}; - -/** - * Create a date picker under the date field. - * @private - */ -Blockly.FieldDate.prototype.showEditor_ = function() { - Blockly.WidgetDiv.show(this, this.sourceBlock_.RTL, - Blockly.FieldDate.widgetDispose_); - - // Record viewport dimensions before adding the picker. - var viewportBBox = Blockly.utils.getViewportBBox(); - var anchorBBox = this.getScaledBBox_(); - - // Create and add the date picker, then record the size. - var picker = this.createWidget_(); - var pickerSize = goog.style.getSize(picker.getElement()); - - // Position the picker to line up with the field. - Blockly.WidgetDiv.positionWithAnchor(viewportBBox, anchorBBox, pickerSize, - this.sourceBlock_.RTL); - - // Configure event handler. - var thisField = this; - Blockly.FieldDate.changeEventKey_ = goog.events.listen(picker, - goog.ui.DatePicker.Events.CHANGE, - function(event) { - var date = event.date ? event.date.toIsoString(true) : ''; - Blockly.WidgetDiv.hide(); - if (thisField.sourceBlock_) { - // Call any validation function, and allow it to override. - date = thisField.callValidator(date); - } - thisField.setValue(date); - }); -}; - -/** - * Create a date picker widget and render it inside the widget div. - * @return {!goog.ui.DatePicker} The newly created date picker. - * @private - */ -Blockly.FieldDate.prototype.createWidget_ = function() { - // Create the date picker using Closure. - Blockly.FieldDate.loadLanguage_(); - var picker = new goog.ui.DatePicker(); - picker.setAllowNone(false); - picker.setShowWeekNum(false); - var div = Blockly.WidgetDiv.DIV; - picker.render(div); - picker.setDate(goog.date.DateTime.fromIsoString(this.getValue())); - return picker; -}; - -/** - * Hide the date picker. - * @private - */ -Blockly.FieldDate.widgetDispose_ = function() { - if (Blockly.FieldDate.changeEventKey_) { - goog.events.unlistenByKey(Blockly.FieldDate.changeEventKey_); - } - Blockly.Events.setGroup(false); -}; - -/** - * Load the best language pack by scanning the Blockly.Msg object for a - * language that matches the available languages in Closure. - * @private - */ -Blockly.FieldDate.loadLanguage_ = function() { - var reg = /^DateTimeSymbols_(.+)$/; - for (var prop in goog.i18n) { - var m = prop.match(reg); - if (m) { - var lang = m[1].toLowerCase().replace('_', '.'); // E.g. 'pt.br' - if (goog.getObjectByName(lang, Blockly.Msg)) { - goog.i18n.DateTimeSymbols = goog.i18n[prop]; - } - } - } -}; - -/** - * CSS for date picker. See css.js for use. - */ -Blockly.FieldDate.CSS = [ - /* Copied from: goog/css/datepicker.css */ - /** - * Copyright 2009 The Closure Library Authors. All Rights Reserved. - * - * Use of this source code is governed by the Apache License, Version 2.0. - * See the COPYING file for details. - */ - - /** - * Standard styling for a goog.ui.DatePicker. - * - * @author arv@google.com (Erik Arvidsson) - */ - - '.blocklyWidgetDiv .goog-date-picker,', - '.blocklyWidgetDiv .goog-date-picker th,', - '.blocklyWidgetDiv .goog-date-picker td {', - ' font: 13px Arial, sans-serif;', - '}', - - '.blocklyWidgetDiv .goog-date-picker {', - ' -moz-user-focus: normal;', - ' -moz-user-select: none;', - ' position: relative;', - ' border: 1px solid #000;', - ' float: left;', - ' padding: 2px;', - ' color: #000;', - ' background: #c3d9ff;', - ' cursor: default;', - '}', - - '.blocklyWidgetDiv .goog-date-picker th {', - ' text-align: center;', - '}', - - '.blocklyWidgetDiv .goog-date-picker td {', - ' text-align: center;', - ' vertical-align: middle;', - ' padding: 1px 3px;', - '}', - - '.blocklyWidgetDiv .goog-date-picker-menu {', - ' position: absolute;', - ' background: threedface;', - ' border: 1px solid gray;', - ' -moz-user-focus: normal;', - ' z-index: 1;', - ' outline: none;', - '}', - - '.blocklyWidgetDiv .goog-date-picker-menu ul {', - ' list-style: none;', - ' margin: 0px;', - ' padding: 0px;', - '}', - - '.blocklyWidgetDiv .goog-date-picker-menu ul li {', - ' cursor: default;', - '}', - - '.blocklyWidgetDiv .goog-date-picker-menu-selected {', - ' background: #ccf;', - '}', - - '.blocklyWidgetDiv .goog-date-picker th {', - ' font-size: .9em;', - '}', - - '.blocklyWidgetDiv .goog-date-picker td div {', - ' float: left;', - '}', - - '.blocklyWidgetDiv .goog-date-picker button {', - ' padding: 0px;', - ' margin: 1px 0;', - ' border: 0;', - ' color: #20c;', - ' font-weight: bold;', - ' background: transparent;', - '}', - - '.blocklyWidgetDiv .goog-date-picker-date {', - ' background: #fff;', - '}', - - '.blocklyWidgetDiv .goog-date-picker-week,', - '.blocklyWidgetDiv .goog-date-picker-wday {', - ' padding: 1px 3px;', - ' border: 0;', - ' border-color: #a2bbdd;', - ' border-style: solid;', - '}', - - '.blocklyWidgetDiv .goog-date-picker-week {', - ' border-right-width: 1px;', - '}', - - '.blocklyWidgetDiv .goog-date-picker-wday {', - ' border-bottom-width: 1px;', - '}', - - '.blocklyWidgetDiv .goog-date-picker-head td {', - ' text-align: center;', - '}', - - /** Use td.className instead of !important */ - '.blocklyWidgetDiv td.goog-date-picker-today-cont {', - ' text-align: center;', - '}', - - /** Use td.className instead of !important */ - '.blocklyWidgetDiv td.goog-date-picker-none-cont {', - ' text-align: center;', - '}', - - '.blocklyWidgetDiv .goog-date-picker-month {', - ' min-width: 11ex;', - ' white-space: nowrap;', - '}', - - '.blocklyWidgetDiv .goog-date-picker-year {', - ' min-width: 6ex;', - ' white-space: nowrap;', - '}', - - '.blocklyWidgetDiv .goog-date-picker-monthyear {', - ' white-space: nowrap;', - '}', - - '.blocklyWidgetDiv .goog-date-picker table {', - ' border-collapse: collapse;', - '}', - - '.blocklyWidgetDiv .goog-date-picker-other-month {', - ' color: #888;', - '}', - - '.blocklyWidgetDiv .goog-date-picker-wkend-start,', - '.blocklyWidgetDiv .goog-date-picker-wkend-end {', - ' background: #eee;', - '}', - - /** Use td.className instead of !important */ - '.blocklyWidgetDiv td.goog-date-picker-selected {', - ' background: #c3d9ff;', - '}', - - '.blocklyWidgetDiv .goog-date-picker-today {', - ' background: #9ab;', - ' font-weight: bold !important;', - ' border-color: #246 #9bd #9bd #246;', - ' color: #fff;', - '}' -]; - -Blockly.Field.register('field_date', Blockly.FieldDate); diff --git a/core/field_dropdown.js b/core/field_dropdown.js deleted file mode 100644 index 627fbf89e4..0000000000 --- a/core/field_dropdown.js +++ /dev/null @@ -1,483 +0,0 @@ -/** - * @license - * Visual Blocks Editor - * - * Copyright 2012 Google Inc. - * https://developers.google.com/blockly/ - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @fileoverview Dropdown input field. Used for editable titles and variables. - * In the interests of a consistent UI, the toolbox shares some functions and - * properties with the context menu. - * @author fraser@google.com (Neil Fraser) - */ -'use strict'; - -goog.provide('Blockly.FieldDropdown'); - -goog.require('Blockly.Field'); -goog.require('Blockly.DropDownDiv'); -goog.require('goog.dom'); -goog.require('goog.events'); -goog.require('goog.style'); -goog.require('goog.ui.Menu'); -goog.require('goog.ui.MenuItem'); -goog.require('goog.userAgent'); - - -/** - * Class for an editable dropdown field. - * @param {(!Array.|!Function)} menuGenerator An array of options - * for a dropdown list, or a function which generates these options. - * @param {Function=} opt_validator A function that is executed when a new - * option is selected, with the newly selected value as its sole argument. - * If it returns a value, that value (which must be one of the options) will - * become selected in place of the newly selected option, unless the return - * value is null, in which case the change is aborted. - * @extends {Blockly.Field} - * @constructor - */ -Blockly.FieldDropdown = function(menuGenerator, opt_validator) { - this.menuGenerator_ = menuGenerator; - this.trimOptions_(); - var firstTuple = this.getOptions()[0]; - - // Call parent's constructor. - Blockly.FieldDropdown.superClass_.constructor.call(this, firstTuple[1], - opt_validator); - this.addArgType('dropdown'); -}; -goog.inherits(Blockly.FieldDropdown, Blockly.Field); - -/** - * Construct a FieldDropdown from a JSON arg object. - * @param {!Object} element A JSON object with options. - * @returns {!Blockly.FieldDropdown} The new field instance. - * @package - * @nocollapse - */ -Blockly.FieldDropdown.fromJson = function(element) { - return new Blockly.FieldDropdown(element['options']); -}; - -/** - * Horizontal distance that a checkmark overhangs the dropdown. - */ -Blockly.FieldDropdown.CHECKMARK_OVERHANG = 25; - -/** - * Mouse cursor style when over the hotspot that initiates the editor. - */ -Blockly.FieldDropdown.prototype.CURSOR = 'default'; - -/** - * Closure menu item currently selected. - * @type {?goog.ui.MenuItem} - */ -Blockly.FieldDropdown.prototype.selectedItem = null; - -/** - * Language-neutral currently selected string or image object. - * @type {string|!Object} - * @private - */ -Blockly.FieldDropdown.prototype.value_ = ''; - -/** - * SVG image element if currently selected option is an image, or null. - * @type {SVGElement} - * @private - */ -Blockly.FieldDropdown.prototype.imageElement_ = null; - -/** - * Object with src, height, width, and alt attributes if currently selected - * option is an image, or null. - * @type {Object} - * @private - */ -Blockly.FieldDropdown.prototype.imageJson_ = null; - -/** - * Install this dropdown on a block. - */ -Blockly.FieldDropdown.prototype.init = function() { - if (this.fieldGroup_) { - // Dropdown has already been initialized once. - return; - } - // Add dropdown arrow: "option ▾" (LTR) or "▾ אופציה" (RTL) - // Positioned on render, after text size is calculated. - /** @type {Number} */ - this.arrowSize_ = 12; - /** @type {Number} */ - this.arrowX_ = 0; - /** @type {Number} */ - this.arrowY_ = 11; - this.arrow_ = Blockly.utils.createSvgElement('image', { - 'height': this.arrowSize_ + 'px', - 'width': this.arrowSize_ + 'px' - }); - this.arrow_.setAttributeNS('http://www.w3.org/1999/xlink', - 'xlink:href', Blockly.mainWorkspace.options.pathToMedia + 'dropdown-arrow.svg'); - this.className_ += ' blocklyDropdownText'; - - Blockly.FieldDropdown.superClass_.init.call(this); - // If not in a shadow block, draw a box. - if (!this.sourceBlock_.isShadow()) { - this.box_ = Blockly.utils.createSvgElement('rect', { - 'rx': Blockly.BlockSvg.CORNER_RADIUS, - 'ry': Blockly.BlockSvg.CORNER_RADIUS, - 'x': 0, - 'y': 0, - 'width': this.size_.width, - 'height': this.size_.height, - 'stroke': this.sourceBlock_.getColourTertiary(), - 'fill': this.sourceBlock_.getColour(), - 'class': 'blocklyBlockBackground', - 'fill-opacity': 1 - }, null); - this.fieldGroup_.insertBefore(this.box_, this.textElement_); - } - // Force a reset of the text to add the arrow. - var text = this.text_; - this.text_ = null; - this.setText(text); -}; - -/** - * Create a dropdown menu under the text. - * @private - */ -Blockly.FieldDropdown.prototype.showEditor_ = function() { - var options = this.getOptions(); - if (options.length == 0) return; - - this.dropDownOpen_ = true; - // If there is an existing drop-down someone else owns, hide it immediately and clear it. - Blockly.DropDownDiv.hideWithoutAnimation(); - Blockly.DropDownDiv.clearContent(); - - var contentDiv = Blockly.DropDownDiv.getContentDiv(); - - var thisField = this; - - function callback(e) { - var menu = this; - var menuItem = e.target; - if (menuItem) { - thisField.onItemSelected(menu, menuItem); - } - Blockly.DropDownDiv.hide(); - Blockly.Events.setGroup(false); - } - - var menu = new goog.ui.Menu(); - menu.setRightToLeft(this.sourceBlock_.RTL); - for (var i = 0; i < options.length; i++) { - var content = options[i][0]; // Human-readable text or image. - var value = options[i][1]; // Language-neutral value. - if (typeof content == 'object') { - // An image, not text. - var image = new Image(content['width'], content['height']); - image.src = content['src']; - image.alt = content['alt'] || ''; - content = image; - } - var menuItem = new goog.ui.MenuItem(content); - menuItem.setRightToLeft(this.sourceBlock_.RTL); - menuItem.setValue(value); - menuItem.setCheckable(true); - menu.addChild(menuItem, true); - var checked = (value == this.value_); - menuItem.setChecked(checked); - if (checked) { - this.selectedItem = menuItem; - } - } - // Listen for mouse/keyboard events. - goog.events.listen(menu, goog.ui.Component.EventType.ACTION, callback); - - // Record windowSize and scrollOffset before adding menu. - menu.render(contentDiv); - var menuDom = menu.getElement(); - Blockly.utils.addClass(menuDom, 'blocklyDropdownMenu'); - // Record menuSize after adding menu. - var menuSize = goog.style.getSize(menuDom); - // Recalculate height for the total content, not only box height. - menuSize.height = menuDom.scrollHeight; - - var primaryColour = (this.sourceBlock_.isShadow()) ? - this.sourceBlock_.parentBlock_.getColour() : this.sourceBlock_.getColour(); - - Blockly.DropDownDiv.setColour(primaryColour, this.sourceBlock_.getColourTertiary()); - - var category = (this.sourceBlock_.isShadow()) ? - this.sourceBlock_.parentBlock_.getCategory() : this.sourceBlock_.getCategory(); - Blockly.DropDownDiv.setCategory(category); - - // Calculate positioning based on the field position. - var scale = this.sourceBlock_.workspace.scale; - var bBox = {width: this.size_.width, height: this.size_.height}; - bBox.width *= scale; - bBox.height *= scale; - var position = this.fieldGroup_.getBoundingClientRect(); - var primaryX = position.left + bBox.width / 2; - var primaryY = position.top + bBox.height; - var secondaryX = primaryX; - var secondaryY = position.top; - // Set bounds to workspace; show the drop-down. - Blockly.DropDownDiv.setBoundsElement(this.sourceBlock_.workspace.getParentSvg().parentNode); - Blockly.DropDownDiv.show( - this, primaryX, primaryY, secondaryX, secondaryY, this.onHide.bind(this)); - - menu.setAllowAutoFocus(true); - menuDom.focus(); - - // Update colour to look selected. - if (!this.disableColourChange_) { - if (this.sourceBlock_.isShadow()) { - this.sourceBlock_.setShadowColour(this.sourceBlock_.getColourQuaternary()); - } else if (this.box_) { - this.box_.setAttribute('fill', this.sourceBlock_.getColourQuaternary()); - } - } -}; - -/** - * Callback for when the drop-down is hidden. - */ -Blockly.FieldDropdown.prototype.onHide = function() { - this.dropDownOpen_ = false; - // Update colour to look selected. - if (!this.disableColourChange_ && this.sourceBlock_) { - if (this.sourceBlock_.isShadow()) { - this.sourceBlock_.clearShadowColour(); - } else if (this.box_) { - this.box_.setAttribute('fill', this.sourceBlock_.getColour()); - } - } -}; - -/** - * Handle the selection of an item in the dropdown menu. - * @param {!goog.ui.Menu} menu The Menu component clicked. - * @param {!goog.ui.MenuItem} menuItem The MenuItem selected within menu. - */ -Blockly.FieldDropdown.prototype.onItemSelected = function(menu, menuItem) { - var value = menuItem.getValue(); - if (this.sourceBlock_) { - // Call any validation function, and allow it to override. - value = this.callValidator(value); - } - // If the value of the menu item is a function, call it and do not select it. - if (typeof value == 'function') { - value(); - return; - } - if (value !== null) { - this.setValue(value); - } -}; - -/** - * Factor out common words in statically defined options. - * Create prefix and/or suffix labels. - * @private - */ -Blockly.FieldDropdown.prototype.trimOptions_ = function() { - this.prefixField = null; - this.suffixField = null; - var options = this.menuGenerator_; - if (!goog.isArray(options)) { - return; - } - var hasImages = false; - - // Localize label text and image alt text. - for (var i = 0; i < options.length; i++) { - var label = options[i][0]; - if (typeof label == 'string') { - options[i][0] = Blockly.utils.replaceMessageReferences(label); - } else { - if (label.alt != null) { - options[i][0].alt = Blockly.utils.replaceMessageReferences(label.alt); - } - hasImages = true; - } - } - if (hasImages || options.length < 2) { - return; // Do nothing if too few items or at least one label is an image. - } - var strings = []; - for (var i = 0; i < options.length; i++) { - strings.push(options[i][0]); - } - var shortest = Blockly.utils.shortestStringLength(strings); - var prefixLength = Blockly.utils.commonWordPrefix(strings, shortest); - var suffixLength = Blockly.utils.commonWordSuffix(strings, shortest); - if (!prefixLength && !suffixLength) { - return; - } - if (shortest <= prefixLength + suffixLength) { - // One or more strings will entirely vanish if we proceed. Abort. - return; - } - if (prefixLength) { - this.prefixField = strings[0].substring(0, prefixLength - 1); - } - if (suffixLength) { - this.suffixField = strings[0].substr(1 - suffixLength); - } - // Remove the prefix and suffix from the options. - var newOptions = []; - for (var i = 0; i < options.length; i++) { - var text = options[i][0]; - var value = options[i][1]; - text = text.substring(prefixLength, text.length - suffixLength); - newOptions[i] = [text, value]; - } - this.menuGenerator_ = newOptions; -}; - -/** - * @return {boolean} True if the option list is generated by a function. - * Otherwise false. - */ -Blockly.FieldDropdown.prototype.isOptionListDynamic = function() { - return goog.isFunction(this.menuGenerator_); -}; - -/** - * Return a list of the options for this dropdown. - * @return {!Array.} Array of option tuples: - * (human-readable text or image, language-neutral name). - */ -Blockly.FieldDropdown.prototype.getOptions = function() { - if (goog.isFunction(this.menuGenerator_)) { - return this.menuGenerator_.call(this); - } - return /** @type {!Array.>} */ (this.menuGenerator_); -}; - -/** - * Get the language-neutral value from this dropdown menu. - * @return {string} Current text. - */ -Blockly.FieldDropdown.prototype.getValue = function() { - return this.value_; -}; - -/** - * Set the language-neutral value for this dropdown menu. - * @param {string} newValue New value to set. - */ -Blockly.FieldDropdown.prototype.setValue = function(newValue) { - if (newValue === null || newValue === this.value_) { - return; // No change if null. - } - if (this.sourceBlock_ && Blockly.Events.isEnabled()) { - Blockly.Events.fire(new Blockly.Events.BlockChange( - this.sourceBlock_, 'field', this.name, this.value_, newValue)); - } - // Clear menu item for old value. - if (this.selectedItem) { - this.selectedItem.setChecked(false); - this.selectedItem = null; - } - this.value_ = newValue; - // Look up and display the human-readable text. - var options = this.getOptions(); - for (var i = 0; i < options.length; i++) { - // Options are tuples of human-readable text and language-neutral values. - if (options[i][1] == newValue) { - var content = options[i][0]; - if (typeof content == 'object') { - this.imageJson_ = content; - this.text_ = content.alt; - } else { - this.imageJson_ = null; - this.text_ = content; - } - // Always rerender if either the value or the text has changed. - this.forceRerender(); - return; - } - } - // Value not found. Add it, maybe it will become valid once set - // (like variable names). - this.text_ = newValue; - this.forceRerender(); -}; - -/** - * Sets the text in this field. Trigger a rerender of the source block. - * @param {?string} text New text. - */ -Blockly.FieldDropdown.prototype.setText = function(text) { - if (text === null || text === this.text_) { - // No change if null. - return; - } - this.text_ = text; - this.updateTextNode_(); - - if (this.textElement_) { - this.textElement_.parentNode.appendChild(this.arrow_); - } - if (this.sourceBlock_ && this.sourceBlock_.rendered) { - this.sourceBlock_.render(); - this.sourceBlock_.bumpNeighbours_(); - } -}; - -/** - * Position a drop-down arrow at the appropriate location at render-time. - * @param {number} x X position the arrow is being rendered at, in px. - * @return {number} Amount of space the arrow is taking up, in px. - */ -Blockly.FieldDropdown.prototype.positionArrow = function(x) { - if (!this.arrow_) { - return 0; - } - - var addedWidth = 0; - if (this.sourceBlock_.RTL) { - this.arrowX_ = this.arrowSize_ - Blockly.BlockSvg.DROPDOWN_ARROW_PADDING; - addedWidth = this.arrowSize_ + Blockly.BlockSvg.DROPDOWN_ARROW_PADDING; - } else { - this.arrowX_ = x + Blockly.BlockSvg.DROPDOWN_ARROW_PADDING / 2; - addedWidth = this.arrowSize_ + Blockly.BlockSvg.DROPDOWN_ARROW_PADDING; - } - if (this.box_) { - // Bump positioning to the right for a box-type drop-down. - this.arrowX_ += Blockly.BlockSvg.BOX_FIELD_PADDING; - } - this.arrow_.setAttribute('transform', - 'translate(' + this.arrowX_ + ',' + this.arrowY_ + ')'); - return addedWidth; -}; - -/** - * Close the dropdown menu if this input is being deleted. - */ -Blockly.FieldDropdown.prototype.dispose = function() { - this.selectedItem = null; - Blockly.WidgetDiv.hideIfOwner(this); - Blockly.FieldDropdown.superClass_.dispose.call(this); -}; - -Blockly.Field.register('field_dropdown', Blockly.FieldDropdown); diff --git a/core/field_iconmenu.js b/core/field_iconmenu.js deleted file mode 100644 index f5d2a83b55..0000000000 --- a/core/field_iconmenu.js +++ /dev/null @@ -1,309 +0,0 @@ -/** - * @license - * Visual Blocks Editor - * - * Copyright 2016 Massachusetts Institute of Technology - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @fileoverview Icon picker input field. - * This is primarily for use in Scratch Horizontal blocks. - * Pops open a drop-down with icons; when an icon is selected, it replaces - * the icon (image field) in the original block. - * @author tmickel@mit.edu (Tim Mickel) - */ -'use strict'; - -goog.provide('Blockly.FieldIconMenu'); - -goog.require('Blockly.DropDownDiv'); - -/** - * Class for an icon menu field. - * @param {Object} icons List of icons. These take the same options as an Image Field. - * @extends {Blockly.Field} - * @constructor - */ -Blockly.FieldIconMenu = function(icons) { - /** @type {object} */ - this.icons_ = icons; - // Example: - // [{src: '...', width: 20, height: 20, alt: '...', value: 'machine_value'}, ...] - // First icon provides the default values. - var defaultValue = icons[0].value; - Blockly.FieldIconMenu.superClass_.constructor.call(this, defaultValue); - this.addArgType('iconmenu'); -}; -goog.inherits(Blockly.FieldIconMenu, Blockly.Field); - -/** - * Construct a FieldIconMenu from a JSON arg object. - * @param {!Object} element A JSON object with options. - * @returns {!Blockly.FieldIconMenu} The new field instance. - * @package - * @nocollapse - */ -Blockly.FieldIconMenu.fromJson = function(element) { - return new Blockly.FieldIconMenu(element['options']); -}; - -/** - * Fixed width of the drop-down, in px. Icon buttons will flow inside this width. - * @type {number} - * @const - */ -Blockly.FieldIconMenu.DROPDOWN_WIDTH = 168; - -/** - * Save the primary colour of the source block while the menu is open, for reset. - * @type {number|string} - * @private - */ -Blockly.FieldIconMenu.savedPrimary_ = null; - -/** - * Called when the field is placed on a block. - * @param {Block} block The owning block. - */ -Blockly.FieldIconMenu.prototype.init = function(block) { - if (this.fieldGroup_) { - // Icon menu has already been initialized once. - return; - } - // Render the arrow icon - // Fixed sizes in px. Saved for creating the flip transform of the menu renders above the button. - var arrowSize = 12; - /** @type {Number} */ - this.arrowX_ = 18; - /** @type {Number} */ - this.arrowY_ = 10; - if (block.RTL) { - // In RTL, the icon position is flipped and rendered from the right (offset by width) - this.arrowX_ = -this.arrowX_ - arrowSize; - } - /** @type {Element} */ - this.arrowIcon_ = Blockly.utils.createSvgElement('image', { - 'height': arrowSize + 'px', - 'width': arrowSize + 'px', - 'transform': 'translate(' + this.arrowX_ + ',' + this.arrowY_ + ')' - }); - this.arrowIcon_.setAttributeNS('http://www.w3.org/1999/xlink', - 'xlink:href', Blockly.mainWorkspace.options.pathToMedia + 'dropdown-arrow.svg'); - block.getSvgRoot().appendChild(this.arrowIcon_); - Blockly.FieldIconMenu.superClass_.init.call(this, block); -}; - -/** - * Mouse cursor style when over the hotspot that initiates the editor. - * @const - */ -Blockly.FieldIconMenu.prototype.CURSOR = 'default'; - -/** -* Set the language-neutral value for this icon drop-down menu. - * @param {?string} newValue New value. - * @override - */ -Blockly.FieldIconMenu.prototype.setValue = function(newValue) { - if (newValue === null || newValue === this.value_) { - return; // No change - } - if (this.sourceBlock_ && Blockly.Events.isEnabled()) { - Blockly.Events.fire(new Blockly.Events.Change( - this.sourceBlock_, 'field', this.name, this.value_, newValue)); - } - this.value_ = newValue; - // Find the relevant icon in this.icons_ to get the image src. - this.setParentFieldImage(this.getSrcForValue(this.value_)); -}; - -/** -* Find the parent block's FieldImage and set its src. - * @param {?string} src New src for the parent block FieldImage. - * @private - */ -Blockly.FieldIconMenu.prototype.setParentFieldImage = function(src) { - // Only attempt if we have a set sourceBlock_ and parentBlock_ - // It's possible that this function could be called before - // a parent block is set; in that case, fail silently. - if (this.sourceBlock_ && this.sourceBlock_.parentBlock_) { - var parentBlock = this.sourceBlock_.parentBlock_; - // Loop through all inputs' fields to find the first FieldImage - for (var i = 0, input; input = parentBlock.inputList[i]; i++) { - for (var j = 0, field; field = input.fieldRow[j]; j++) { - if (field instanceof Blockly.FieldImage) { - // Src for a FieldImage is stored in its value. - field.setValue(src); - return; - } - } - } - } -}; - -/** - * Get the language-neutral value from this drop-down menu. - * @return {string} Current language-neutral value. - */ -Blockly.FieldIconMenu.prototype.getValue = function() { - return this.value_; -}; - -/** - * For a language-neutral value, get the src for the image that represents it. - * @param {string} value Language-neutral value to look up. - * @return {string} Src to image representing value - */ -Blockly.FieldIconMenu.prototype.getSrcForValue = function(value) { - for (var i = 0, icon; icon = this.icons_[i]; i++) { - if (icon.value === value) { - return icon.src; - } - } -}; - -/** - * Show the drop-down menu for editing this field. - * @private - */ -Blockly.FieldIconMenu.prototype.showEditor_ = function() { - // If there is an existing drop-down we own, this is a request to hide the drop-down. - if (Blockly.DropDownDiv.hideIfOwner(this)) { - return; - } - // If there is an existing drop-down someone else owns, hide it immediately and clear it. - Blockly.DropDownDiv.hideWithoutAnimation(); - Blockly.DropDownDiv.clearContent(); - // Populate the drop-down with the icons for this field. - var contentDiv = Blockly.DropDownDiv.getContentDiv(); - // Accessibility properties - contentDiv.setAttribute('role', 'menu'); - contentDiv.setAttribute('aria-haspopup', 'true'); - for (var i = 0, icon; icon = this.icons_[i]; i++) { - // Icons with the type property placeholder take up space but don't have any functionality - // Use for special-case layouts - if (icon.type == 'placeholder') { - var placeholder = document.createElement('span'); - placeholder.setAttribute('class', 'blocklyDropDownPlaceholder'); - placeholder.style.width = icon.width + 'px'; - placeholder.style.height = icon.height + 'px'; - contentDiv.appendChild(placeholder); - continue; - } - var button = document.createElement('button'); - button.setAttribute('id', ':' + i); // For aria-activedescendant - button.setAttribute('role', 'menuitem'); - button.setAttribute('class', 'blocklyDropDownButton'); - button.title = icon.alt; - button.style.width = icon.width + 'px'; - button.style.height = icon.height + 'px'; - var backgroundColor = this.sourceBlock_.getColour(); - if (icon.value == this.getValue()) { - // This icon is selected, show it in a different colour - backgroundColor = this.sourceBlock_.getColourTertiary(); - button.setAttribute('aria-selected', 'true'); - } - button.style.backgroundColor = backgroundColor; - button.style.borderColor = this.sourceBlock_.getColourTertiary(); - Blockly.bindEvent_(button, 'click', this, this.buttonClick_); - Blockly.bindEvent_(button, 'mouseup', this, this.buttonClick_); - // These are applied manually instead of using the :hover pseudoclass - // because Android has a bad long press "helper" menu and green highlight - // that we must prevent with ontouchstart preventDefault - Blockly.bindEvent_(button, 'mousedown', button, function(e) { - this.setAttribute('class', 'blocklyDropDownButton blocklyDropDownButtonHover'); - e.preventDefault(); - }); - Blockly.bindEvent_(button, 'mouseover', button, function() { - this.setAttribute('class', 'blocklyDropDownButton blocklyDropDownButtonHover'); - contentDiv.setAttribute('aria-activedescendant', this.id); - }); - Blockly.bindEvent_(button, 'mouseout', button, function() { - this.setAttribute('class', 'blocklyDropDownButton'); - contentDiv.removeAttribute('aria-activedescendant'); - }); - var buttonImg = document.createElement('img'); - buttonImg.src = icon.src; - //buttonImg.alt = icon.alt; - // Upon click/touch, we will be able to get the clicked element as e.target - // Store a data attribute on all possible click targets so we can match it to the icon. - button.setAttribute('data-value', icon.value); - buttonImg.setAttribute('data-value', icon.value); - button.appendChild(buttonImg); - contentDiv.appendChild(button); - } - contentDiv.style.width = Blockly.FieldIconMenu.DROPDOWN_WIDTH + 'px'; - - Blockly.DropDownDiv.setColour(this.sourceBlock_.getColour(), this.sourceBlock_.getColourTertiary()); - Blockly.DropDownDiv.setCategory(this.sourceBlock_.parentBlock_.getCategory()); - - // Update source block colour to look selected - this.savedPrimary_ = this.sourceBlock_.getColour(); - this.sourceBlock_.setColour(this.sourceBlock_.getColourSecondary(), - this.sourceBlock_.getColourSecondary(), - this.sourceBlock_.getColourTertiary(), - this.sourceBlock_.getColourQuaternary()); - - var scale = this.sourceBlock_.workspace.scale; - // Offset for icon-type horizontal blocks. - var secondaryYOffset = ( - -(Blockly.BlockSvg.MIN_BLOCK_Y * scale) - (Blockly.BlockSvg.FIELD_Y_OFFSET * scale) - ); - var renderedPrimary = Blockly.DropDownDiv.showPositionedByBlock( - this, this.sourceBlock_, this.onHide_.bind(this), secondaryYOffset); - if (!renderedPrimary) { - // Adjust for rotation - var arrowX = this.arrowX_ + Blockly.DropDownDiv.ARROW_SIZE / 1.5 + 1; - var arrowY = this.arrowY_ + Blockly.DropDownDiv.ARROW_SIZE / 1.5; - // Flip the arrow on the button - this.arrowIcon_.setAttribute('transform', - 'translate(' + arrowX + ',' + arrowY + ') rotate(180)');} -}; - -/** - * Callback for when a button is clicked inside the drop-down. - * Should be bound to the FieldIconMenu. - * @param {Event} e DOM event for the click/touch - * @private - */ -Blockly.FieldIconMenu.prototype.buttonClick_ = function(e) { - var value = e.target.getAttribute('data-value'); - this.setValue(value); - Blockly.DropDownDiv.hide(); -}; - -/** - * Callback for when the drop-down is hidden. - */ -Blockly.FieldIconMenu.prototype.onHide_ = function() { - // Reset the button colour and clear accessibility properties - // Only attempt to do this reset if sourceBlock_ is not disposed. - // It could become disposed before an onHide_, for example, - // when a block is dragged from the flyout. - if (this.sourceBlock_) { - this.sourceBlock_.setColour(this.savedPrimary_, - this.sourceBlock_.getColourSecondary(), - this.sourceBlock_.getColourTertiary(), - this.sourceBlock_.getColourQuaternary()); - } - Blockly.DropDownDiv.content_.removeAttribute('role'); - Blockly.DropDownDiv.content_.removeAttribute('aria-haspopup'); - Blockly.DropDownDiv.content_.removeAttribute('aria-activedescendant'); - // Unflip the arrow if appropriate - this.arrowIcon_.setAttribute('transform', 'translate(' + this.arrowX_ + ',' + this.arrowY_ + ')'); -}; - -Blockly.Field.register('field_iconmenu', Blockly.FieldIconMenu); diff --git a/core/field_image.js b/core/field_image.js deleted file mode 100644 index 57fcf30eff..0000000000 --- a/core/field_image.js +++ /dev/null @@ -1,193 +0,0 @@ -/** - * @license - * Visual Blocks Editor - * - * Copyright 2012 Google Inc. - * https://developers.google.com/blockly/ - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @fileoverview Image field. Used for pictures, icons, etc. - * @author fraser@google.com (Neil Fraser) - */ -'use strict'; - -goog.provide('Blockly.FieldImage'); - -goog.require('Blockly.Field'); -goog.require('goog.dom'); -goog.require('goog.math.Size'); -goog.require('goog.userAgent'); - - -/** - * Class for an image on a block. - * @param {string} src The URL of the image. - * @param {number} width Width of the image. - * @param {number} height Height of the image. - * @param {string=} opt_alt Optional alt text for when block is collapsed. - * @param {boolean} flip_rtl Whether to flip the icon in RTL - * @extends {Blockly.Field} - * @constructor - */ -Blockly.FieldImage = function(src, width, height, opt_alt, flip_rtl) { - this.sourceBlock_ = null; - - // Ensure height and width are numbers. Strings are bad at math. - this.height_ = Number(height); - this.width_ = Number(width); - this.size_ = new goog.math.Size(this.width_, this.height_); - this.text_ = opt_alt || ''; - this.flipRTL_ = flip_rtl; - this.setValue(src); -}; -goog.inherits(Blockly.FieldImage, Blockly.Field); - -/** - * Construct a FieldImage from a JSON arg object, - * dereferencing any string table references. - * @param {!Object} options A JSON object with options (src, width, height, alt, - * and flipRtl/flip_rtl). - * @returns {!Blockly.FieldImage} The new field instance. - * @package - * @nocollapse - */ -Blockly.FieldImage.fromJson = function(options) { - var src = Blockly.utils.replaceMessageReferences(options['src']); - var width = Number(Blockly.utils.replaceMessageReferences(options['width'])); - var height = - Number(Blockly.utils.replaceMessageReferences(options['height'])); - var alt = Blockly.utils.replaceMessageReferences(options['alt']); - var flip_rtl = !!options['flip_rtl'] || !!options['flipRtl']; - return new Blockly.FieldImage(src, width, height, alt, flip_rtl); -}; - -/** - * Editable fields are saved by the XML renderer, non-editable fields are not. - */ -Blockly.FieldImage.prototype.EDITABLE = false; - -/** - * Install this image on a block. - */ -Blockly.FieldImage.prototype.init = function() { - if (this.fieldGroup_) { - // Image has already been initialized once. - return; - } - // Build the DOM. - /** @type {SVGElement} */ - this.fieldGroup_ = Blockly.utils.createSvgElement('g', {}, null); - if (!this.visible_) { - this.fieldGroup_.style.display = 'none'; - } - /** @type {SVGElement} */ - this.imageElement_ = Blockly.utils.createSvgElement( - 'image', - { - 'height': this.height_ + 'px', - 'width': this.width_ + 'px' - }, - this.fieldGroup_); - this.setValue(this.src_); - this.sourceBlock_.getSvgRoot().appendChild(this.fieldGroup_); - - // Configure the field to be transparent with respect to tooltips. - this.setTooltip(this.sourceBlock_); - Blockly.Tooltip.bindMouseEvents(this.imageElement_); -}; - -/** - * Dispose of all DOM objects belonging to this text. - */ -Blockly.FieldImage.prototype.dispose = function() { - goog.dom.removeNode(this.fieldGroup_); - this.fieldGroup_ = null; - this.imageElement_ = null; -}; - -/** - * Change the tooltip text for this field. - * @param {string|!Element} newTip Text for tooltip or a parent element to - * link to for its tooltip. - */ -Blockly.FieldImage.prototype.setTooltip = function(newTip) { - this.imageElement_.tooltip = newTip; -}; - -/** - * Get the source URL of this image. - * @return {string} Current text. - * @override - */ -Blockly.FieldImage.prototype.getValue = function() { - return this.src_; -}; - -/** - * Set the source URL of this image. - * @param {?string} src New source. - * @override - */ -Blockly.FieldImage.prototype.setValue = function(src) { - if (src === null) { - // No change if null. - return; - } - this.src_ = src; - if (this.imageElement_) { - this.imageElement_.setAttributeNS('http://www.w3.org/1999/xlink', - 'xlink:href', src || ''); - } -}; - -/** - * Get whether to flip this image in RTL - * @return {boolean} True if we should flip in RTL. - */ -Blockly.FieldImage.prototype.getFlipRTL = function() { - return this.flipRTL_; -}; - -/** - * Set the alt text of this image. - * @param {?string} alt New alt text. - * @override - */ -Blockly.FieldImage.prototype.setText = function(alt) { - if (alt === null) { - // No change if null. - return; - } - this.text_ = alt; -}; - -/** - * Images are fixed width, no need to render. - * @private - */ -Blockly.FieldImage.prototype.render_ = function() { - // NOP -}; - -/** - * Images are fixed width, no need to update. - * @private - */ -Blockly.FieldImage.prototype.updateWidth = function() { - // NOP -}; - -Blockly.Field.register('field_image', Blockly.FieldImage); diff --git a/core/field_label.js b/core/field_label.js deleted file mode 100644 index 1565b66368..0000000000 --- a/core/field_label.js +++ /dev/null @@ -1,136 +0,0 @@ -/** - * @license - * Visual Blocks Editor - * - * Copyright 2012 Google Inc. - * https://developers.google.com/blockly/ - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @fileoverview Non-editable text field. Used for titles, labels, etc. - * @author fraser@google.com (Neil Fraser) - */ -'use strict'; - -goog.provide('Blockly.FieldLabel'); - -goog.require('Blockly.Field'); -goog.require('Blockly.Tooltip'); -goog.require('goog.dom'); -goog.require('goog.math.Size'); -goog.require('goog.userAgent'); - - -/** - * Class for a non-editable field. - * @param {string} text The initial content of the field. - * @param {string=} opt_class Optional CSS class for the field's text. - * @extends {Blockly.Field} - * @constructor - */ -Blockly.FieldLabel = function(text, opt_class) { - this.size_ = new goog.math.Size(0, 0); - this.class_ = opt_class; - this.setValue(text); -}; -goog.inherits(Blockly.FieldLabel, Blockly.Field); - -/** - * Construct a FieldLabel from a JSON arg object, - * dereferencing any string table references. - * @param {!Object} options A JSON object with options (text, and class). - * @returns {!Blockly.FieldLabel} The new field instance. - * @package - * @nocollapse - */ -Blockly.FieldLabel.fromJson = function(options) { - var text = Blockly.utils.replaceMessageReferences(options['text']); - return new Blockly.FieldLabel(text, options['class']); -}; - -/** - * Editable fields usually show some sort of UI for the user to change them. - * @type {boolean} - * @public - */ -Blockly.FieldLabel.prototype.EDITABLE = false; - -/** - * Serializable fields are saved by the XML renderer, non-serializable fields - * are not. Editable fields should be serialized. - * @type {boolean} - * @public - */ -Blockly.FieldLabel.prototype.SERIALIZABLE = false; - -/** - * Install this text on a block. - */ -Blockly.FieldLabel.prototype.init = function() { - if (this.textElement_) { - // Text has already been initialized once. - return; - } - // Build the DOM. - this.textElement_ = Blockly.utils.createSvgElement('text', - { - 'class': 'blocklyText', - 'y': Blockly.BlockSvg.FIELD_TOP_PADDING, - 'text-anchor': 'middle', - 'dominant-baseline': 'middle', - 'dy': goog.userAgent.EDGE_OR_IE ? Blockly.Field.IE_TEXT_OFFSET : '0' - }, null); - if (this.class_) { - Blockly.utils.addClass(this.textElement_, this.class_); - } - if (!this.visible_) { - this.textElement_.style.display = 'none'; - } - this.sourceBlock_.getSvgRoot().appendChild(this.textElement_); - - // Configure the field to be transparent with respect to tooltips. - this.textElement_.tooltip = this.sourceBlock_; - Blockly.Tooltip.bindMouseEvents(this.textElement_); - // Force a render. - this.render_(); -}; - -/** - * Dispose of all DOM objects belonging to this text. - */ -Blockly.FieldLabel.prototype.dispose = function() { - goog.dom.removeNode(this.textElement_); - this.textElement_ = null; -}; - -/** - * Gets the group element for this field. - * Used for measuring the size and for positioning. - * @return {!Element} The group element. - */ -Blockly.FieldLabel.prototype.getSvgRoot = function() { - return /** @type {!Element} */ (this.textElement_); -}; - -/** - * Change the tooltip text for this field. - * @param {string|!Element} newTip Text for tooltip or a parent element to - * link to for its tooltip. - */ -Blockly.FieldLabel.prototype.setTooltip = function(newTip) { - this.textElement_.tooltip = newTip; -}; - -Blockly.Field.register('field_label', Blockly.FieldLabel); diff --git a/core/field_label_serializable.js b/core/field_label_serializable.js deleted file mode 100644 index 3b468fd80e..0000000000 --- a/core/field_label_serializable.js +++ /dev/null @@ -1,125 +0,0 @@ -/** - * @license - * Visual Blocks Editor - * - * Copyright 2017 Google Inc. - * https://developers.google.com/blockly/ - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @fileoverview Serialized label field. Behaves like a normal label but is - * always serialized to XML. It may only be edited programmatically. - * @author fenichel@google.com (Rachel Fenichel) - */ -'use strict'; - -goog.provide('Blockly.FieldLabelSerializable'); - -goog.require('Blockly.FieldLabel'); - - -/** - * Class for a variable getter field. - * @param {string} text The initial content of the field. - * @param {string} opt_class Optional CSS class for the field's text. - * @extends {Blockly.FieldLabel} - * @constructor - * - */ -Blockly.FieldLabelSerializable = function(text, opt_class) { - Blockly.FieldLabelSerializable.superClass_.constructor.call(this, text, - opt_class); - // Used in base field rendering, but we don't need it. - this.arrowWidth_ = 0; -}; -goog.inherits(Blockly.FieldLabelSerializable, Blockly.FieldLabel); - -/** - * Construct a FieldLabelSerializable from a JSON arg object, - * dereferencing any string table references. - * @param {!Object} options A JSON object with options (text, and class). - * @returns {!Blockly.FieldLabelSerializable} The new field instance. - * @package - * @nocollapse - */ -Blockly.FieldLabelSerializable.fromJson = function(options) { - var text = Blockly.utils.replaceMessageReferences(options['text']); - return new Blockly.FieldLabelSerializable(text, options['class']); -}; - -/** - * Editable fields usually show some sort of UI for the user to change them. - * This field should be serialized, but only edited programmatically. - * @type {boolean} - * @public - */ -Blockly.FieldLabelSerializable.prototype.EDITABLE = false; - -/** - * Serializable fields are saved by the XML renderer, non-serializable fields - * are not. This field should be serialized, but only edited programmatically. - * @type {boolean} - * @public - */ -Blockly.FieldLabelSerializable.prototype.SERIALIZABLE = true; - -/** - * Updates the width of the field. This calls getCachedWidth which won't cache - * the approximated width on IE/Edge when `getComputedTextLength` fails. Once - * it eventually does succeed, the result will be cached. - **/ -Blockly.FieldLabelSerializable.prototype.updateWidth = function() { - // Set width of the field. - // Unlike the base Field class, this doesn't add space to editable fields. - this.size_.width = Blockly.Field.getCachedWidth(this.textElement_); -}; - -/** - * Draws the border with the correct width. - * Saves the computed width in a property. - * @private - */ -Blockly.FieldLabelSerializable.prototype.render_ = function() { - if (this.visible_ && this.textElement_) { - // Replace the text. - goog.dom.removeChildren(/** @type {!Element} */ (this.textElement_)); - var textNode = document.createTextNode(this.getDisplayText_()); - this.textElement_.appendChild(textNode); - this.updateWidth(); - - // Update text centering, based on newly calculated width. - var centerTextX = this.size_.width / 2; - - // If half the text length is not at least center of - // visible field (FIELD_WIDTH), center it there instead. - var minOffset = Blockly.BlockSvg.FIELD_WIDTH / 2; - if (this.sourceBlock_.RTL) { - // X position starts at the left edge of the block, in both RTL and LTR. - // First offset by the width of the block to move to the right edge, - // and then subtract to move to the same position as LTR. - var minCenter = this.size_.width - minOffset; - centerTextX = Math.min(minCenter, centerTextX); - } else { - // (width / 2) should exceed Blockly.BlockSvg.FIELD_WIDTH / 2 - // if the text is longer. - centerTextX = Math.max(minOffset, centerTextX); - } - // Apply new text element x position. - this.textElement_.setAttribute('x', centerTextX); - } -}; - -Blockly.Field.register( - 'field_label_serializable', Blockly.FieldLabelSerializable); diff --git a/core/field_numberdropdown.js b/core/field_numberdropdown.js deleted file mode 100644 index 27f1c91c04..0000000000 --- a/core/field_numberdropdown.js +++ /dev/null @@ -1,77 +0,0 @@ -/** - * @license - * Visual Blocks Editor - * - * Copyright 2013 Google Inc. - * https://developers.google.com/blockly/ - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @fileoverview Combination number + drop-down field - * @author tmickel@mit.edu (Tim Mickel) - */ -'use strict'; - -goog.provide('Blockly.FieldNumberDropdown'); - -goog.require('Blockly.FieldTextDropdown'); -goog.require('goog.userAgent'); - - -/** - * Class for a combination number + drop-down field. - * @param {number|string} value The initial content of the field. - * @param {(!Array.>|!Function)} menuGenerator An array of - * options for a dropdown list, or a function which generates these options. - * @param {number|string|undefined} opt_min Minimum value. - * @param {number|string|undefined} opt_max Maximum value. - * @param {number|string|undefined} opt_precision Precision for value. - * @param {Function=} opt_validator An optional function that is called - * to validate any constraints on what the user entered. Takes the new - * text as an argument and returns the accepted text or null to abort - * the change. - * @extends {Blockly.FieldTextInput} - * @constructor - */ -Blockly.FieldNumberDropdown = function(value, menuGenerator, opt_min, opt_max, - opt_precision, opt_validator) { - this.setConstraints_ = Blockly.FieldNumber.prototype.setConstraints_; - - var numRestrictor = Blockly.FieldNumber.prototype.getNumRestrictor.call( - this, opt_min, opt_max, opt_precision - ); - Blockly.FieldNumberDropdown.superClass_.constructor.call( - this, value, menuGenerator, opt_validator, numRestrictor - ); - this.addArgType('numberdropdown'); -}; -goog.inherits(Blockly.FieldNumberDropdown, Blockly.FieldTextDropdown); - -/** - * Construct a FieldTextDropdown from a JSON arg object, - * dereferencing any string table references. - * @param {!Object} element A JSON object with options. - * @returns {!Blockly.FieldNumberDropdown} The new field instance. - * @package - * @nocollapse - */ -Blockly.FieldNumberDropdown.fromJson = function(element) { - return new Blockly.FieldNumberDropdown( - element['value'], element['options'], - element['min'], element['max'], element['precision'] - ); -}; - -Blockly.Field.register('field_numberdropdown', Blockly.FieldNumberDropdown); diff --git a/core/field_textdropdown.js b/core/field_textdropdown.js deleted file mode 100644 index 4e192a33f6..0000000000 --- a/core/field_textdropdown.js +++ /dev/null @@ -1,164 +0,0 @@ -/** - * @license - * Visual Blocks Editor - * - * Copyright 2013 Google Inc. - * https://developers.google.com/blockly/ - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @fileoverview Combination text + drop-down field - * @author tmickel@mit.edu (Tim Mickel) - */ -'use strict'; - -goog.provide('Blockly.FieldTextDropdown'); - -goog.require('Blockly.DropDownDiv'); -goog.require('Blockly.FieldDropdown'); -goog.require('Blockly.FieldTextInput'); -goog.require('goog.userAgent'); - - -/** - * Class for a combination text + drop-down field. - * @param {string} text The initial content of the text field. - * @param {(!Array.>|!Function)} menuGenerator An array of - * options for a dropdown list, or a function which generates these options. - * @param {Function=} opt_validator An optional function that is called - * to validate any constraints on what the user entered. Takes the new - * text as an argument and returns the accepted text or null to abort - * the change. - * @param {RegExp=} opt_restrictor An optional regular expression to restrict - * typed text to. Text that doesn't match the restrictor will never show - * in the text field. - * @extends {Blockly.FieldTextInput} - * @constructor - */ -Blockly.FieldTextDropdown = function(text, menuGenerator, opt_validator, opt_restrictor) { - this.menuGenerator_ = menuGenerator; - Blockly.FieldDropdown.prototype.trimOptions_.call(this); - Blockly.FieldTextDropdown.superClass_.constructor.call(this, text, opt_validator, opt_restrictor); - this.addArgType('textdropdown'); -}; -goog.inherits(Blockly.FieldTextDropdown, Blockly.FieldTextInput); - -/** - * Construct a FieldTextDropdown from a JSON arg object, - * dereferencing any string table references. - * @param {!Object} element A JSON object with options. - * @returns {!Blockly.FieldTextDropdown} The new field instance. - * @package - * @nocollapse - */ -Blockly.FieldTextDropdown.fromJson = function(element) { - var field = - new Blockly.FieldTextDropdown(element['text'], element['options']); - if (typeof element['spellcheck'] == 'boolean') { - field.setSpellcheck(element['spellcheck']); - } - return field; -}; - -/** - * Install this text drop-down field on a block. - */ -Blockly.FieldTextDropdown.prototype.init = function() { - if (this.fieldGroup_) { - // Text input + dropdown has already been initialized once. - return; - } - Blockly.FieldTextDropdown.superClass_.init.call(this); - // Add dropdown arrow: "option ▾" (LTR) or "▾ אופציה" (RTL) - // Positioned on render, after text size is calculated. - if (!this.arrow_) { - /** @type {Number} */ - this.arrowSize_ = 12; - /** @type {Number} */ - this.arrowX_ = 0; - /** @type {Number} */ - this.arrowY_ = 11; - this.arrow_ = Blockly.utils.createSvgElement('image', - { - 'height': this.arrowSize_ + 'px', - 'width': this.arrowSize_ + 'px' - }); - this.arrow_.setAttributeNS('http://www.w3.org/1999/xlink', - 'xlink:href', Blockly.mainWorkspace.options.pathToMedia + 'dropdown-arrow-dark.svg'); - this.arrow_.style.cursor = 'pointer'; - this.fieldGroup_.appendChild(this.arrow_); - this.mouseUpWrapper_ = - Blockly.bindEvent_(this.arrow_, 'mouseup', this, this.showDropdown_); - } - // Prevent the drop-down handler from changing the field colour on open. - this.disableColourChange_ = true; -}; - -/** - * Close the input widget if this input is being deleted. - */ -Blockly.FieldTextDropdown.prototype.dispose = function() { - if (this.mouseUpWrapper_) { - Blockly.unbindEvent_(this.mouseUpWrapper_); - this.mouseUpWrapper_ = null; - Blockly.Touch.clearTouchIdentifier(); - } - Blockly.FieldTextDropdown.superClass_.dispose.call(this); -}; - -/** - * If the drop-down isn't open, show the text editor. - */ -Blockly.FieldTextDropdown.prototype.showEditor_ = function() { - if (!this.dropDownOpen_) { - Blockly.FieldTextDropdown.superClass_.showEditor_.call(this, null, null, - true, function() { - // When the drop-down arrow is clicked, hide text editor and show drop-down. - Blockly.WidgetDiv.hide(); - this.showDropdown_(); - Blockly.Touch.clearTouchIdentifier(); - }); - } -}; - -/** - * Return a list of the options for this dropdown. - * See: Blockly.FieldDropDown.prototype.getOptions_. - * @return {!Array.>} Array of option tuples: - * (human-readable text, language-neutral name). - * @private - */ -Blockly.FieldTextDropdown.prototype.getOptions_ = Blockly.FieldDropdown.prototype.getOptions_; - -/** - * Position a drop-down arrow at the appropriate location at render-time. - * See: Blockly.FieldDropDown.prototype.positionArrow. - * @param {number} x X position the arrow is being rendered at, in px. - * @return {number} Amount of space the arrow is taking up, in px. - */ -Blockly.FieldTextDropdown.prototype.positionArrow = Blockly.FieldDropdown.prototype.positionArrow; - -/** - * Create the dropdown menu. - * @private - */ -Blockly.FieldTextDropdown.prototype.showDropdown_ = Blockly.FieldDropdown.prototype.showEditor_; - -/** - * Callback when the drop-down menu is hidden. - */ -Blockly.FieldTextDropdown.prototype.onHide = Blockly.FieldDropdown.prototype.onHide; - -Blockly.Field.register('field_textdropdown', Blockly.FieldTextDropdown); diff --git a/core/field_textinput.js b/core/field_textinput.js deleted file mode 100644 index 8ecf563024..0000000000 --- a/core/field_textinput.js +++ /dev/null @@ -1,675 +0,0 @@ -/** - * @license - * Visual Blocks Editor - * - * Copyright 2012 Google Inc. - * https://developers.google.com/blockly/ - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @fileoverview Text input field. - * @author fraser@google.com (Neil Fraser) - */ -'use strict'; - -goog.provide('Blockly.FieldTextInput'); - -goog.require('Blockly.BlockSvg.render'); -goog.require('Blockly.Colours'); -goog.require('Blockly.Field'); -goog.require('Blockly.Msg'); -goog.require('Blockly.scratchBlocksUtils'); -goog.require('Blockly.utils'); - -goog.require('goog.asserts'); -goog.require('goog.dom'); -goog.require('goog.dom.TagName'); -goog.require('goog.userAgent'); - - -/** - * Class for an editable text field. - * @param {string} text The initial content of the field. - * @param {Function=} opt_validator An optional function that is called - * to validate any constraints on what the user entered. Takes the new - * text as an argument and returns either the accepted text, a replacement - * text, or null to abort the change. - * @param {RegExp=} opt_restrictor An optional regular expression to restrict - * typed text to. Text that doesn't match the restrictor will never show - * in the text field. - * @extends {Blockly.Field} - * @constructor - */ -Blockly.FieldTextInput = function(text, opt_validator, opt_restrictor) { - Blockly.FieldTextInput.superClass_.constructor.call(this, text, - opt_validator); - this.setRestrictor(opt_restrictor); - this.addArgType('text'); -}; -goog.inherits(Blockly.FieldTextInput, Blockly.Field); - -/** - * Construct a FieldTextInput from a JSON arg object, - * dereferencing any string table references. - * @param {!Object} options A JSON object with options (text, class, and - * spellcheck). - * @returns {!Blockly.FieldTextInput} The new field instance. - * @package - * @nocollapse - */ -Blockly.FieldTextInput.fromJson = function(options) { - var text = Blockly.utils.replaceMessageReferences(options['text']); - var field = new Blockly.FieldTextInput(text, options['class']); - if (typeof options['spellcheck'] === 'boolean') { - field.setSpellcheck(options['spellcheck']); - } - return field; -}; - -/** - * Length of animations in seconds. - */ -Blockly.FieldTextInput.ANIMATION_TIME = 0.25; - -/** - * Padding to use for text measurement for the field during editing, in px. - */ -Blockly.FieldTextInput.TEXT_MEASURE_PADDING_MAGIC = 45; - -/** - * The HTML input element for the user to type, or null if no FieldTextInput - * editor is currently open. - * @type {HTMLInputElement} - * @private - */ -Blockly.FieldTextInput.htmlInput_ = null; - -/** - * Mouse cursor style when over the hotspot that initiates the editor. - */ -Blockly.FieldTextInput.prototype.CURSOR = 'text'; - -/** - * Allow browser to spellcheck this field. - * @private - */ -Blockly.FieldTextInput.prototype.spellcheck_ = true; - -/** - * Install this text field on a block. - */ -Blockly.FieldTextInput.prototype.init = function() { - if (this.fieldGroup_) { - // Field has already been initialized once. - return; - } - - var notInShadow = !this.sourceBlock_.isShadow(); - - if (notInShadow) { - this.className_ += ' blocklyEditableLabel'; - } - - Blockly.FieldTextInput.superClass_.init.call(this); - - // If not in a shadow block, draw a box. - if (notInShadow) { - this.box_ = Blockly.utils.createSvgElement('rect', - { - 'x': 0, - 'y': 0, - 'width': this.size_.width, - 'height': this.size_.height, - 'fill': this.sourceBlock_.getColourTertiary() - } - ); - this.fieldGroup_.insertBefore(this.box_, this.textElement_); - } -}; - -/** - * Close the input widget if this input is being deleted. - */ -Blockly.FieldTextInput.prototype.dispose = function() { - Blockly.WidgetDiv.hideIfOwner(this); - Blockly.FieldTextInput.superClass_.dispose.call(this); -}; - -/** - * Set the value of this field. - * @param {?string} newValue New value. - * @override - */ -Blockly.FieldTextInput.prototype.setValue = function(newValue) { - if (newValue === null) { - return; // No change if null. - } - if (this.sourceBlock_) { - var validated = this.callValidator(newValue); - // If the new value is invalid, validation returns null. - // In this case we still want to display the illegal result. - if (validated !== null) { - newValue = validated; - } - } - Blockly.Field.prototype.setValue.call(this, newValue); -}; - -/** - * Set the text in this field and fire a change event. - * @param {*} newText New text. - */ -Blockly.FieldTextInput.prototype.setText = function(newText) { - if (newText === null) { - // No change if null. - return; - } - newText = String(newText); - if (newText === this.text_) { - // No change. - return; - } - if (this.sourceBlock_ && Blockly.Events.isEnabled()) { - Blockly.Events.fire(new Blockly.Events.BlockChange( - this.sourceBlock_, 'field', this.name, this.text_, newText)); - } - Blockly.Field.prototype.setText.call(this, newText); -}; - -/** - * Set whether this field is spellchecked by the browser. - * @param {boolean} check True if checked. - */ -Blockly.FieldTextInput.prototype.setSpellcheck = function(check) { - this.spellcheck_ = check; -}; - -/** - * Set the restrictor regex for this text input. - * Text that doesn't match the restrictor will never show in the text field. - * @param {?RegExp} restrictor Regular expression to restrict text. - */ -Blockly.FieldTextInput.prototype.setRestrictor = function(restrictor) { - this.restrictor_ = restrictor; -}; - -/** - * Show the inline free-text editor on top of the text. - * @param {boolean=} opt_quietInput True if editor should be created without - * focus. Defaults to false. - * @param {boolean=} opt_readOnly True if editor should be created with HTML - * input set to read-only, to prevent virtual keyboards. - * @param {boolean=} opt_withArrow True to show drop-down arrow in text editor. - * @param {Function=} opt_arrowCallback Callback for when drop-down arrow clicked. - * @private - */ -Blockly.FieldTextInput.prototype.showEditor_ = function( - opt_quietInput, opt_readOnly, opt_withArrow, opt_arrowCallback) { - this.workspace_ = this.sourceBlock_.workspace; - var quietInput = opt_quietInput || false; - var readOnly = opt_readOnly || false; - Blockly.WidgetDiv.show(this, this.sourceBlock_.RTL, - this.widgetDispose_(), this.widgetDisposeAnimationFinished_(), - Blockly.FieldTextInput.ANIMATION_TIME); - var div = Blockly.WidgetDiv.DIV; - // Apply text-input-specific fixed CSS - div.className += ' fieldTextInput'; - // Create the input. - var htmlInput = - goog.dom.createDom(goog.dom.TagName.INPUT, 'blocklyHtmlInput'); - htmlInput.setAttribute('spellcheck', this.spellcheck_); - if (readOnly) { - htmlInput.setAttribute('readonly', 'true'); - } - /** @type {!HTMLInputElement} */ - Blockly.FieldTextInput.htmlInput_ = htmlInput; - div.appendChild(htmlInput); - - if (opt_withArrow) { - // Move text in input to account for displayed drop-down arrow. - if (this.sourceBlock_.RTL) { - htmlInput.style.paddingLeft = (this.arrowSize_ + Blockly.BlockSvg.DROPDOWN_ARROW_PADDING) + 'px'; - } else { - htmlInput.style.paddingRight = (this.arrowSize_ + Blockly.BlockSvg.DROPDOWN_ARROW_PADDING) + 'px'; - } - // Create the arrow. - var dropDownArrow = - goog.dom.createDom(goog.dom.TagName.IMG, 'blocklyTextDropDownArrow'); - dropDownArrow.setAttribute('src', - Blockly.mainWorkspace.options.pathToMedia + 'dropdown-arrow-dark.svg'); - dropDownArrow.style.width = this.arrowSize_ + 'px'; - dropDownArrow.style.height = this.arrowSize_ + 'px'; - dropDownArrow.style.top = this.arrowY_ + 'px'; - dropDownArrow.style.cursor = 'pointer'; - // Magic number for positioning the drop-down arrow on top of the text editor. - var dropdownArrowMagic = '11px'; - if (this.sourceBlock_.RTL) { - dropDownArrow.style.left = dropdownArrowMagic; - } else { - dropDownArrow.style.right = dropdownArrowMagic; - } - if (opt_arrowCallback) { - htmlInput.dropDownArrowMouseWrapper_ = Blockly.bindEvent_(dropDownArrow, - 'mousedown', this, opt_arrowCallback); - } - div.appendChild(dropDownArrow); - } - - htmlInput.value = htmlInput.defaultValue = this.text_; - htmlInput.oldValue_ = null; - this.validate_(); - this.resizeEditor_(); - if (!quietInput) { - htmlInput.focus(); - htmlInput.select(); - // For iOS only - htmlInput.setSelectionRange(0, 99999); - } - - this.bindEvents_(htmlInput, quietInput || readOnly); - - // Add animation transition properties - var transitionProperties = 'box-shadow ' + Blockly.FieldTextInput.ANIMATION_TIME + 's'; - if (Blockly.BlockSvg.FIELD_TEXTINPUT_ANIMATE_POSITIONING) { - div.style.transition += ',padding ' + Blockly.FieldTextInput.ANIMATION_TIME + 's,' + - 'width ' + Blockly.FieldTextInput.ANIMATION_TIME + 's,' + - 'height ' + Blockly.FieldTextInput.ANIMATION_TIME + 's,' + - 'margin-left ' + Blockly.FieldTextInput.ANIMATION_TIME + 's'; - } - div.style.transition = transitionProperties; - htmlInput.style.transition = 'font-size ' + Blockly.FieldTextInput.ANIMATION_TIME + 's'; - // The animated properties themselves - htmlInput.style.fontSize = Blockly.BlockSvg.FIELD_TEXTINPUT_FONTSIZE_FINAL + 'pt'; - div.style.boxShadow = '0px 0px 0px 4px ' + Blockly.Colours.fieldShadow; -}; - -/** - * Bind handlers for user input on this field and size changes on the workspace. - * @param {!HTMLInputElement} htmlInput The htmlInput created in showEditor, to - * which event handlers will be bound. - * @param {boolean} bindGlobalKeypress Whether to bind a keypress listener to enable - * keyboard editing without focusing the field. - * @private - */ -Blockly.FieldTextInput.prototype.bindEvents_ = function( - htmlInput, bindGlobalKeypress) { - // Bind to keydown -- trap Enter without IME and Esc to hide. - htmlInput.onKeyDownWrapper_ = - Blockly.bindEventWithChecks_(htmlInput, 'keydown', this, - this.onHtmlInputKeyDown_); - // Bind to keyup -- trap Enter; resize after every keystroke. - htmlInput.onKeyUpWrapper_ = - Blockly.bindEventWithChecks_(htmlInput, 'keyup', this, - this.onHtmlInputChange_); - // Bind to keyPress -- repeatedly resize when holding down a key. - htmlInput.onKeyPressWrapper_ = - Blockly.bindEventWithChecks_(htmlInput, 'keypress', this, - this.onHtmlInputChange_); - // For modern browsers (IE 9+, Chrome, Firefox, etc.) that support the - // DOM input event, also trigger onHtmlInputChange_ then. The input event - // is triggered on keypress but after the value of the text input - // has updated, allowing us to resize the block at that time. - htmlInput.onInputWrapper_ = - Blockly.bindEvent_(htmlInput, 'input', this, this.onHtmlInputChange_); - htmlInput.onWorkspaceChangeWrapper_ = this.resizeEditor_.bind(this); - this.workspace_.addChangeListener(htmlInput.onWorkspaceChangeWrapper_); - - if (bindGlobalKeypress) { - htmlInput.onDocumentKeyDownWrapper_ = - Blockly.bindEventWithChecks_(document, 'keydown', this, - this.onDocumentKeyDown_); - } -}; - -/** - * Unbind handlers for user input and workspace size changes. - * @param {!HTMLInputElement} htmlInput The html for this text input. - * @private - */ -Blockly.FieldTextInput.prototype.unbindEvents_ = function(htmlInput) { - Blockly.unbindEvent_(htmlInput.onKeyDownWrapper_); - Blockly.unbindEvent_(htmlInput.onKeyUpWrapper_); - Blockly.unbindEvent_(htmlInput.onKeyPressWrapper_); - Blockly.unbindEvent_(htmlInput.onInputWrapper_); - this.workspace_.removeChangeListener( - htmlInput.onWorkspaceChangeWrapper_); - - // Remove document handler only if it was added (e.g. in quiet mode) - if (htmlInput.onDocumentKeyDownWrapper_) { - Blockly.unbindEvent_(htmlInput.onDocumentKeyDownWrapper_); - } -}; - -/** - * Handle key down to the editor. - * @param {!Event} e Keyboard event. - * @private - */ -Blockly.FieldTextInput.prototype.onHtmlInputKeyDown_ = function(e) { - var htmlInput = Blockly.FieldTextInput.htmlInput_; - var tabKey = 9, enterKey = 13, escKey = 27; - if (e.keyCode == enterKey) { - Blockly.WidgetDiv.hide(); - Blockly.DropDownDiv.hideWithoutAnimation(); - } else if (e.keyCode == escKey) { - htmlInput.value = htmlInput.defaultValue; - Blockly.WidgetDiv.hide(); - Blockly.DropDownDiv.hideWithoutAnimation(); - } else if (e.keyCode == tabKey) { - Blockly.WidgetDiv.hide(); - Blockly.DropDownDiv.hideWithoutAnimation(); - this.sourceBlock_.tab(this, !e.shiftKey); - e.preventDefault(); - } -}; - -Blockly.FieldTextInput.prototype.onDocumentKeyDown_ = function(e) { - var htmlInput = Blockly.FieldTextInput.htmlInput_; - var targetMatches = e.target === htmlInput; - var targetIsInput = e.target.tagName === 'INPUT' || e.target.tagName === 'TEXTAREA'; - if (targetMatches || !targetIsInput) { // Ignore keys into other inputs - htmlInput.removeAttribute('readonly'); - htmlInput.value = ''; // Reset the input, new value is picked up by input keypress - htmlInput.focus(); - Blockly.unbindEvent_(htmlInput.onDocumentKeyDownWrapper_); - htmlInput.onDocumentKeyDownWrapper_ = null; - } -}; - -/** - * Key codes that are whitelisted from the restrictor. - * These are only needed and used on Gecko (Firefox). - * See: https://github.com/LLK/scratch-blocks/issues/503. - */ -Blockly.FieldTextInput.GECKO_KEYCODE_WHITELIST = [ - 97, // Select all, META-A. - 99, // Copy, META-C. - 118, // Paste, META-V. - 120 // Cut, META-X. -]; - -/** - * Handle a change to the editor. - * @param {!Event} e Keyboard event. - * @private - */ -Blockly.FieldTextInput.prototype.onHtmlInputChange_ = function(e) { - // Check if the key matches the restrictor. - if (e.type === 'keypress' && this.restrictor_) { - var keyCode; - var isWhitelisted = false; - if (goog.userAgent.GECKO) { - // e.keyCode is not available in Gecko. - keyCode = e.charCode; - // Gecko reports control characters (e.g., left, right, copy, paste) - // in the key event - whitelist these from being restricted. - // < 32 and 127 (delete) are control characters. - // See: http://www.theasciicode.com.ar/ascii-control-characters/delete-ascii-code-127.html - if (keyCode < 32 || keyCode == 127) { - isWhitelisted = true; - } else if (e.metaKey || e.ctrlKey) { - // For combos (ctrl-v, ctrl-c, etc.), Gecko reports the ASCII letter - // and the metaKey/ctrlKey flags. - isWhitelisted = Blockly.FieldTextInput.GECKO_KEYCODE_WHITELIST.indexOf(keyCode) > -1; - } - } else { - keyCode = e.keyCode; - } - var char = String.fromCharCode(keyCode); - if (!isWhitelisted && !this.restrictor_.test(char) && e.preventDefault) { - // Failed to pass restrictor. - e.preventDefault(); - return; - } - } - var htmlInput = Blockly.FieldTextInput.htmlInput_; - // Update source block. - var text = htmlInput.value; - if (text !== htmlInput.oldValue_) { - htmlInput.oldValue_ = text; - this.setText(text); - this.validate_(); - } else if (goog.userAgent.WEBKIT) { - // Cursor key. Render the source block to show the caret moving. - // Chrome only (version 26, OS X). - this.sourceBlock_.render(); - } - this.resizeEditor_(); -}; - -/** - * Check to see if the contents of the editor validates. - * Style the editor accordingly. - * @private - */ -Blockly.FieldTextInput.prototype.validate_ = function() { - var valid = true; - goog.asserts.assertObject(Blockly.FieldTextInput.htmlInput_); - var htmlInput = Blockly.FieldTextInput.htmlInput_; - if (this.sourceBlock_) { - valid = this.callValidator(htmlInput.value); - } - if (valid === null) { - Blockly.utils.addClass(htmlInput, 'blocklyInvalidInput'); - } else { - Blockly.utils.removeClass(htmlInput, 'blocklyInvalidInput'); - } -}; - -/** - * Resize the editor and the underlying block to fit the text. - * @private - */ -Blockly.FieldTextInput.prototype.resizeEditor_ = function() { - var scale = this.sourceBlock_.workspace.scale; - var div = Blockly.WidgetDiv.DIV; - - var initialWidth; - if (this.sourceBlock_.isShadow()) { - initialWidth = this.sourceBlock_.getHeightWidth().width * scale; - } else { - initialWidth = this.size_.width * scale; - } - - var width; - if (Blockly.BlockSvg.FIELD_TEXTINPUT_EXPAND_PAST_TRUNCATION) { - // Resize the box based on the measured width of the text, pre-truncation - var textWidth = Blockly.scratchBlocksUtils.measureText( - Blockly.FieldTextInput.htmlInput_.style.fontSize, - Blockly.FieldTextInput.htmlInput_.style.fontFamily, - Blockly.FieldTextInput.htmlInput_.style.fontWeight, - Blockly.FieldTextInput.htmlInput_.value - ); - // Size drawn in the canvas needs padding and scaling - textWidth += Blockly.FieldTextInput.TEXT_MEASURE_PADDING_MAGIC; - textWidth *= scale; - width = textWidth; - } else { - // Set width to (truncated) block size. - width = initialWidth; - } - // The width must be at least FIELD_WIDTH and at most FIELD_WIDTH_MAX_EDIT - width = Math.max(width, Blockly.BlockSvg.FIELD_WIDTH_MIN_EDIT * scale); - width = Math.min(width, Blockly.BlockSvg.FIELD_WIDTH_MAX_EDIT * scale); - // Add 1px to width and height to account for border (pre-scale) - div.style.width = (width / scale + 1) + 'px'; - div.style.height = (Blockly.BlockSvg.FIELD_HEIGHT_MAX_EDIT + 1) + 'px'; - div.style.transform = 'scale(' + scale + ')'; - - // Use margin-left to animate repositioning of the box (value is unscaled). - // This is the difference between the default position and the positioning - // after growing the box. - div.style.marginLeft = -0.5 * (width - initialWidth) + 'px'; - - // Add 0.5px to account for slight difference between SVG and CSS border - var borderRadius = this.getBorderRadius() + 0.5; - div.style.borderRadius = borderRadius + 'px'; - Blockly.FieldTextInput.htmlInput_.style.borderRadius = borderRadius + 'px'; - // Pull stroke colour from the existing shadow block - var strokeColour = this.sourceBlock_.getColourTertiary(); - div.style.borderColor = strokeColour; - - var xy = this.getAbsoluteXY_(); - // Account for border width, post-scale - xy.x -= scale / 2; - xy.y -= scale / 2; - // In RTL mode block fields and LTR input fields the left edge moves, - // whereas the right edge is fixed. Reposition the editor. - if (this.sourceBlock_.RTL) { - xy.x += width; - xy.x -= div.offsetWidth * scale; - xy.x += 1 * scale; - } - // Shift by a few pixels to line up exactly. - xy.y += 1 * scale; - if (goog.userAgent.GECKO && Blockly.WidgetDiv.DIV.style.top) { - // Firefox mis-reports the location of the border by a pixel - // once the WidgetDiv is moved into position. - xy.x += 2 * scale; - xy.y += 1 * scale; - } - if (goog.userAgent.WEBKIT) { - xy.y -= 1 * scale; - } - // Finally, set the actual style - div.style.left = xy.x + 'px'; - div.style.top = xy.y + 'px'; -}; - -/** - * Border radius for drawing this field, called when rendering the owning shadow block. - * @return {Number} Border radius in px. -*/ -Blockly.FieldTextInput.prototype.getBorderRadius = function() { - if (this.sourceBlock_.getOutputShape() == Blockly.OUTPUT_SHAPE_ROUND) { - return Blockly.BlockSvg.NUMBER_FIELD_CORNER_RADIUS; - } - return Blockly.BlockSvg.TEXT_FIELD_CORNER_RADIUS; -}; - -/** - * Close the editor, save the results, and start animating the disposal of elements. - * @return {!Function} Closure to call on destruction of the WidgetDiv. - * @private - */ -Blockly.FieldTextInput.prototype.widgetDispose_ = function() { - var thisField = this; - return function() { - var div = Blockly.WidgetDiv.DIV; - var htmlInput = Blockly.FieldTextInput.htmlInput_; - // Save the edit (if it validates). - thisField.maybeSaveEdit_(); - - thisField.unbindEvents_(htmlInput); - if (htmlInput.dropDownArrowMouseWrapper_) { - Blockly.unbindEvent_(htmlInput.dropDownArrowMouseWrapper_); - } - Blockly.Events.setGroup(false); - - // Animation of disposal - htmlInput.style.fontSize = Blockly.BlockSvg.FIELD_TEXTINPUT_FONTSIZE_INITIAL + 'pt'; - div.style.boxShadow = ''; - // Resize to actual size of final source block. - if (thisField.sourceBlock_) { - if (thisField.sourceBlock_.isShadow()) { - var size = thisField.sourceBlock_.getHeightWidth(); - div.style.width = (size.width + 1) + 'px'; - div.style.height = (size.height + 1) + 'px'; - } else { - div.style.width = (thisField.size_.width + 1) + 'px'; - div.style.height = (Blockly.BlockSvg.FIELD_HEIGHT_MAX_EDIT + 1) + 'px'; - } - } - div.style.marginLeft = 0; - }; -}; - -/** - * Final disposal of the text field's elements and properties. - * @return {!Function} Closure to call on finish animation of the WidgetDiv. - * @private - */ -Blockly.FieldTextInput.prototype.widgetDisposeAnimationFinished_ = function() { - return function() { - // Delete style properties. - var style = Blockly.WidgetDiv.DIV.style; - style.width = 'auto'; - style.height = 'auto'; - style.fontSize = ''; - // Reset class - Blockly.WidgetDiv.DIV.className = 'blocklyWidgetDiv'; - // Remove all styles - Blockly.WidgetDiv.DIV.removeAttribute('style'); - Blockly.FieldTextInput.htmlInput_.style.transition = ''; - Blockly.FieldTextInput.htmlInput_ = null; - }; -}; - -Blockly.FieldTextInput.prototype.maybeSaveEdit_ = function() { - var htmlInput = Blockly.FieldTextInput.htmlInput_; - // Save the edit (if it validates). - var text = htmlInput.value; - if (this.sourceBlock_) { - var text1 = this.callValidator(text); - if (text1 === null) { - // Invalid edit. - text = htmlInput.defaultValue; - } else { - // Validation function has changed the text. - text = text1; - if (this.onFinishEditing_) { - this.onFinishEditing_(text); - } - } - } - this.setText(text); - this.sourceBlock_.rendered && this.sourceBlock_.render(); -}; - -/** - * Ensure that only a number may be entered. - * @param {string} text The user's text. - * @return {?string} A string representing a valid number, or null if invalid. - */ -Blockly.FieldTextInput.numberValidator = function(text) { - console.warn('Blockly.FieldTextInput.numberValidator is deprecated. ' + - 'Use Blockly.FieldNumber instead.'); - if (text === null) { - return null; - } - text = String(text); - // TODO: Handle cases like 'ten', '1.203,14', etc. - // 'O' is sometimes mistaken for '0' by inexperienced users. - text = text.replace(/O/ig, '0'); - // Strip out thousands separators. - text = text.replace(/,/g, ''); - var n = parseFloat(text || 0); - return isNaN(n) ? null : String(n); -}; - -/** - * Ensure that only a nonnegative integer may be entered. - * @param {string} text The user's text. - * @return {?string} A string representing a valid int, or null if invalid. - */ -Blockly.FieldTextInput.nonnegativeIntegerValidator = function(text) { - var n = Blockly.FieldTextInput.numberValidator(text); - if (n) { - n = String(Math.max(0, Math.floor(n))); - } - return n; -}; - -Blockly.Field.register('field_input', Blockly.FieldTextInput); diff --git a/core/flyout_base.js b/core/flyout_base.js deleted file mode 100644 index fe5b3fcd4e..0000000000 --- a/core/flyout_base.js +++ /dev/null @@ -1,923 +0,0 @@ -/** - * @license - * Visual Blocks Editor - * - * Copyright 2011 Google Inc. - * https://developers.google.com/blockly/ - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @fileoverview Flyout tray containing blocks which may be created. - * @author fraser@google.com (Neil Fraser) - */ -'use strict'; - -goog.provide('Blockly.Flyout'); - -goog.require('Blockly.Block'); -goog.require('Blockly.Comment'); -goog.require('Blockly.Events'); -goog.require('Blockly.Events.BlockCreate'); -goog.require('Blockly.Events.VarCreate'); -goog.require('Blockly.FlyoutButton'); -goog.require('Blockly.FlyoutExtensionCategoryHeader'); -goog.require('Blockly.Gesture'); -goog.require('Blockly.scratchBlocksUtils'); -goog.require('Blockly.Touch'); -goog.require('Blockly.WorkspaceSvg'); -goog.require('goog.dom'); -goog.require('goog.events'); -goog.require('goog.math.Rect'); -goog.require('goog.userAgent'); - - -/** - * Class for a flyout. - * @param {!Object} workspaceOptions Dictionary of options for the workspace. - * @constructor - */ -Blockly.Flyout = function(workspaceOptions) { - workspaceOptions.getMetrics = this.getMetrics_.bind(this); - workspaceOptions.setMetrics = this.setMetrics_.bind(this); - - /** - * @type {!Blockly.Workspace} - * @protected - */ - this.workspace_ = new Blockly.WorkspaceSvg(workspaceOptions); - this.workspace_.isFlyout = true; - - // When we create blocks for this workspace, instead of using the "optional" id - // make the default `id` the same as the `type` for easier re-use. - var newBlock = this.workspace_.newBlock; - this.workspace_.newBlock = function(type, id) { - // Use `type` if `id` isn't passed. `this` will be workspace. - return newBlock.call(this, type, id || type); - }; - - /** - * Is RTL vs LTR. - * @type {boolean} - */ - this.RTL = !!workspaceOptions.RTL; - - /** - * Flyout should be laid out horizontally vs vertically. - * @type {boolean} - * @private - */ - this.horizontalLayout_ = workspaceOptions.horizontalLayout; - - /** - * Position of the toolbox and flyout relative to the workspace. - * @type {number} - * @protected - */ - this.toolboxPosition_ = workspaceOptions.toolboxPosition; - - /** - * Opaque data that can be passed to Blockly.unbindEvent_. - * @type {!Array.} - * @private - */ - this.eventWrappers_ = []; - - /** - * List of background buttons that lurk behind each block to catch clicks - * landing in the blocks' lakes and bays. - * @type {!Array.} - * @private - */ - this.backgroundButtons_ = []; - - /** - * List of visible buttons. - * @type {!Array.} - * @protected - */ - this.buttons_ = []; - - /** - * List of event listeners. - * @type {!Array.} - * @private - */ - this.listeners_ = []; - - /** - * List of blocks that should always be disabled. - * @type {!Array.} - * @private - */ - this.permanentlyDisabled_ = []; - - /** - * The toolbox that this flyout belongs to, or none if tihs is a simple - * workspace. - * @type {Blockly.Toolbox} - * @private - */ - this.parentToolbox_ = null; - - /** - * The target position for the flyout scroll animation in pixels. - * Is a number while animating, null otherwise. - * @type {?number} - * @package - */ - this.scrollTarget = null; - - /** - * A recycle bin for blocks. - * @type {!Array.} - * @private - */ - this.recycleBlocks_ = []; - -}; - -/** - * Does the flyout automatically close when a block is created? - * @type {boolean} - */ -Blockly.Flyout.prototype.autoClose = false; - -/** - * Whether the flyout is visible. - * @type {boolean} - * @private - */ -Blockly.Flyout.prototype.isVisible_ = false; - -/** - * Whether the workspace containing this flyout is visible. - * @type {boolean} - * @private - */ -Blockly.Flyout.prototype.containerVisible_ = true; - -/** - * Corner radius of the flyout background. - * @type {number} - * @const - */ -Blockly.Flyout.prototype.CORNER_RADIUS = 0; - -/** - * Margin around the edges of the blocks in the flyout. - * @type {number} - * @const - */ -Blockly.Flyout.prototype.MARGIN = 12; - -// TODO: Move GAP_X and GAP_Y to their appropriate files. - -/** - * Gap between items in horizontal flyouts. Can be overridden with the "sep" - * element. - * @const {number} - */ -Blockly.Flyout.prototype.GAP_X = Blockly.Flyout.prototype.MARGIN * 3; - -/** - * Gap between items in vertical flyouts. Can be overridden with the "sep" - * element. - * @const {number} - */ -Blockly.Flyout.prototype.GAP_Y = Blockly.Flyout.prototype.MARGIN; - -/** - * Top/bottom padding between scrollbar and edge of flyout background. - * @type {number} - * @const - */ -Blockly.Flyout.prototype.SCROLLBAR_PADDING = 2; - -/** - * Width of flyout. - * @type {number} - * @protected - */ -Blockly.Flyout.prototype.width_ = 0; - -/** - * Height of flyout. - * @type {number} - * @protected - */ -Blockly.Flyout.prototype.height_ = 0; - -/** - * Width of flyout contents. - * @type {number} - * @private - */ -Blockly.Flyout.prototype.contentWidth_ = 0; - -/** - * Height of flyout contents. - * @type {number} - * @private - */ -Blockly.Flyout.prototype.contentHeight_ = 0; - -/** - * Vertical offset of flyout. - * @type {number} - * @private - */ -Blockly.Flyout.prototype.verticalOffset_ = 0; - -/** - * Range of a drag angle from a flyout considered "dragging toward workspace". - * Drags that are within the bounds of this many degrees from the orthogonal - * line to the flyout edge are considered to be "drags toward the workspace". - * Example: - * Flyout Edge Workspace - * [block] / <-within this angle, drags "toward workspace" | - * [block] ---- orthogonal to flyout boundary ---- | - * [block] \ | - * The angle is given in degrees from the orthogonal. - * - * This is used to know when to create a new block and when to scroll the - * flyout. Setting it to 360 means that all drags create a new block. - * @type {number} - * @protected -*/ -Blockly.Flyout.prototype.dragAngleRange_ = 70; - -/** - * The fraction of the distance to the scroll target to move the flyout on - * each animation frame, when auto-scrolling. Values closer to 1.0 will make - * the scroll animation complete faster. Use 1.0 for no animation. - * @type {number} - */ -Blockly.Flyout.prototype.scrollAnimationFraction = 0.3; - -/** - * Whether to recycle blocks when refreshing the flyout. When false, do not allow - * anything to be recycled. The default is to recycle. - * @type {boolean} - * @private - */ -Blockly.Flyout.prototype.recyclingEnabled_ = true; - -/** - * Creates the flyout's DOM. Only needs to be called once. The flyout can - * either exist as its own svg element or be a g element nested inside a - * separate svg element. - * @param {string} tagName The type of tag to put the flyout in. This - * should be or . - * @return {!Element} The flyout's SVG group. - */ -Blockly.Flyout.prototype.createDom = function(tagName) { - /* - - - - - */ - // Setting style to display:none to start. The toolbox and flyout - // hide/show code will set up proper visibility and size later. - this.svgGroup_ = Blockly.utils.createSvgElement(tagName, - {'class': 'blocklyFlyout', 'style': 'display: none'}, null); - this.svgBackground_ = Blockly.utils.createSvgElement('path', - {'class': 'blocklyFlyoutBackground'}, this.svgGroup_); - this.svgGroup_.appendChild(this.workspace_.createDom()); - return this.svgGroup_; -}; - -/** - * Initializes the flyout. - * @param {!Blockly.Workspace} targetWorkspace The workspace in which to create - * new blocks. - */ -Blockly.Flyout.prototype.init = function(targetWorkspace) { - this.targetWorkspace_ = targetWorkspace; - this.workspace_.targetWorkspace = targetWorkspace; - // Add scrollbar. - this.scrollbar_ = new Blockly.Scrollbar(this.workspace_, - this.horizontalLayout_, false, 'blocklyFlyoutScrollbar'); - - this.position(); - - Array.prototype.push.apply(this.eventWrappers_, - Blockly.bindEventWithChecks_(this.svgGroup_, 'wheel', this, this.wheel_)); - // Dragging the flyout up and down (or left and right). - Array.prototype.push.apply(this.eventWrappers_, - Blockly.bindEventWithChecks_( - this.svgGroup_, 'mousedown', this, this.onMouseDown_)); - - // A flyout connected to a workspace doesn't have its own current gesture. - this.workspace_.getGesture = - this.targetWorkspace_.getGesture.bind(this.targetWorkspace_); - - // Get variables from the main workspace rather than the target workspace. - this.workspace_.variableMap_ = this.targetWorkspace_.getVariableMap(); - - this.workspace_.createPotentialVariableMap(); -}; - -/** - * Dispose of this flyout. - * Unlink from all DOM elements to prevent memory leaks. - */ -Blockly.Flyout.prototype.dispose = function() { - this.hide(); - Blockly.unbindEvent_(this.eventWrappers_); - if (this.scrollbar_) { - this.scrollbar_.dispose(); - this.scrollbar_ = null; - } - if (this.workspace_) { - this.workspace_.targetWorkspace = null; - this.workspace_.dispose(); - this.workspace_ = null; - } - if (this.svgGroup_) { - goog.dom.removeNode(this.svgGroup_); - this.svgGroup_ = null; - } - this.parentToolbox_ = null; - this.svgBackground_ = null; - this.targetWorkspace_ = null; -}; - -/** - * Set the parent toolbox of this flyout. - * @param {!Blockly.Toolbox} toolbox The toolbox that owns this flyout. - */ -Blockly.Flyout.prototype.setParentToolbox = function(toolbox) { - this.parentToolbox_ = toolbox; -}; - -/** - * Get the width of the flyout. - * @return {number} The width of the flyout. - */ -Blockly.Flyout.prototype.getWidth = function() { - return this.DEFAULT_WIDTH; -}; - -/** - * Get the height of the flyout. - * @return {number} The width of the flyout. - */ -Blockly.Flyout.prototype.getHeight = function() { - return this.height_; -}; - -/** - * Get the workspace inside the flyout. - * @return {!Blockly.WorkspaceSvg} The workspace inside the flyout. - * @package - */ -Blockly.Flyout.prototype.getWorkspace = function() { - return this.workspace_; -}; - -/** - * Is the flyout visible? - * @return {boolean} True if visible. - */ -Blockly.Flyout.prototype.isVisible = function() { - return this.isVisible_; -}; - -/** - * Set whether the flyout is visible. A value of true does not necessarily mean - * that the flyout is shown. It could be hidden because its container is hidden. - * @param {boolean} visible True if visible. - */ -Blockly.Flyout.prototype.setVisible = function(visible) { - var visibilityChanged = (visible != this.isVisible()); - - this.isVisible_ = visible; - if (visibilityChanged) { - this.updateDisplay_(); - } -}; - -/** - * Set whether this flyout's container is visible. - * @param {boolean} visible Whether the container is visible. - */ -Blockly.Flyout.prototype.setContainerVisible = function(visible) { - var visibilityChanged = (visible != this.containerVisible_); - this.containerVisible_ = visible; - if (visibilityChanged) { - this.updateDisplay_(); - } -}; - -/** - * Update the display property of the flyout based whether it thinks it should - * be visible and whether its containing workspace is visible. - * @private - */ -Blockly.Flyout.prototype.updateDisplay_ = function() { - var show = true; - if (!this.containerVisible_) { - show = false; - } else { - show = this.isVisible(); - } - this.svgGroup_.style.display = show ? 'block' : 'none'; - // Update the scrollbar's visiblity too since it should mimic the - // flyout's visibility. - this.scrollbar_.setContainerVisible(show); -}; - -/** - * Hide and empty the flyout. - */ -Blockly.Flyout.prototype.hide = function() { - if (!this.isVisible()) { - return; - } - this.setVisible(false); - // Delete all the event listeners. - for (var x = 0, listen; listen = this.listeners_[x]; x++) { - Blockly.unbindEvent_(listen); - } - this.listeners_.length = 0; - if (this.reflowWrapper_) { - this.workspace_.removeChangeListener(this.reflowWrapper_); - this.reflowWrapper_ = null; - } - // Do NOT delete the blocks here. Wait until Flyout.show. - // https://neil.fraser.name/news/2014/08/09/ -}; - -/** - * Show and populate the flyout. - * @param {!Array|string} xmlList List of blocks to show. - * Variables and procedures have a custom set of blocks. - */ -Blockly.Flyout.prototype.show = function(xmlList) { - this.workspace_.setResizesEnabled(false); - this.hide(); - this.clearOldBlocks_(); - - this.setVisible(true); - // Create the blocks to be shown in this flyout. - var contents = []; - var gaps = []; - this.permanentlyDisabled_.length = 0; - for (var i = 0, xml; xml = xmlList[i]; i++) { - // Handle dynamic categories, represented by a name instead of a list of XML. - // Look up the correct category generation function and call that to get a - // valid XML list. - if (typeof xml === 'string') { - var fnToApply = this.workspace_.targetWorkspace.getToolboxCategoryCallback( - xmlList[i]); - var newList = fnToApply(this.workspace_.targetWorkspace); - // Insert the new list of blocks in the middle of the list. - // We use splice to insert at index i, and remove a single element - // (the placeholder string). Because the spread operator (...) is not - // available, use apply and concat the array. - xmlList.splice.apply(xmlList, [i, 1].concat(newList)); - xml = xmlList[i]; - } - if (xml.tagName) { - var tagName = xml.tagName.toUpperCase(); - var default_gap = this.horizontalLayout_ ? this.GAP_X : this.GAP_Y; - if (tagName == 'BLOCK') { - - // We assume that in a flyout, the same block id (or type if missing id) means - // the same output BlockSVG. - - // Look for a block that matches the id or type, our createBlock will assign - // id = type if none existed. - var id = xml.getAttribute('id') || xml.getAttribute('type'); - var recycled = this.recycleBlocks_.findIndex(function(block) { - return block.id === id; - }); - - - // If we found a recycled item, reuse the BlockSVG from last time. - // Otherwise, convert the XML block to a BlockSVG. - var curBlock; - if (recycled > -1) { - curBlock = this.recycleBlocks_.splice(recycled, 1)[0]; - } else { - curBlock = Blockly.Xml.domToBlock(xml, this.workspace_); - } - - if (curBlock.disabled) { - // Record blocks that were initially disabled. - // Do not enable these blocks as a result of capacity filtering. - this.permanentlyDisabled_.push(curBlock); - } - contents.push({type: 'block', block: curBlock}); - var gap = parseInt(xml.getAttribute('gap'), 10); - gaps.push(isNaN(gap) ? default_gap : gap); - } else if (xml.tagName.toUpperCase() == 'SEP') { - // Change the gap between two blocks. - // - // The default gap is 24, can be set larger or smaller. - // This overwrites the gap attribute on the previous block. - // Note that a deprecated method is to add a gap to a block. - // - var newGap = parseInt(xml.getAttribute('gap'), 10); - // Ignore gaps before the first block. - if (!isNaN(newGap) && gaps.length > 0) { - gaps[gaps.length - 1] = newGap; - } else { - gaps.push(default_gap); - } - } else if ((tagName == 'LABEL') && (xml.getAttribute('showStatusButton') == 'true')) { - var curButton = new Blockly.FlyoutExtensionCategoryHeader(this.workspace_, - this.targetWorkspace_, xml); - contents.push({type: 'button', button: curButton}); - gaps.push(default_gap); - } else if (tagName == 'BUTTON' || tagName == 'LABEL') { - // Labels behave the same as buttons, but are styled differently. - var isLabel = tagName == 'LABEL'; - var curButton = new Blockly.FlyoutButton(this.workspace_, - this.targetWorkspace_, xml, isLabel); - contents.push({type: 'button', button: curButton}); - gaps.push(default_gap); - } - } - } - - this.emptyRecycleBlocks_(); - - this.layout_(contents, gaps); - - // IE 11 is an incompetent browser that fails to fire mouseout events. - // When the mouse is over the background, deselect all blocks. - var deselectAll = function() { - var topBlocks = this.workspace_.getTopBlocks(false); - for (var i = 0, block; block = topBlocks[i]; i++) { - block.removeSelect(); - } - }; - - this.listeners_.push(Blockly.bindEvent_(this.svgBackground_, 'mouseover', - this, deselectAll)); - - this.workspace_.setResizesEnabled(true); - this.reflow(); - - // Correctly position the flyout's scrollbar when it opens. - this.position(); - - this.reflowWrapper_ = this.reflow.bind(this); - this.workspace_.addChangeListener(this.reflowWrapper_); - - this.recordCategoryScrollPositions_(); -}; - -/** - * Empty out the recycled blocks, properly destroying everything. - * @private - */ -Blockly.Flyout.prototype.emptyRecycleBlocks_ = function() { - // Clean out the old recycle bin. - var oldBlocks = this.recycleBlocks_; - this.recycleBlocks_ = []; - for (var i = 0; i < oldBlocks.length; i++) { - oldBlocks[i].dispose(false, false); - } -}; - -/** - * Store an array of category names, ids, scrollbar positions, and category lengths. - * This is used when scrolling the flyout to cause a category to be selected. - * @private - */ -Blockly.Flyout.prototype.recordCategoryScrollPositions_ = function() { - this.categoryScrollPositions = []; - // Record category names and positions using the text label at the top of each one. - for (var i = 0; i < this.buttons_.length; i++) { - if (this.buttons_[i].getIsCategoryLabel()) { - var categoryLabel = this.buttons_[i]; - this.categoryScrollPositions.push({ - categoryName: categoryLabel.getText(), - position: this.horizontalLayout_ ? - categoryLabel.getPosition().x : categoryLabel.getPosition().y - }); - } - } - // Record the length of each category, setting the final one to 0. - var numCategories = this.categoryScrollPositions.length; - if (numCategories > 0) { - for (var i = 0; i < numCategories - 1; i++) { - var currentPos = this.categoryScrollPositions[i].position; - var nextPos = this.categoryScrollPositions[i + 1].position; - var length = nextPos - currentPos; - this.categoryScrollPositions[i].length = length; - } - this.categoryScrollPositions[numCategories - 1].length = 0; - // Record the id of each category. - for (var i = 0; i < numCategories; i++) { - var category = this.parentToolbox_.getCategoryByIndex(i); - if (category && category.id_) { - this.categoryScrollPositions[i].categoryId = category.id_; - } - } - } -}; - -/** - * Select a category using the scroll position. - * @param {number} pos The scroll position in pixels. - * @package - */ -Blockly.Flyout.prototype.selectCategoryByScrollPosition = function(pos) { - // If we are currently auto-scrolling, due to selecting a category by clicking on it, - // do not update the category selection. - if (this.scrollTarget) { - return; - } - var workspacePos = Math.round(pos / this.workspace_.scale); - // Traverse the array of scroll positions in reverse, so we can select the furthest - // category that the scroll position is beyond. - for (var i = this.categoryScrollPositions.length - 1; i >= 0; i--) { - if (workspacePos >= this.categoryScrollPositions[i].position) { - this.parentToolbox_.selectCategoryById(this.categoryScrollPositions[i].categoryId); - return; - } - } -}; - -/** - * Step the scrolling animation by scrolling a fraction of the way to - * a scroll target, and request the next frame if necessary. - * @package - */ -Blockly.Flyout.prototype.stepScrollAnimation = function() { - if (!this.scrollTarget) { - return; - } - var scrollPos = this.horizontalLayout_ ? - -this.workspace_.scrollX : -this.workspace_.scrollY; - var diff = this.scrollTarget - scrollPos; - if (Math.abs(diff) < 1) { - this.scrollbar_.set(this.scrollTarget); - this.scrollTarget = null; - return; - } - this.scrollbar_.set(scrollPos + diff * this.scrollAnimationFraction); - - // Polyfilled by goog.dom.animationFrame.polyfill - requestAnimationFrame(this.stepScrollAnimation.bind(this)); -}; - -/** - * Get the scaled scroll position. - * @return {number} The current scroll position. - */ -Blockly.Flyout.prototype.getScrollPos = function() { - var pos = this.horizontalLayout_ ? - -this.workspace_.scrollX : -this.workspace_.scrollY; - return pos / this.workspace_.scale; -}; - -/** - * Set the scroll position, scaling it. - * @param {number} pos The scroll position to set. - */ -Blockly.Flyout.prototype.setScrollPos = function(pos) { - this.scrollbar_.set(pos * this.workspace_.scale); -}; - -/** - * Set whether the flyout can recycle blocks. A value of true allows blocks to be recycled. - * @param {boolean} recycle True if recycling is possible. - */ -Blockly.Flyout.prototype.setRecyclingEnabled = function(recycle) { - this.recyclingEnabled_ = recycle; -}; - -/** - * Delete blocks and background buttons from a previous showing of the flyout. - * @private - */ -Blockly.Flyout.prototype.clearOldBlocks_ = function() { - // Delete any blocks from a previous showing. - var oldBlocks = this.workspace_.getTopBlocks(false); - for (var i = 0, block; block = oldBlocks[i]; i++) { - if (block.workspace == this.workspace_) { - if (this.recyclingEnabled_ && - Blockly.scratchBlocksUtils.blockIsRecyclable(block)) { - this.recycleBlock_(block); - } else { - block.dispose(false, false); - } - } - } - // Delete any background buttons from a previous showing. - for (var j = 0; j < this.backgroundButtons_.length; j++) { - var rect = this.backgroundButtons_[j]; - if (rect) goog.dom.removeNode(rect); - } - this.backgroundButtons_.length = 0; - - for (var i = 0, button; button = this.buttons_[i]; i++) { - button.dispose(); - } - this.buttons_.length = 0; - - // Clear potential variables from the previous showing. - this.workspace_.getPotentialVariableMap().clear(); -}; - -/** - * Add listeners to a block that has been added to the flyout. - * @param {!Element} root The root node of the SVG group the block is in. - * @param {!Blockly.Block} block The block to add listeners for. - * @param {!Element} rect The invisible rectangle under the block that acts as - * a button for that block. - * @private - */ -Blockly.Flyout.prototype.addBlockListeners_ = function(root, block, rect) { - this.listeners_.push(Blockly.bindEventWithChecks_(root, 'mousedown', null, - this.blockMouseDown_(block))); - this.listeners_.push(Blockly.bindEventWithChecks_(rect, 'mousedown', null, - this.blockMouseDown_(block))); - this.listeners_.push(Blockly.bindEvent_(root, 'mouseover', block, - block.addSelect)); - this.listeners_.push(Blockly.bindEvent_(root, 'mouseout', block, - block.removeSelect)); - this.listeners_.push(Blockly.bindEvent_(rect, 'mouseover', block, - block.addSelect)); - this.listeners_.push(Blockly.bindEvent_(rect, 'mouseout', block, - block.removeSelect)); -}; - -/** - * Handle a mouse-down on an SVG block in a non-closing flyout. - * @param {!Blockly.Block} block The flyout block to copy. - * @return {!Function} Function to call when block is clicked. - * @private - */ -Blockly.Flyout.prototype.blockMouseDown_ = function(block) { - var flyout = this; - return function(e) { - var gesture = flyout.targetWorkspace_.getGesture(e); - if (gesture) { - gesture.setStartBlock(block); - gesture.handleFlyoutStart(e, flyout); - } - }; -}; - -/** - * Mouse down on the flyout background. Start a scroll drag. - * @param {!Event} e Mouse down event. - * @private - */ -Blockly.Flyout.prototype.onMouseDown_ = function(e) { - var gesture = this.targetWorkspace_.getGesture(e); - if (gesture) { - gesture.handleFlyoutStart(e, this); - } -}; - -/** - * Create a copy of this block on the workspace. - * @param {!Blockly.BlockSvg} originalBlock The block to copy from the flyout. - * @return {Blockly.BlockSvg} The newly created block, or null if something - * went wrong with deserialization. - * @package - */ -Blockly.Flyout.prototype.createBlock = function(originalBlock) { - var newBlock = null; - Blockly.Events.disable(); - var variablesBeforeCreation = this.targetWorkspace_.getAllVariables(); - this.targetWorkspace_.setResizesEnabled(false); - try { - newBlock = this.placeNewBlock_(originalBlock); - // Close the flyout. - Blockly.hideChaff(); - } finally { - Blockly.Events.enable(); - } - - var newVariables = Blockly.Variables.getAddedVariables(this.targetWorkspace_, - variablesBeforeCreation); - - if (Blockly.Events.isEnabled()) { - Blockly.Events.setGroup(true); - Blockly.Events.fire(new Blockly.Events.Create(newBlock)); - // Fire a VarCreate event for each (if any) new variable created. - for (var i = 0; i < newVariables.length; i++) { - var thisVariable = newVariables[i]; - Blockly.Events.fire(new Blockly.Events.VarCreate(thisVariable)); - } - } - if (this.autoClose) { - this.hide(); - } - return newBlock; -}; - -/** - * Reflow blocks and their buttons. - */ -Blockly.Flyout.prototype.reflow = function() { - if (this.reflowWrapper_) { - this.workspace_.removeChangeListener(this.reflowWrapper_); - } - var blocks = this.workspace_.getTopBlocks(false); - this.reflowInternal_(blocks); - if (this.reflowWrapper_) { - this.workspace_.addChangeListener(this.reflowWrapper_); - } -}; - -/** - * @return {boolean} True if this flyout may be scrolled with a scrollbar or by - * dragging. - * @package - */ -Blockly.Flyout.prototype.isScrollable = function() { - return this.scrollbar_ ? this.scrollbar_.isVisible() : false; -}; - -/** - * Copy a block from the flyout to the workspace and position it correctly. - * @param {!Blockly.Block} oldBlock The flyout block to copy. - * @return {!Blockly.Block} The new block in the main workspace. - * @private - */ -Blockly.Flyout.prototype.placeNewBlock_ = function(oldBlock) { - var targetWorkspace = this.targetWorkspace_; - var svgRootOld = oldBlock.getSvgRoot(); - if (!svgRootOld) { - throw 'oldBlock is not rendered.'; - } - - // Create the new block by cloning the block in the flyout (via XML). - var xml = Blockly.Xml.blockToDom(oldBlock); - // The target workspace would normally resize during domToBlock, which will - // lead to weird jumps. Save it for terminateDrag. - targetWorkspace.setResizesEnabled(false); - - // Using domToBlock instead of domToWorkspace means that the new block will be - // placed at position (0, 0) in main workspace units. - var block = Blockly.Xml.domToBlock(xml, targetWorkspace); - var svgRootNew = block.getSvgRoot(); - if (!svgRootNew) { - throw 'block is not rendered.'; - } - - // The offset in pixels between the main workspace's origin and the upper left - // corner of the injection div. - var mainOffsetPixels = targetWorkspace.getOriginOffsetInPixels(); - - // The offset in pixels between the flyout workspace's origin and the upper - // left corner of the injection div. - var flyoutOffsetPixels = this.workspace_.getOriginOffsetInPixels(); - - // The position of the old block in flyout workspace coordinates. - var oldBlockPosWs = oldBlock.getRelativeToSurfaceXY(); - - // The position of the old block in pixels relative to the flyout - // workspace's origin. - var oldBlockPosPixels = oldBlockPosWs.scale(this.workspace_.scale); - - // The position of the old block in pixels relative to the upper left corner - // of the injection div. - var oldBlockOffsetPixels = goog.math.Coordinate.sum(flyoutOffsetPixels, - oldBlockPosPixels); - - // The position of the old block in pixels relative to the origin of the - // main workspace. - var finalOffsetPixels = goog.math.Coordinate.difference(oldBlockOffsetPixels, - mainOffsetPixels); - - // The position of the old block in main workspace coordinates. - var finalOffsetMainWs = finalOffsetPixels.scale(1 / targetWorkspace.scale); - - block.moveBy(finalOffsetMainWs.x, finalOffsetMainWs.y); - return block; -}; - -/** - * Put a previously created block into the recycle bin, used during large - * workspace swaps to limit the number of new dom elements we need to create - * - * @param {!Blockly.BlockSvg} block The block to recycle. - * @private - */ -Blockly.Flyout.prototype.recycleBlock_ = function(block) { - var xy = block.getRelativeToSurfaceXY(); - block.moveBy(-xy.x, -xy.y); - this.recycleBlocks_.push(block); -}; diff --git a/core/flyout_button.js b/core/flyout_button.js deleted file mode 100644 index 26f7d8f39a..0000000000 --- a/core/flyout_button.js +++ /dev/null @@ -1,322 +0,0 @@ -/** - * @license - * Visual Blocks Editor - * - * Copyright 2016 Google Inc. - * https://developers.google.com/blockly/ - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @fileoverview Class for a button in the flyout. - * @author fenichel@google.com (Rachel Fenichel) - */ -'use strict'; - -goog.provide('Blockly.FlyoutButton'); - -goog.require('goog.dom'); -goog.require('goog.math.Coordinate'); - - -/** - * Class for a button or label in the flyout. Labels behave the same as buttons, - * but are styled differently. - * @param {!Blockly.WorkspaceSvg} workspace The workspace in which to place this - * button. - * @param {!Blockly.WorkspaceSvg} targetWorkspace The flyout's target workspace. - * @param {!Element} xml The XML specifying the label/button. - * @param {boolean} isLabel Whether this button should be styled as a label. - * @constructor - */ -Blockly.FlyoutButton = function(workspace, targetWorkspace, xml, isLabel) { - - this.init(workspace, targetWorkspace, xml, isLabel); - - /** - * Function to call when this button is clicked. - * @type {function(!Blockly.FlyoutButton)} - * @private - */ - this.callback_ = null; - - var callbackKey = xml.getAttribute('callbackKey'); - if (this.isLabel_ && callbackKey) { - console.warn('Labels should not have callbacks. Label text: ' + this.text_); - } else if (!this.isLabel_ && - !(callbackKey && targetWorkspace.getButtonCallback(callbackKey))) { - console.warn('Buttons should have callbacks. Button text: ' + this.text_); - } else { - this.callback_ = targetWorkspace.getButtonCallback(callbackKey); - } -}; - -/** - * The margin around the text in the button. - */ -Blockly.FlyoutButton.MARGIN = 40; - -/** - * The width of the button's rect. - * @type {number} - */ -Blockly.FlyoutButton.prototype.width = 0; - -/** - * The height of the button's rect. - * @type {number} - */ -Blockly.FlyoutButton.prototype.height = 40; // Can't be computed like the width - -/** - * Opaque data that can be passed to Blockly.unbindEvent_. - * @type {Array.} - * @private - */ -Blockly.FlyoutButton.prototype.onMouseUpWrapper_ = null; - -/** -* Initialize the button or label. This is a helper function to so that the -* constructor can be overridden. -* @param {!Blockly.WorkspaceSvg} workspace The workspace in which to place this -* button. -* @param {!Blockly.WorkspaceSvg} targetWorkspace The flyout's target workspace. -* @param {!Element} xml The XML specifying the label/button. -* @param {boolean} isLabel Whether this button should be styled as a label. - */ -Blockly.FlyoutButton.prototype.init = function( - workspace, targetWorkspace, xml, isLabel) { - - /** - * @type {!Blockly.WorkspaceSvg} - * @private - */ - this.workspace_ = workspace; - - /** - * @type {!Blockly.Workspace} - * @private - */ - this.targetWorkspace_ = targetWorkspace; - - /** - * @type {string} - * @private - */ - this.text_ = xml.getAttribute('text'); - - /** - * @type {!goog.math.Coordinate} - * @private - */ - this.position_ = new goog.math.Coordinate(0, 0); - - /** - * Whether this button should be styled as a label. - * @type {boolean} - * @private - */ - this.isLabel_ = isLabel; - - /** - * Whether this button is a label at the top of a category. - * @type {boolean} - * @private - */ - this.isCategoryLabel_ = xml.getAttribute('category-label') === 'true'; - - /** - * If specified, a CSS class to add to this button. - * @type {?string} - * @private - */ - this.cssClass_ = xml.getAttribute('web-class') || null; -}; - -/** - * Create the button elements. - * @return {!Element} The button's SVG group. - */ -Blockly.FlyoutButton.prototype.createDom = function() { - var cssClass = this.isLabel_ ? 'blocklyFlyoutLabel' : 'blocklyFlyoutButton'; - if (this.cssClass_) { - cssClass += ' ' + this.cssClass_; - } - - this.svgGroup_ = Blockly.utils.createSvgElement('g', {'class': cssClass}, - this.workspace_.getCanvas()); - - this.addTextSvg(this.isLabel_); - - this.mouseUpWrapper_ = Blockly.bindEventWithChecks_(this.svgGroup_, 'mouseup', - this, this.onMouseUp_); - return this.svgGroup_; -}; - -/** - * Add the text element for the label or button. - * @param {boolean} isLabel True if this is a label and not button. - * @package - */ -Blockly.FlyoutButton.prototype.addTextSvg = function(isLabel) { - if (!isLabel) { - // Shadow rectangle (light source does not mirror in RTL). - var shadow = Blockly.utils.createSvgElement('rect', - { - 'class': 'blocklyFlyoutButtonShadow', - 'rx': 4, - 'ry': 4, - 'x': 1, - 'y': 1 - }, - this.svgGroup_); - } - // Background rectangle. - var rect = Blockly.utils.createSvgElement('rect', - { - 'class': isLabel ? - 'blocklyFlyoutLabelBackground' : 'blocklyFlyoutButtonBackground', - 'rx': 4, 'ry': 4 - }, - this.svgGroup_); - - var svgText = Blockly.utils.createSvgElement('text', - { - 'class': isLabel ? 'blocklyFlyoutLabelText' : 'blocklyText', - 'x': 0, - 'y': 0, - 'text-anchor': 'middle' - }, - this.svgGroup_); - svgText.textContent = Blockly.utils.replaceMessageReferences(this.text_); - - this.width = Blockly.Field.getCachedWidth(svgText); - - if (!isLabel) { - this.width += 2 * Blockly.FlyoutButton.MARGIN; - shadow.setAttribute('width', this.width); - shadow.setAttribute('height', this.height); - } - - rect.setAttribute('width', this.width); - rect.setAttribute('height', this.height); - - svgText.setAttribute('text-anchor', 'middle'); - svgText.setAttribute('dominant-baseline', 'central'); - svgText.setAttribute('dy', goog.userAgent.EDGE_OR_IE ? - Blockly.Field.IE_TEXT_OFFSET : '0'); - svgText.setAttribute('x', this.width / 2); - svgText.setAttribute('y', this.height / 2); -}; - -/** - * Correctly position the flyout button and make it visible. - */ -Blockly.FlyoutButton.prototype.show = function() { - this.updateTransform_(); - this.svgGroup_.setAttribute('display', 'block'); -}; - -/** - * Update SVG attributes to match internal state. - * @private - */ -Blockly.FlyoutButton.prototype.updateTransform_ = function() { - this.svgGroup_.setAttribute('transform', - 'translate(' + this.position_.x + ',' + this.position_.y + ')'); -}; - -/** - * Move the button to the given x, y coordinates. - * @param {number} x The new x coordinate. - * @param {number} y The new y coordinate. - */ -Blockly.FlyoutButton.prototype.moveTo = function(x, y) { - this.position_.x = x; - this.position_.y = y; - this.updateTransform_(); -}; - -/** - * Get the button's target workspace. - * @return {!Blockly.WorkspaceSvg} The target workspace of the flyout where this - * button resides. - */ -Blockly.FlyoutButton.prototype.getTargetWorkspace = function() { - return this.targetWorkspace_; -}; - -/** - * Get whether this button is a label at the top of a category. - * @return {boolean} True if it is a category label. - * @package - */ -Blockly.FlyoutButton.prototype.getIsCategoryLabel = function() { - return this.isCategoryLabel_; -}; - -/** - * Get the text of this button. - * @return {string} The text on the button. - * @package - */ -Blockly.FlyoutButton.prototype.getText = function() { - return this.text_; -}; - -/** - * Get the position of this button. - * @return {!goog.math.Coordinate} The button position. - * @package - */ -Blockly.FlyoutButton.prototype.getPosition = function() { - return this.position_; -}; - -/** - * Dispose of this button. - */ -Blockly.FlyoutButton.prototype.dispose = function() { - if (this.onMouseUpWrapper_) { - Blockly.unbindEvent_(this.onMouseUpWrapper_); - } - if (this.svgGroup_) { - goog.dom.removeNode(this.svgGroup_); - this.svgGroup_ = null; - } - this.workspace_ = null; - this.targetWorkspace_ = null; -}; - -/** - * Do something when the button is clicked. - * @param {!Event} e Mouse up event. - * @private - */ -Blockly.FlyoutButton.prototype.onMouseUp_ = function(e) { - var gesture = this.targetWorkspace_.getGesture(e); - if (gesture) { - // If we're in the middle of dragging something (blocks, workspace, etc.) ignore the button. - // Otherwise, cancel the gesture. - if (gesture.isDragging()) { - return; - } - gesture.cancel(); - } - - // Call the callback registered to this button. - if (this.callback_) { - this.callback_(this); - } -}; diff --git a/core/flyout_dragger.js b/core/flyout_dragger.js deleted file mode 100644 index c3909eaf2f..0000000000 --- a/core/flyout_dragger.js +++ /dev/null @@ -1,83 +0,0 @@ -/** - * @license - * Visual Blocks Editor - * - * Copyright 2017 Google Inc. - * https://developers.google.com/blockly/ - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @fileoverview Methods for dragging a flyout visually. - * @author fenichel@google.com (Rachel Fenichel) - */ -'use strict'; - -goog.provide('Blockly.FlyoutDragger'); - -goog.require('Blockly.WorkspaceDragger'); - -goog.require('goog.asserts'); -goog.require('goog.math.Coordinate'); - - -/** - * Class for a flyout dragger. It moves a flyout workspace around when it is - * being dragged by a mouse or touch. - * Note that the workspace itself manages whether or not it has a drag surface - * and how to do translations based on that. This simply passes the right - * commands based on events. - * @param {!Blockly.Flyout} flyout The flyout to drag. - * @constructor - */ -Blockly.FlyoutDragger = function(flyout) { - Blockly.FlyoutDragger.superClass_.constructor.call(this, - flyout.getWorkspace()); - - /** - * The scrollbar to update to move the flyout. - * Unlike the main workspace, the flyout has only one scrollbar, in either the - * horizontal or the vertical direction. - * @type {!Blockly.Scrollbar} - * @private - */ - this.scrollbar_ = flyout.scrollbar_; - - /** - * Whether the flyout scrolls horizontally. If false, the flyout scrolls - * vertically. - * @type {boolean} - * @private - */ - this.horizontalLayout_ = flyout.horizontalLayout_; -}; -goog.inherits(Blockly.FlyoutDragger, Blockly.WorkspaceDragger); - -/** - * Move the appropriate scrollbar to drag the flyout. - * Since flyouts only scroll in one direction at a time, this will discard one - * of the calculated values. - * x and y are in pixels. - * @param {number} x The new x position to move the scrollbar to. - * @param {number} y The new y position to move the scrollbar to. - * @private - */ -Blockly.FlyoutDragger.prototype.updateScroll_ = function(x, y) { - // Move the scrollbar and the flyout will scroll automatically. - if (this.horizontalLayout_) { - this.scrollbar_.set(x); - } else { - this.scrollbar_.set(y); - } -}; diff --git a/core/flyout_extension_category_header.js b/core/flyout_extension_category_header.js deleted file mode 100644 index b97aa04b55..0000000000 --- a/core/flyout_extension_category_header.js +++ /dev/null @@ -1,159 +0,0 @@ -/** - * @license - * Visual Blocks Editor - * - * Copyright 2018 Google Inc. - * https://developers.google.com/blockly/ - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @fileoverview Class for a category header in the flyout for Scratch - * extensions which can display a textual label and a status button. - * @author ericr@media.mit.edu (Eric Rosenbaum) - */ -'use strict'; - -goog.provide('Blockly.FlyoutExtensionCategoryHeader'); - -goog.require('Blockly.FlyoutButton'); - -/** - * Class for a category header in the flyout for Scratch extensions which can - * display a textual label and a status button. - * @param {!Blockly.WorkspaceSvg} workspace The workspace in which to place this - * header. - * @param {!Blockly.WorkspaceSvg} targetWorkspace The flyout's target workspace. - * @param {!Element} xml The XML specifying the header. - * @extends {Blockly.FlyoutButton} - * @constructor - */ -Blockly.FlyoutExtensionCategoryHeader = function(workspace, targetWorkspace, xml) { - - this.init(workspace, targetWorkspace, xml, false); - - /** - * @type {number} - * @private - */ - this.flyoutWidth_ = this.targetWorkspace_.getFlyout().getWidth(); - - /** - * @type {string} - */ - this.extensionId = xml.getAttribute('id'); - - /** - * Whether this is a label at the top of a category. - * @type {boolean} - * @private - */ - this.isCategoryLabel_ = true; -}; -goog.inherits(Blockly.FlyoutExtensionCategoryHeader, Blockly.FlyoutButton); - -/** - * Create the label and button elements. - * @return {!Element} The SVG group. - */ -Blockly.FlyoutExtensionCategoryHeader.prototype.createDom = function() { - var cssClass = 'blocklyFlyoutLabel'; - - this.svgGroup_ = Blockly.utils.createSvgElement('g', {'class': cssClass}, - this.workspace_.getCanvas()); - - this.addTextSvg(true); - - this.refreshStatus(); - - var statusButtonWidth = 30; - var marginX = 20; - var marginY = 5; - var touchPadding = 16; - - var statusButtonX = this.workspace_.RTL ? (marginX - this.flyoutWidth_ + statusButtonWidth) : - (this.flyoutWidth_ - statusButtonWidth - marginX) / this.workspace_.scale; - - if (this.imageSrc_) { - /** @type {SVGElement} */ - this.imageElement_ = Blockly.utils.createSvgElement( - 'image', - { - 'class': 'blocklyFlyoutButton', - 'height': statusButtonWidth + 'px', - 'width': statusButtonWidth + 'px', - 'x': statusButtonX + 'px', - 'y': marginY + 'px' - }, - this.svgGroup_); - this.imageElementBackground_ = Blockly.utils.createSvgElement( - 'rect', - { - 'class': 'blocklyTouchTargetBackground', - 'height': statusButtonWidth + 2 * touchPadding + 'px', - 'width': statusButtonWidth + 2 * touchPadding + 'px', - 'x': (statusButtonX - touchPadding) + 'px', - 'y': (marginY - touchPadding) + 'px' - }, - this.svgGroup_); - this.setImageSrc(this.imageSrc_); - } - - this.callback_ = Blockly.statusButtonCallback.bind(this, this.extensionId); - - this.mouseUpWrapper_ = Blockly.bindEventWithChecks_(this.imageElementBackground_, 'mouseup', - this, this.onMouseUp_); - return this.svgGroup_; -}; - -/** - * Set the image on the status button using a status string. - */ -Blockly.FlyoutExtensionCategoryHeader.prototype.refreshStatus = function() { - var status = Blockly.FlyoutExtensionCategoryHeader.getExtensionState(this.extensionId); - var basePath = Blockly.mainWorkspace.options.pathToMedia; - if (status == Blockly.StatusButtonState.READY) { - this.setImageSrc(basePath + 'status-ready.svg'); - } - if (status == Blockly.StatusButtonState.NOT_READY) { - this.setImageSrc(basePath + 'status-not-ready.svg'); - } -}; - -/** - * Set the source URL of the image for the button. - * @param {?string} src New source. - * @package - */ -Blockly.FlyoutExtensionCategoryHeader.prototype.setImageSrc = function(src) { - if (src === null) { - // No change if null. - return; - } - this.imageSrc_ = src; - if (this.imageElement_) { - this.imageElement_.setAttributeNS('http://www.w3.org/1999/xlink', - 'xlink:href', this.imageSrc_ || ''); - } -}; - -/** - * Gets the extension state. Overridden externally. - * @param {string} extensionId The ID of the extension in question. - * @return {Blockly.StatusButtonState} The state of the extension. - * @public - */ -Blockly.FlyoutExtensionCategoryHeader.getExtensionState = function(/* extensionId */) { - return Blockly.StatusButtonState.NOT_READY; -}; diff --git a/core/flyout_horizontal.js b/core/flyout_horizontal.js deleted file mode 100644 index b80d844643..0000000000 --- a/core/flyout_horizontal.js +++ /dev/null @@ -1,475 +0,0 @@ -/** - * @license - * Visual Blocks Editor - * - * Copyright 2011 Google Inc. - * https://developers.google.com/blockly/ - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @fileoverview Flyout tray containing blocks which may be created. - * @author fraser@google.com (Neil Fraser) - */ -'use strict'; - -goog.provide('Blockly.HorizontalFlyout'); - -goog.require('Blockly.Block'); -goog.require('Blockly.Comment'); -goog.require('Blockly.Events'); -goog.require('Blockly.FlyoutButton'); -goog.require('Blockly.Flyout'); -goog.require('Blockly.WorkspaceSvg'); -goog.require('goog.dom'); -goog.require('goog.dom.animationFrame.polyfill'); -goog.require('goog.events'); -goog.require('goog.math.Rect'); -goog.require('goog.userAgent'); - - -/** - * Class for a flyout. - * @param {!Object} workspaceOptions Dictionary of options for the workspace. - * @extends {Blockly.Flyout} - * @constructor - */ -Blockly.HorizontalFlyout = function(workspaceOptions) { - workspaceOptions.getMetrics = this.getMetrics_.bind(this); - workspaceOptions.setMetrics = this.setMetrics_.bind(this); - - Blockly.HorizontalFlyout.superClass_.constructor.call(this, workspaceOptions); - /** - * Flyout should be laid out horizontally vs vertically. - * @type {boolean} - * @private - */ - this.horizontalLayout_ = true; -}; -goog.inherits(Blockly.HorizontalFlyout, Blockly.Flyout); - -/** - * Return an object with all the metrics required to size scrollbars for the - * flyout. The following properties are computed: - * .viewHeight: Height of the visible rectangle, - * .viewWidth: Width of the visible rectangle, - * .contentHeight: Height of the contents, - * .contentWidth: Width of the contents, - * .viewTop: Offset of top edge of visible rectangle from parent, - * .contentTop: Offset of the top-most content from the y=0 coordinate, - * .absoluteTop: Top-edge of view. - * .viewLeft: Offset of the left edge of visible rectangle from parent, - * .contentLeft: Offset of the left-most content from the x=0 coordinate, - * .absoluteLeft: Left-edge of view. - * @return {Object} Contains size and position metrics of the flyout. - * @private - */ -Blockly.HorizontalFlyout.prototype.getMetrics_ = function() { - if (!this.isVisible()) { - // Flyout is hidden. - return null; - } - - try { - var optionBox = this.workspace_.getCanvas().getBBox(); - } catch (e) { - // Firefox has trouble with hidden elements (Bug 528969). - var optionBox = {height: 0, y: 0, width: 0, x: 0}; - } - - var absoluteTop = this.SCROLLBAR_PADDING; - var absoluteLeft = this.SCROLLBAR_PADDING; - if (this.toolboxPosition_ == Blockly.TOOLBOX_AT_BOTTOM) { - absoluteTop = 0; - } - var viewHeight = this.height_; - if (this.toolboxPosition_ == Blockly.TOOLBOX_AT_TOP) { - viewHeight += this.MARGIN; - } - var viewWidth = this.width_ - 2 * this.SCROLLBAR_PADDING; - - var metrics = { - viewHeight: viewHeight, - viewWidth: viewWidth, - contentHeight: optionBox.height * this.workspace_.scale + 2 * this.MARGIN, - contentWidth: optionBox.width * this.workspace_.scale + 2 * this.MARGIN, - viewTop: -this.workspace_.scrollY, - viewLeft: -this.workspace_.scrollX, - contentTop: optionBox.y, - contentLeft: optionBox.x, - absoluteTop: absoluteTop, - absoluteLeft: absoluteLeft - }; - return metrics; -}; - -/** - * Sets the translation of the flyout to match the scrollbars. - * @param {!Object} xyRatio Contains a y property which is a float - * between 0 and 1 specifying the degree of scrolling and a - * similar x property. - * @private - */ -Blockly.HorizontalFlyout.prototype.setMetrics_ = function(xyRatio) { - var metrics = this.getMetrics_(); - // This is a fix to an apparent race condition. - if (!metrics) { - return; - } - - if (goog.isNumber(xyRatio.x)) { - this.workspace_.scrollX = -metrics.contentWidth * xyRatio.x; - } - - this.workspace_.translate(this.workspace_.scrollX + metrics.absoluteLeft, - this.workspace_.scrollY + metrics.absoluteTop); - - if (this.categoryScrollPositions) { - this.selectCategoryByScrollPosition(-this.workspace_.scrollX); - } -}; - -/** - * Move the flyout to the edge of the workspace. - */ -Blockly.HorizontalFlyout.prototype.position = function() { - if (!this.isVisible()) { - return; - } - var targetWorkspaceMetrics = this.targetWorkspace_.getMetrics(); - if (!targetWorkspaceMetrics) { - // Hidden components will return null. - return; - } - var edgeWidth = this.horizontalLayout_ ? - targetWorkspaceMetrics.viewWidth - 2 * this.CORNER_RADIUS : - this.width_ - this.CORNER_RADIUS; - - var edgeHeight = this.horizontalLayout_ ? - this.height_ - this.CORNER_RADIUS : - targetWorkspaceMetrics.viewHeight - 2 * this.CORNER_RADIUS; - - this.setBackgroundPath_(edgeWidth, edgeHeight); - - var x = targetWorkspaceMetrics.absoluteLeft; - if (this.toolboxPosition_ == Blockly.TOOLBOX_AT_RIGHT) { - x += targetWorkspaceMetrics.viewWidth; - x -= this.width_; - } - - var y = targetWorkspaceMetrics.absoluteTop; - if (this.toolboxPosition_ == Blockly.TOOLBOX_AT_BOTTOM) { - y += targetWorkspaceMetrics.viewHeight; - y -= this.height_; - } - - // Record the height for Blockly.Flyout.getMetrics_, or width if the layout is - // horizontal. - if (this.horizontalLayout_) { - this.width_ = targetWorkspaceMetrics.viewWidth; - } else { - this.height_ = targetWorkspaceMetrics.viewHeight; - } - - this.svgGroup_.setAttribute("width", this.width_); - this.svgGroup_.setAttribute("height", this.height_); - var transform = 'translate(' + x + 'px,' + y + 'px)'; - Blockly.utils.setCssTransform(this.svgGroup_, transform); - - // Update the scrollbar (if one exists). - if (this.scrollbar_) { - // Set the scrollbars origin to be the top left of the flyout. - this.scrollbar_.setOrigin(x, y); - this.scrollbar_.resize(); - } - // The blocks need to be visible in order to be laid out and measured correctly, but we don't - // want the flyout to show up until it's properly sized. - // Opacity is set to zero in show(). - this.svgGroup_.style.opacity = 1; -}; - -/** - * Create and set the path for the visible boundaries of the flyout. - * @param {number} width The width of the flyout, not including the - * rounded corners. - * @param {number} height The height of the flyout, not including - * rounded corners. - * @private - */ -Blockly.HorizontalFlyout.prototype.setBackgroundPath_ = function(width, height) { - var atTop = this.toolboxPosition_ == Blockly.TOOLBOX_AT_TOP; - // Start at top left. - var path = ['M 0,' + (atTop ? 0 : this.CORNER_RADIUS)]; - - if (atTop) { - // Top. - path.push('h', width + 2 * this.CORNER_RADIUS); - // Right. - path.push('v', height); - // Bottom. - path.push('a', this.CORNER_RADIUS, this.CORNER_RADIUS, 0, 0, 1, - -this.CORNER_RADIUS, this.CORNER_RADIUS); - path.push('h', -1 * width); - // Left. - path.push('a', this.CORNER_RADIUS, this.CORNER_RADIUS, 0, 0, 1, - -this.CORNER_RADIUS, -this.CORNER_RADIUS); - path.push('z'); - } else { - // Top. - path.push('a', this.CORNER_RADIUS, this.CORNER_RADIUS, 0, 0, 1, - this.CORNER_RADIUS, -this.CORNER_RADIUS); - path.push('h', width); - // Right. - path.push('a', this.CORNER_RADIUS, this.CORNER_RADIUS, 0, 0, 1, - this.CORNER_RADIUS, this.CORNER_RADIUS); - path.push('v', height); - // Bottom. - path.push('h', -width - 2 * this.CORNER_RADIUS); - // Left. - path.push('z'); - } - this.svgBackground_.setAttribute('d', path.join(' ')); -}; - -/** - * Scroll the flyout to the top. - */ -Blockly.HorizontalFlyout.prototype.scrollToStart = function() { - this.scrollbar_.set(this.RTL ? Infinity : 0); -}; - -/** - * Scroll the flyout to a position. - * @param {number} pos The targeted scroll position. - * @package - */ -Blockly.HorizontalFlyout.prototype.scrollTo = function(pos) { - this.scrollTarget = pos * this.workspace_.scale; - - // Make sure not to set the scroll target past the farthest point we can - // scroll to, i.e. the content width minus the view width - var metrics = this.workspace_.getMetrics(); - var contentWidth = metrics.contentWidth; - var viewWidth = metrics.viewWidth; - this.scrollTarget = Math.min(this.scrollTarget, contentWidth - viewWidth); - - this.stepScrollAnimation(); -}; - -/** - * Scroll the flyout. - * @param {!Event} e Mouse wheel scroll event. - * @private - */ -Blockly.HorizontalFlyout.prototype.wheel_ = function(e) { - // remove scrollTarget to stop auto scrolling in stepScrollAnimation - this.scrollTarget = null; - - var delta = e.deltaX; - - // If we're scrolling more vertically than horizontally, use the vertical - // scroll delta instead. This allows people using a mouse wheel (which can - // only scroll vertically) to scroll the horizontal flyout. It also allows - // trackpad users to scroll it by scrolling either horizontally or - // vertically. - if (Math.abs(e.deltaY) > Math.abs(delta)) { - delta = e.deltaY; - } - - if (delta) { - // Firefox's mouse wheel deltas are a tenth that of Chrome/Safari. - // DeltaMode is 1 for a mouse wheel, but not for a trackpad scroll event - if (goog.userAgent.GECKO && (e.deltaMode === 1)) { - delta *= 10; - } - var metrics = this.getMetrics_(); - var pos = metrics.viewLeft + delta; - var limit = metrics.contentWidth - metrics.viewWidth; - pos = Math.min(pos, limit); - pos = Math.max(pos, 0); - this.scrollbar_.set(pos); - // When the flyout moves from a wheel event, hide WidgetDiv and DropDownDiv. - Blockly.WidgetDiv.hide(true); - Blockly.DropDownDiv.hideWithoutAnimation(); - } - - // Don't scroll the page. - e.preventDefault(); - // Don't propagate mousewheel event (zooming). - e.stopPropagation(); -}; - -/** - * Lay out the blocks in the flyout. - * @param {!Array.} contents The blocks and buttons to lay out. - * @param {!Array.} gaps The visible gaps between blocks. - * @private - */ -Blockly.HorizontalFlyout.prototype.layout_ = function(contents, gaps) { - this.workspace_.scale = this.targetWorkspace_.scale; - var margin = this.MARGIN; - var cursorX = margin; - var cursorY = margin; - if (this.RTL) { - contents = contents.reverse(); - } - - for (var i = 0, item; item = contents[i]; i++) { - if (item.type == 'block') { - var block = item.block; - var allBlocks = block.getDescendants(false); - for (var j = 0, child; child = allBlocks[j]; j++) { - // Mark blocks as being inside a flyout. This is used to detect and - // prevent the closure of the flyout if the user right-clicks on such a - // block. - child.isInFlyout = true; - } - var root = block.getSvgRoot(); - var blockHW = block.getHeightWidth(); - - var moveX = cursorX; - if (this.RTL) { - moveX += blockHW.width; - } - - block.moveBy(moveX, cursorY); - cursorX += blockHW.width + gaps[i]; - - // Create an invisible rectangle under the block to act as a button. Just - // using the block as a button is poor, since blocks have holes in them. - var rect = Blockly.utils.createSvgElement('rect', {'fill-opacity': 0}, null); - rect.tooltip = block; - Blockly.Tooltip.bindMouseEvents(rect); - // Add the rectangles under the blocks, so that the blocks' tooltips work. - this.workspace_.getCanvas().insertBefore(rect, block.getSvgRoot()); - block.flyoutRect_ = rect; - this.backgroundButtons_[i] = rect; - - this.addBlockListeners_(root, block, rect); - } else if (item.type == 'button') { - var button = item.button; - var buttonSvg = button.createDom(); - button.moveTo(cursorX, cursorY); - button.show(); - // Clicking on a flyout button or label is a lot like clicking on the - // flyout background. - this.listeners_.push(Blockly.bindEventWithChecks_(buttonSvg, 'mousedown', - this, this.onMouseDown_)); - - - this.buttons_.push(button); - cursorX += (button.width + gaps[i]); - } - } -}; - -/** - * Determine if a drag delta is toward the workspace, based on the position - * and orientation of the flyout. This to decide if a new block should be - * created or if the flyout should scroll. - * @param {!goog.math.Coordinate} currentDragDeltaXY How far the pointer has - * moved from the position at mouse down, in pixel units. - * @return {boolean} true if the drag is toward the workspace. - * @package - */ -Blockly.HorizontalFlyout.prototype.isDragTowardWorkspace = function(currentDragDeltaXY) { - var dx = currentDragDeltaXY.x; - var dy = currentDragDeltaXY.y; - // Direction goes from -180 to 180, with 0 toward the right and 90 on top. - var dragDirection = Math.atan2(dy, dx) / Math.PI * 180; - - var draggingTowardWorkspace = false; - var range = this.dragAngleRange_; - if (this.toolboxPosition_ == Blockly.TOOLBOX_AT_TOP) { - // Horizontal at top. - if (dragDirection < 90 + range && dragDirection > 90 - range) { - draggingTowardWorkspace = true; - } - } else { - // Horizontal at bottom. - if (dragDirection > -90 - range && dragDirection < -90 + range) { - draggingTowardWorkspace = true; - } - } - return draggingTowardWorkspace; -}; - -/** - * Return the deletion rectangle for this flyout in viewport coordinates. - * @return {goog.math.Rect} Rectangle in which to delete. - */ -Blockly.HorizontalFlyout.prototype.getClientRect = function() { - if (!this.svgGroup_) { - return null; - } - - var flyoutRect = this.svgGroup_.getBoundingClientRect(); - // BIG_NUM is offscreen padding so that blocks dragged beyond the shown flyout - // area are still deleted. Must be larger than the largest screen size, - // but be smaller than half Number.MAX_SAFE_INTEGER (not available on IE). - var BIG_NUM = 1000000000; - var y = flyoutRect.top; - var height = flyoutRect.height; - - if (this.toolboxPosition_ == Blockly.TOOLBOX_AT_TOP) { - return new goog.math.Rect(-BIG_NUM, y - BIG_NUM, BIG_NUM * 2, - BIG_NUM + height); - } else if (this.toolboxPosition_ == Blockly.TOOLBOX_AT_BOTTOM) { - return new goog.math.Rect(-BIG_NUM, y, BIG_NUM * 2, - BIG_NUM + height); - } -}; - -/** - * Compute height of flyout. Position button under each block. - * For RTL: Lay out the blocks right-aligned. - * @param {!Array} blocks The blocks to reflow. - */ -Blockly.HorizontalFlyout.prototype.reflowInternal_ = function(blocks) { - this.workspace_.scale = this.targetWorkspace_.scale; - var flyoutHeight = 0; - for (var i = 0, block; block = blocks[i]; i++) { - flyoutHeight = Math.max(flyoutHeight, block.getHeightWidth().height); - } - flyoutHeight += this.MARGIN * 1.5; - flyoutHeight *= this.workspace_.scale; - flyoutHeight += Blockly.Scrollbar.scrollbarThickness; - if (this.height_ != flyoutHeight) { - for (var i = 0, block; block = blocks[i]; i++) { - var blockHW = block.getHeightWidth(); - if (block.flyoutRect_) { - block.flyoutRect_.setAttribute('width', blockHW.width); - block.flyoutRect_.setAttribute('height', blockHW.height); - // Rectangles behind blocks with output tabs are shifted a bit. - var blockXY = block.getRelativeToSurfaceXY(); - block.flyoutRect_.setAttribute('y', blockXY.y); - block.flyoutRect_.setAttribute('x', - this.RTL ? blockXY.x - blockHW.width : blockXY.x); - // For hat blocks we want to shift them down by the hat height - // since the y coordinate is the corner, not the top of the hat. - var hatOffset = - block.startHat_ ? Blockly.BlockSvg.START_HAT_HEIGHT : 0; - if (hatOffset) { - block.moveBy(0, hatOffset); - } - block.flyoutRect_.setAttribute('y', blockXY.y); - } - } - // Record the height for .getMetrics_ and .position. - this.height_ = flyoutHeight; - // Call this since it is possible the trash and zoom buttons need - // to move. e.g. on a bottom positioned flyout when zoom is clicked. - this.targetWorkspace_.resize(); - } -}; diff --git a/core/flyout_vertical.js b/core/flyout_vertical.js deleted file mode 100644 index 8b6a45169c..0000000000 --- a/core/flyout_vertical.js +++ /dev/null @@ -1,770 +0,0 @@ -/** - * @license - * Visual Blocks Editor - * - * Copyright 2017 Google Inc. - * https://developers.google.com/blockly/ - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @fileoverview Layout code for a vertical variant of the flyout. - * @author fenichel@google.com (Rachel Fenichel) - */ -'use strict'; - -goog.provide('Blockly.VerticalFlyout'); - -goog.require('Blockly.Block'); -goog.require('Blockly.Comment'); -goog.require('Blockly.Events'); -goog.require('Blockly.Flyout'); -goog.require('Blockly.FlyoutButton'); -goog.require('Blockly.utils'); -goog.require('Blockly.WorkspaceSvg'); -goog.require('goog.dom'); -goog.require('goog.dom.animationFrame.polyfill'); -goog.require('goog.events'); -goog.require('goog.math.Rect'); -goog.require('goog.userAgent'); - - -/** - * Class for a flyout. - * @param {!Object} workspaceOptions Dictionary of options for the workspace. - * @extends {Blockly.Flyout} - * @constructor - */ -Blockly.VerticalFlyout = function(workspaceOptions) { - workspaceOptions.getMetrics = this.getMetrics_.bind(this); - workspaceOptions.setMetrics = this.setMetrics_.bind(this); - - Blockly.VerticalFlyout.superClass_.constructor.call(this, workspaceOptions); - /** - * Flyout should be laid out vertically. - * @type {boolean} - * @private - */ - this.horizontalLayout_ = false; - - /** - * Map of checkboxes that correspond to monitored blocks. - * Each element is an object containing the SVG for the checkbox, a boolean - * for its checked state, and the block the checkbox is associated with. - * @type {!Object.} - * @private - */ - this.checkboxes_ = {}; -}; -goog.inherits(Blockly.VerticalFlyout, Blockly.Flyout); - -/** - * Does the flyout automatically close when a block is created? - * @type {boolean} - */ -Blockly.VerticalFlyout.prototype.autoClose = false; - -/** - * The width of the flyout, if not otherwise specified. - * @type {number} - */ -Blockly.VerticalFlyout.prototype.DEFAULT_WIDTH = 250; - -/** - * Size of a checkbox next to a variable reporter. - * @type {number} - * @const - */ -Blockly.VerticalFlyout.prototype.CHECKBOX_SIZE = 25; - -/** - * Amount of touchable padding around reporter checkboxes. - * @type {number} - * @const - */ -Blockly.VerticalFlyout.prototype.CHECKBOX_TOUCH_PADDING = 12; - -/** - * SVG path data for checkmark in checkbox. - * @type {string} - * @const - */ -Blockly.VerticalFlyout.prototype.CHECKMARK_PATH = - 'M' + Blockly.VerticalFlyout.prototype.CHECKBOX_SIZE / 4 + - ' ' + Blockly.VerticalFlyout.prototype.CHECKBOX_SIZE / 2 + - 'L' + 5 * Blockly.VerticalFlyout.prototype.CHECKBOX_SIZE / 12 + - ' ' + 2 * Blockly.VerticalFlyout.prototype.CHECKBOX_SIZE / 3 + - 'L' + 3 * Blockly.VerticalFlyout.prototype.CHECKBOX_SIZE / 4 + - ' ' + Blockly.VerticalFlyout.prototype.CHECKBOX_SIZE / 3; - -/** - * Size of the checkbox corner radius - * @type {number} - * @const - */ -Blockly.VerticalFlyout.prototype.CHECKBOX_CORNER_RADIUS = 5; - -/** - * Space above and around the checkbox. - * @type {number} - * @const - */ -Blockly.VerticalFlyout.prototype.CHECKBOX_MARGIN = Blockly.Flyout.prototype.MARGIN; - -/** - * Total additional width of a row that contains a checkbox. - * @type {number} - * @const - */ -Blockly.VerticalFlyout.prototype.CHECKBOX_SPACE_X = - Blockly.VerticalFlyout.prototype.CHECKBOX_SIZE + - 2 * Blockly.VerticalFlyout.prototype.CHECKBOX_MARGIN; - -/** - * Initializes the flyout. - * @param {!Blockly.Workspace} targetWorkspace The workspace in which to create - * new blocks. - */ -Blockly.VerticalFlyout.prototype.init = function(targetWorkspace) { - Blockly.VerticalFlyout.superClass_.init.call(this, targetWorkspace); - this.workspace_.scale = targetWorkspace.scale; -}; - -/** - * Creates the flyout's DOM. Only needs to be called once. - * @param {string} tagName HTML element - * @return {!Element} The flyout's SVG group. - */ -Blockly.VerticalFlyout.prototype.createDom = function(tagName) { - Blockly.VerticalFlyout.superClass_.createDom.call(this, tagName); - - /* - - - - - - - */ - this.defs_ = Blockly.utils.createSvgElement('defs', {}, this.svgGroup_); - var clipPath = Blockly.utils.createSvgElement('clipPath', - {'id':'blocklyBlockMenuClipPath'}, this.defs_); - this.clipRect_ = Blockly.utils.createSvgElement('rect', - { - 'id': 'blocklyBlockMenuClipRect', - 'height': '0', - 'width': '0', - 'y': '0', - 'x': '0' - }, - clipPath); - this.workspace_.svgGroup_.setAttribute( - 'clip-path', 'url(#blocklyBlockMenuClipPath)'); - - return this.svgGroup_; -}; - -/** - * Calculate the bounding box of the flyout. - * - * @return {Object} Contains the position and size of the bounding - * box containing the elements (blocks, buttons, labels) in the flyout. - */ -Blockly.VerticalFlyout.prototype.getContentBoundingBox_ = function() { - var contentBounds = this.workspace_.getBlocksBoundingBox(); - var bounds = { - xMin: contentBounds.x, - yMin: contentBounds.y, - xMax: contentBounds.x + contentBounds.width, - yMax: contentBounds.y + contentBounds.height - }; - - // Check if any of the buttons/labels are outside the blocks bounding box. - for (var i = 0; i < this.buttons_.length; i ++) { - var button = this.buttons_[i]; - var buttonPosition = button.getPosition(); - if (buttonPosition.x < bounds.xMin) { - bounds.xMin = buttonPosition.x; - } - if (buttonPosition.y < bounds.yMin) { - bounds.yMin = buttonPosition.y; - } - // Button extends past the bounding box to the right. - if (buttonPosition.x + button.width > bounds.xMax) { - bounds.xMax = buttonPosition.x + button.width; - } - - // Button extends past the bounding box on the bottom - if (buttonPosition.y + button.height > bounds.yMax) { - bounds.yMax = buttonPosition.y + button.height; - } - } - - return { - x: bounds.xMin, - y: bounds.yMin, - width: bounds.xMax - bounds.xMin, - height: bounds.yMax - bounds.yMin, - }; -}; - -/** - * Return an object with all the metrics required to size scrollbars for the - * flyout. The following properties are computed: - * .viewHeight: Height of the visible rectangle, - * .viewWidth: Width of the visible rectangle, - * .contentHeight: Height of the contents, - * .contentWidth: Width of the contents, - * .viewTop: Offset of top edge of visible rectangle from parent, - * .contentTop: Offset of the top-most content from the y=0 coordinate, - * .absoluteTop: Top-edge of view. - * .viewLeft: Offset of the left edge of visible rectangle from parent, - * .contentLeft: Offset of the left-most content from the x=0 coordinate, - * .absoluteLeft: Left-edge of view. - * @return {Object} Contains size and position metrics of the flyout. - * @private - */ -Blockly.VerticalFlyout.prototype.getMetrics_ = function() { - if (!this.isVisible()) { - // Flyout is hidden. - return null; - } - - var optionBox = this.getContentBoundingBox_(); - - // Padding for the end of the scrollbar. - var absoluteTop = this.SCROLLBAR_PADDING; - var absoluteLeft = 0; - - var viewHeight = this.height_ - 2 * this.SCROLLBAR_PADDING; - var viewWidth = this.getWidth() - this.SCROLLBAR_PADDING; - - // Add padding to the bottom of the flyout, so we can scroll to the top of - // the last category. - var contentHeight = optionBox.height * this.workspace_.scale; - this.recordCategoryScrollPositions_(); - var bottomPadding = this.MARGIN; - if (this.categoryScrollPositions.length > 0) { - var lastLabel = this.categoryScrollPositions[ - this.categoryScrollPositions.length - 1]; - var lastPos = lastLabel.position * this.workspace_.scale; - var lastCategoryHeight = contentHeight - lastPos; - if (lastCategoryHeight < viewHeight) { - bottomPadding = viewHeight - lastCategoryHeight; - } - } - - var metrics = { - viewHeight: viewHeight, - viewWidth: viewWidth, - contentHeight: contentHeight + bottomPadding, - contentWidth: optionBox.width * this.workspace_.scale + 2 * this.MARGIN, - viewTop: -this.workspace_.scrollY + optionBox.y, - viewLeft: -this.workspace_.scrollX, - contentTop: optionBox.y, - contentLeft: optionBox.x, - absoluteTop: absoluteTop, - absoluteLeft: absoluteLeft - }; - return metrics; -}; - -/** - * Sets the translation of the flyout to match the scrollbars. - * @param {!Object} xyRatio Contains a y property which is a float - * between 0 and 1 specifying the degree of scrolling and a - * similar x property. - * @private - */ -Blockly.VerticalFlyout.prototype.setMetrics_ = function(xyRatio) { - var metrics = this.getMetrics_(); - // This is a fix to an apparent race condition. - if (!metrics) { - return; - } - if (goog.isNumber(xyRatio.y)) { - this.workspace_.scrollY = -metrics.contentHeight * xyRatio.y; - } - this.workspace_.translate(this.workspace_.scrollX + metrics.absoluteLeft, - this.workspace_.scrollY + metrics.absoluteTop); - - this.clipRect_.setAttribute('height', Math.max(0, metrics.viewHeight) + 'px'); - this.clipRect_.setAttribute('width', metrics.viewWidth + 'px'); - - if (this.categoryScrollPositions) { - this.selectCategoryByScrollPosition(-this.workspace_.scrollY); - } -}; - -/** - * Move the flyout to the edge of the workspace. - */ -Blockly.VerticalFlyout.prototype.position = function() { - if (!this.isVisible()) { - return; - } - var targetWorkspaceMetrics = this.targetWorkspace_.getMetrics(); - if (!targetWorkspaceMetrics) { - // Hidden components will return null. - return; - } - - // This version of the flyout does not change width to fit its contents. - // Instead it matches the width of its parent or uses a default value. - this.width_ = this.getWidth(); - - if (this.parentToolbox_) { - var toolboxWidth = this.parentToolbox_.getWidth(); - var categoryWidth = toolboxWidth - this.width_; - var x = this.toolboxPosition_ == Blockly.TOOLBOX_AT_RIGHT ? - targetWorkspaceMetrics.viewWidth : categoryWidth; - var y = 0; - } else { - var x = this.toolboxPosition_ == Blockly.TOOLBOX_AT_RIGHT ? - targetWorkspaceMetrics.viewWidth - this.width_ : 0; - var y = 0; - } - - // Record the height for Blockly.Flyout.getMetrics_ - this.height_ = Math.max(0, targetWorkspaceMetrics.viewHeight - y); - - this.setBackgroundPath_(this.width_, this.height_); - - this.svgGroup_.setAttribute("width", this.width_); - this.svgGroup_.setAttribute("height", this.height_); - var transform = 'translate(' + x + 'px,' + y + 'px)'; - Blockly.utils.setCssTransform(this.svgGroup_, transform); - - // Update the scrollbar (if one exists). - if (this.scrollbar_) { - // Set the scrollbars origin to be the top left of the flyout. - this.scrollbar_.setOrigin(x, y); - this.scrollbar_.resize(); - } - // The blocks need to be visible in order to be laid out and measured - // correctly, but we don't want the flyout to show up until it's properly - // sized. Opacity is set to zero in show(). - this.svgGroup_.style.opacity = 1; -}; - -/** - * Create and set the path for the visible boundaries of the flyout. - * @param {number} width The width of the flyout, not including the - * rounded corners. - * @param {number} height The height of the flyout, not including - * rounded corners. - * @private - */ -Blockly.VerticalFlyout.prototype.setBackgroundPath_ = function(width, height) { - var atRight = this.toolboxPosition_ == Blockly.TOOLBOX_AT_RIGHT; - // Decide whether to start on the left or right. - var path = ['M ' + 0 + ',0']; - // Top. - path.push('h', width); - // Rounded corner. - path.push('a', this.CORNER_RADIUS, this.CORNER_RADIUS, 0, 0, - atRight ? 0 : 1, - atRight ? -this.CORNER_RADIUS : this.CORNER_RADIUS, - this.CORNER_RADIUS); - // Side closest to workspace. - path.push('v', Math.max(0, height - this.CORNER_RADIUS * 2)); - // Rounded corner. - path.push('a', this.CORNER_RADIUS, this.CORNER_RADIUS, 0, 0, - atRight ? 0 : 1, - atRight ? this.CORNER_RADIUS : -this.CORNER_RADIUS, - this.CORNER_RADIUS); - // Bottom. - path.push('h', -width); - path.push('z'); - this.svgBackground_.setAttribute('d', path.join(' ')); -}; - -/** - * Scroll the flyout to the top. - */ -Blockly.VerticalFlyout.prototype.scrollToStart = function() { - this.scrollbar_.set(0); -}; - -/** - * Scroll the flyout to a position. - * @param {number} pos The targeted scroll position in workspace coordinates. - * @package - */ -Blockly.VerticalFlyout.prototype.scrollTo = function(pos) { - this.scrollTarget = pos * this.workspace_.scale; - - // Make sure not to set the scroll target below the lowest point we can - // scroll to, i.e. the content height minus the view height - var metrics = this.workspace_.getMetrics(); - var contentHeight = metrics.contentHeight; - var viewHeight = metrics.viewHeight; - this.scrollTarget = Math.min(this.scrollTarget, contentHeight - viewHeight); - - this.stepScrollAnimation(); -}; - -/** - * Scroll the flyout. - * @param {!Event} e Mouse wheel scroll event. - * @private - */ -Blockly.VerticalFlyout.prototype.wheel_ = function(e) { - // remove scrollTarget to stop auto scrolling in stepScrollAnimation - this.scrollTarget = null; - - var delta = e.deltaY; - - if (delta) { - // Firefox's mouse wheel deltas are a tenth that of Chrome/Safari. - // DeltaMode is 1 for a mouse wheel, but not for a trackpad scroll event - if (goog.userAgent.GECKO && (e.deltaMode === 1)) { - delta *= 10; - } - var metrics = this.getMetrics_(); - var pos = (metrics.viewTop - metrics.contentTop) + delta; - var limit = metrics.contentHeight - metrics.viewHeight; - pos = Math.min(pos, limit); - pos = Math.max(pos, 0); - this.scrollbar_.set(pos); - // When the flyout moves from a wheel event, hide WidgetDiv and DropDownDiv. - Blockly.WidgetDiv.hide(true); - Blockly.DropDownDiv.hideWithoutAnimation(); - } - - // Don't scroll the page. - e.preventDefault(); - // Don't propagate mousewheel event (zooming). - e.stopPropagation(); -}; - -/** - * Delete blocks and background buttons from a previous showing of the flyout. - * @private - */ -Blockly.VerticalFlyout.prototype.clearOldBlocks_ = function() { - Blockly.VerticalFlyout.superClass_.clearOldBlocks_.call(this); - - // Do the same for checkboxes. - for (var checkboxId in this.checkboxes_) { - if (!Object.prototype.hasOwnProperty.call(this.checkboxes_, checkboxId)) { - continue; - } - var checkbox = this.checkboxes_[checkboxId]; - checkbox.block.flyoutCheckbox = null; - goog.dom.removeNode(checkbox.svgRoot); - } - this.checkboxes_ = {}; -}; - -/** - * Add listeners to a block that has been added to the flyout. - * @param {Element} root The root node of the SVG group the block is in. - * @param {!Blockly.Block} block The block to add listeners for. - * @param {!Element} rect The invisible rectangle under the block that acts as - * a button for that block. - * @private - */ -Blockly.VerticalFlyout.prototype.addBlockListeners_ = function(root, block, - rect) { - Blockly.VerticalFlyout.superClass_.addBlockListeners_.call(this, root, block, - rect); - if (block.flyoutCheckbox) { - this.listeners_.push(Blockly.bindEvent_(block.flyoutCheckbox.svgRoot, - 'mousedown', null, this.checkboxClicked_(block.flyoutCheckbox))); - } -}; - -/** - * Lay out the blocks in the flyout. - * @param {!Array.} contents The blocks and buttons to lay out. - * @param {!Array.} gaps The visible gaps between blocks. - * @private - */ -Blockly.VerticalFlyout.prototype.layout_ = function(contents, gaps) { - var margin = this.MARGIN; - var flyoutWidth = this.getWidth() / this.workspace_.scale; - var cursorX = margin; - var cursorY = margin; - - for (var i = 0, item; item = contents[i]; i++) { - if (item.type == 'block') { - var block = item.block; - var allBlocks = block.getDescendants(false); - for (var j = 0, child; child = allBlocks[j]; j++) { - // Mark blocks as being inside a flyout. This is used to detect and - // prevent the closure of the flyout if the user right-clicks on such a - // block. - child.isInFlyout = true; - } - var root = block.getSvgRoot(); - var blockHW = block.getHeightWidth(); - - // Figure out where the block goes, taking into account its size, whether - // we're in RTL mode, and whether it has a checkbox. - var oldX = block.getRelativeToSurfaceXY().x; - var newX = flyoutWidth - this.MARGIN; - - var moveX = this.RTL ? newX - oldX : margin; - if (block.hasCheckboxInFlyout()) { - this.createCheckbox_(block, cursorX, cursorY, blockHW); - if (this.RTL) { - moveX -= (this.CHECKBOX_SIZE + this.CHECKBOX_MARGIN); - } else { - moveX += this.CHECKBOX_SIZE + this.CHECKBOX_MARGIN; - } - } - - // The block moves a bit extra for the hat, but the block's rectangle - // doesn't. That's because the hat actually extends up from 0. - block.moveBy(moveX, - cursorY + (block.startHat_ ? Blockly.BlockSvg.START_HAT_HEIGHT : 0)); - - var rect = this.createRect_(block, this.RTL ? moveX - blockHW.width : moveX, cursorY, blockHW, i); - - this.addBlockListeners_(root, block, rect); - - cursorY += blockHW.height + gaps[i] + (block.startHat_ ? Blockly.BlockSvg.START_HAT_HEIGHT : 0); - } else if (item.type == 'button') { - var button = item.button; - var buttonSvg = button.createDom(); - if (this.RTL) { - button.moveTo(flyoutWidth - this.MARGIN - button.width, cursorY); - } else { - button.moveTo(cursorX, cursorY); - } - button.show(); - // Clicking on a flyout button or label is a lot like clicking on the - // flyout background. - this.listeners_.push(Blockly.bindEventWithChecks_( - buttonSvg, 'mousedown', this, this.onMouseDown_)); - - this.buttons_.push(button); - cursorY += button.height + gaps[i]; - } - } -}; - -/** - * Create and place a rectangle corresponding to the given block. - * @param {!Blockly.Block} block The block to associate the rect to. - * @param {number} x The x position of the cursor during this layout pass. - * @param {number} y The y position of the cursor during this layout pass. - * @param {!{height: number, width: number}} blockHW The height and width of the - * block. - * @param {number} index The index into the background buttons list where this - * rect should be placed. - * @return {!SVGElement} Newly created SVG element for the rectangle behind the - * block. - * @private - */ -Blockly.VerticalFlyout.prototype.createRect_ = function(block, x, y, - blockHW, index) { - // Create an invisible rectangle under the block to act as a button. Just - // using the block as a button is poor, since blocks have holes in them. - var rect = Blockly.utils.createSvgElement('rect', - { - 'fill-opacity': 0, - 'x': x, - 'y': y, - 'height': blockHW.height, - 'width': blockHW.width - }, null); - rect.tooltip = block; - Blockly.Tooltip.bindMouseEvents(rect); - // Add the rectangles under the blocks, so that the blocks' tooltips work. - this.workspace_.getCanvas().insertBefore(rect, block.getSvgRoot()); - - block.flyoutRect_ = rect; - this.backgroundButtons_[index] = rect; - return rect; -}; - -/** - * Create and place a checkbox corresponding to the given block. - * @param {!Blockly.Block} block The block to associate the checkbox to. - * @param {number} cursorX The x position of the cursor during this layout pass. - * @param {number} cursorY The y position of the cursor during this layout pass. - * @param {!{height: number, width: number}} blockHW The height and width of the - * block. - * @private - */ -Blockly.VerticalFlyout.prototype.createCheckbox_ = function(block, cursorX, - cursorY, blockHW) { - var checkboxState = Blockly.VerticalFlyout.getCheckboxState(block.id); - var svgRoot = block.getSvgRoot(); - var extraSpace = this.CHECKBOX_SIZE + this.CHECKBOX_MARGIN; - var width = this.RTL ? this.getWidth() / this.workspace_.scale - extraSpace : cursorX; - var height = cursorY + blockHW.height / 2 - this.CHECKBOX_SIZE / 2; - var touchMargin = this.CHECKBOX_TOUCH_PADDING; - var checkboxGroup = Blockly.utils.createSvgElement('g', - { - 'transform': 'translate(' + width + ', ' + height + ')' - }, null); - Blockly.utils.createSvgElement('rect', - { - 'class': 'blocklyFlyoutCheckbox', - 'height': this.CHECKBOX_SIZE, - 'width': this.CHECKBOX_SIZE, - 'rx': this.CHECKBOX_CORNER_RADIUS, - 'ry': this.CHECKBOX_CORNER_RADIUS - }, checkboxGroup); - Blockly.utils.createSvgElement('path', - { - 'class': 'blocklyFlyoutCheckboxPath', - 'd': this.CHECKMARK_PATH - }, checkboxGroup); - Blockly.utils.createSvgElement('rect', - { - 'class': 'blocklyTouchTargetBackground', - 'x': -touchMargin + 'px', - 'y': -touchMargin + 'px', - 'height': this.CHECKBOX_SIZE + 2 * touchMargin, - 'width': this.CHECKBOX_SIZE + 2 * touchMargin, - }, checkboxGroup); - var checkboxObj = {svgRoot: checkboxGroup, clicked: checkboxState, block: block}; - - if (checkboxState) { - Blockly.utils.addClass((checkboxObj.svgRoot), 'checked'); - } - - block.flyoutCheckbox = checkboxObj; - this.workspace_.getCanvas().insertBefore(checkboxGroup, svgRoot); - this.checkboxes_[block.id] = checkboxObj; -}; - -/** - * Respond to a click on a checkbox in the flyout. - * @param {!Object} checkboxObj An object containing the svg element of the - * checkbox, a boolean for the state of the checkbox, and the block the - * checkbox is associated with. - * @return {!Function} Function to call when checkbox is clicked. - * @private - */ -Blockly.VerticalFlyout.prototype.checkboxClicked_ = function(checkboxObj) { - return function(e) { - this.setCheckboxState(checkboxObj.block.id, !checkboxObj.clicked); - // This event has been handled. No need to bubble up to the document. - e.stopPropagation(); - e.preventDefault(); - }.bind(this); -}; - -/** - * Set the state of a checkbox by block ID. - * @param {string} blockId ID of the block whose checkbox should be set - * @param {boolean} value Value to set the checkbox to. - * @public - */ -Blockly.VerticalFlyout.prototype.setCheckboxState = function(blockId, value) { - var checkboxObj = this.checkboxes_[blockId]; - if (!checkboxObj || checkboxObj.clicked === value) { - return; - } - - var oldValue = checkboxObj.clicked; - checkboxObj.clicked = value; - - if (checkboxObj.clicked) { - Blockly.utils.addClass(checkboxObj.svgRoot, 'checked'); - } else { - Blockly.utils.removeClass(checkboxObj.svgRoot, 'checked'); - } - - Blockly.Events.fire(new Blockly.Events.Change( - checkboxObj.block, 'checkbox', null, oldValue, value)); -}; - -/** - * Determine if a drag delta is toward the workspace, based on the position - * and orientation of the flyout. This to decide if a new block should be - * created or if the flyout should scroll. - * @param {!goog.math.Coordinate} currentDragDeltaXY How far the pointer has - * moved from the position at mouse down, in pixel units. - * @return {boolean} true if the drag is toward the workspace. - * @package - */ -Blockly.VerticalFlyout.prototype.isDragTowardWorkspace = function(currentDragDeltaXY) { - var dx = currentDragDeltaXY.x; - var dy = currentDragDeltaXY.y; - // Direction goes from -180 to 180, with 0 toward the right and 90 on top. - var dragDirection = Math.atan2(dy, dx) / Math.PI * 180; - - var draggingTowardWorkspace = false; - var range = this.dragAngleRange_; - if (this.toolboxPosition_ == Blockly.TOOLBOX_AT_LEFT) { - // Vertical at left. - if (dragDirection < range && dragDirection > -range) { - draggingTowardWorkspace = true; - } - } else { - // Vertical at right. - if (dragDirection < -180 + range || dragDirection > 180 - range) { - draggingTowardWorkspace = true; - } - } - return draggingTowardWorkspace; -}; - -/** - * Return the deletion rectangle for this flyout in viewport coordinates. - * Deletion area is the height of the flyout, but extends to the left (in LTR) - * by a lot in order to allow for deleting blocks when dragged beyond the left - * window edge. In RTL, the delete area extends off to the right. - * The top/bottom do not extend to allow dragging blocks outside of the workspace - * to be dropped (e.g. to the backpack). - * @return {goog.math.Rect} Rectangle in which to delete. - */ -Blockly.VerticalFlyout.prototype.getClientRect = function() { - if (!this.svgGroup_) { - return null; - } - - var flyoutRect = this.svgGroup_.getBoundingClientRect(); - // BIG_NUM is offscreen padding so that blocks dragged beyond the shown flyout - // area are still deleted. Must be larger than the largest screen size, - // but be smaller than half Number.MAX_SAFE_INTEGER (not available on IE). - var BIG_NUM = 1000000000; - var x = flyoutRect.left; - var y = flyoutRect.top; - var width = flyoutRect.width; - var height = flyoutRect.height; - - if (this.toolboxPosition_ == Blockly.TOOLBOX_AT_LEFT) { - return new goog.math.Rect(x - BIG_NUM, y, BIG_NUM + width, height); - } else { // Right - return new goog.math.Rect(x, y, BIG_NUM + width, height); - } -}; - -/** - * Compute width of flyout. Position button under each block. - * For RTL: Lay out the blocks right-aligned. - * @param {!Array} blocks The blocks to reflow. - */ -Blockly.VerticalFlyout.prototype.reflowInternal_ = function(/* blocks */) { - // This is a no-op because the flyout is a fixed size. - return; -}; - -/** - * Gets the checkbox state for a block - * @param {string} blockId The ID of the block in question. - * @return {boolean} Whether the block is checked. - * @public - */ -Blockly.VerticalFlyout.getCheckboxState = function(/* blockId */) { - return false; -}; diff --git a/core/generator.js b/core/generator.js deleted file mode 100644 index b567304f83..0000000000 --- a/core/generator.js +++ /dev/null @@ -1,426 +0,0 @@ -/** - * @license - * Visual Blocks Editor - * - * Copyright 2012 Google Inc. - * https://developers.google.com/blockly/ - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @fileoverview Utility functions for generating executable code from - * Blockly code. - * @author fraser@google.com (Neil Fraser) - */ -'use strict'; - -goog.provide('Blockly.Generator'); - -goog.require('Blockly.Block'); -goog.require('goog.asserts'); - - -/** - * Class for a code generator that translates the blocks into a language. - * @param {string} name Language name of this generator. - * @constructor - */ -Blockly.Generator = function(name) { - this.name_ = name; - this.FUNCTION_NAME_PLACEHOLDER_REGEXP_ = - new RegExp(this.FUNCTION_NAME_PLACEHOLDER_, 'g'); -}; - -/** - * Category to separate generated function names from variables and procedures. - */ -Blockly.Generator.NAME_TYPE = 'generated_function'; - -/** - * Arbitrary code to inject into locations that risk causing infinite loops. - * Any instances of '%1' will be replaced by the block ID that failed. - * E.g. ' checkTimeout(%1);\n' - * @type {?string} - */ -Blockly.Generator.prototype.INFINITE_LOOP_TRAP = null; - -/** - * Arbitrary code to inject before every statement. - * Any instances of '%1' will be replaced by the block ID of the statement. - * E.g. 'highlight(%1);\n' - * @type {?string} - */ -Blockly.Generator.prototype.STATEMENT_PREFIX = null; - -/** - * The method of indenting. Defaults to two spaces, but language generators - * may override this to increase indent or change to tabs. - * @type {string} - */ -Blockly.Generator.prototype.INDENT = ' '; - -/** - * Maximum length for a comment before wrapping. Does not account for - * indenting level. - * @type {number} - */ -Blockly.Generator.prototype.COMMENT_WRAP = 60; - -/** - * List of outer-inner pairings that do NOT require parentheses. - * @type {!Array.>} - */ -Blockly.Generator.prototype.ORDER_OVERRIDES = []; - -/** - * Generate code for all blocks in the workspace to the specified language. - * @param {Blockly.Workspace} workspace Workspace to generate code from. - * @return {string} Generated code. - */ -Blockly.Generator.prototype.workspaceToCode = function(workspace) { - if (!workspace) { - // Backwards compatibility from before there could be multiple workspaces. - console.warn('No workspace specified in workspaceToCode call. Guessing.'); - workspace = Blockly.getMainWorkspace(); - } - var code = []; - this.init(workspace); - var blocks = workspace.getTopBlocks(true); - for (var x = 0, block; block = blocks[x]; x++) { - var line = this.blockToCode(block); - if (goog.isArray(line)) { - // Value blocks return tuples of code and operator order. - // Top-level blocks don't care about operator order. - line = line[0]; - } - if (line) { - if (block.outputConnection && this.scrubNakedValue) { - // This block is a naked value. Ask the language's code generator if - // it wants to append a semicolon, or something. - line = this.scrubNakedValue(line); - } - code.push(line); - } - } - code = code.join('\n'); // Blank line between each section. - code = this.finish(code); - // Final scrubbing of whitespace. - code = code.replace(/^\s+\n/, ''); - code = code.replace(/\n\s+$/, '\n'); - code = code.replace(/[ \t]+\n/g, '\n'); - return code; -}; - -// The following are some helpful functions which can be used by multiple -// languages. - -/** - * Prepend a common prefix onto each line of code. - * @param {string} text The lines of code. - * @param {string} prefix The common prefix. - * @return {string} The prefixed lines of code. - */ -Blockly.Generator.prototype.prefixLines = function(text, prefix) { - return prefix + text.replace(/(?!\n$)\n/g, '\n' + prefix); -}; - -/** - * Recursively spider a tree of blocks, returning all their comments. - * @param {!Blockly.Block} block The block from which to start spidering. - * @return {string} Concatenated list of comments. - */ -Blockly.Generator.prototype.allNestedComments = function(block) { - var comments = []; - var blocks = block.getDescendants(true); - for (var i = 0; i < blocks.length; i++) { - var comment = blocks[i].getCommentText(); - if (comment) { - comments.push(comment); - } - } - // Append an empty string to create a trailing line break when joined. - if (comments.length) { - comments.push(''); - } - return comments.join('\n'); -}; - -/** - * Generate code for the specified block (and attached blocks). - * @param {Blockly.Block} block The block to generate code for. - * @return {string|!Array} For statement blocks, the generated code. - * For value blocks, an array containing the generated code and an - * operator order value. Returns '' if block is null. - */ -Blockly.Generator.prototype.blockToCode = function(block) { - if (!block) { - return ''; - } - if (block.disabled) { - // Skip past this block if it is disabled. - return this.blockToCode(block.getNextBlock()); - } - - var func = this[block.type]; - goog.asserts.assertFunction(func, - 'Language "%s" does not know how to generate code for block type "%s".', - this.name_, block.type); - // First argument to func.call is the value of 'this' in the generator. - // Prior to 24 September 2013 'this' was the only way to access the block. - // The current prefered method of accessing the block is through the second - // argument to func.call, which becomes the first parameter to the generator. - var code = func.call(block, block); - if (goog.isArray(code)) { - // Value blocks return tuples of code and operator order. - goog.asserts.assert(block.outputConnection, - 'Expecting string from statement block "%s".', block.type); - return [this.scrub_(block, code[0]), code[1]]; - } else if (goog.isString(code)) { - var id = block.id.replace(/\$/g, '$$$$'); // Issue 251. - if (this.STATEMENT_PREFIX) { - code = this.STATEMENT_PREFIX.replace(/%1/g, '\'' + id + '\'') + - code; - } - return this.scrub_(block, code); - } else if (code === null) { - // Block has handled code generation itself. - return ''; - } else { - goog.asserts.fail('Invalid code generated: %s', code); - } -}; - -/** - * Generate code representing the specified value input. - * @param {!Blockly.Block} block The block containing the input. - * @param {string} name The name of the input. - * @param {number} outerOrder The maximum binding strength (minimum order value) - * of any operators adjacent to "block". - * @return {string} Generated code or '' if no blocks are connected or the - * specified input does not exist. - */ -Blockly.Generator.prototype.valueToCode = function(block, name, outerOrder) { - if (isNaN(outerOrder)) { - goog.asserts.fail('Expecting valid order from block "%s".', block.type); - } - var targetBlock = block.getInputTargetBlock(name); - if (!targetBlock) { - return ''; - } - var tuple = this.blockToCode(targetBlock); - if (tuple === '') { - // Disabled block. - return ''; - } - // Value blocks must return code and order of operations info. - // Statement blocks must only return code. - goog.asserts.assertArray(tuple, 'Expecting tuple from value block "%s".', - targetBlock.type); - var code = tuple[0]; - var innerOrder = tuple[1]; - if (isNaN(innerOrder)) { - goog.asserts.fail('Expecting valid order from value block "%s".', - targetBlock.type); - } - if (!code) { - return ''; - } - - // Add parentheses if needed. - var parensNeeded = false; - var outerOrderClass = Math.floor(outerOrder); - var innerOrderClass = Math.floor(innerOrder); - if (outerOrderClass <= innerOrderClass) { - if (outerOrderClass == innerOrderClass && - (outerOrderClass == 0 || outerOrderClass == 99)) { - // Don't generate parens around NONE-NONE and ATOMIC-ATOMIC pairs. - // 0 is the atomic order, 99 is the none order. No parentheses needed. - // In all known languages multiple such code blocks are not order - // sensitive. In fact in Python ('a' 'b') 'c' would fail. - } else { - // The operators outside this code are stronger than the operators - // inside this code. To prevent the code from being pulled apart, - // wrap the code in parentheses. - parensNeeded = true; - // Check for special exceptions. - for (var i = 0; i < this.ORDER_OVERRIDES.length; i++) { - if (this.ORDER_OVERRIDES[i][0] == outerOrder && - this.ORDER_OVERRIDES[i][1] == innerOrder) { - parensNeeded = false; - break; - } - } - } - } - if (parensNeeded) { - // Technically, this should be handled on a language-by-language basis. - // However all known (sane) languages use parentheses for grouping. - code = '(' + code + ')'; - } - return code; -}; - -/** - * Generate code representing the statement. Indent the code. - * @param {!Blockly.Block} block The block containing the input. - * @param {string} name The name of the input. - * @return {string} Generated code or '' if no blocks are connected. - */ -Blockly.Generator.prototype.statementToCode = function(block, name) { - var targetBlock = block.getInputTargetBlock(name); - var code = this.blockToCode(targetBlock); - // Value blocks must return code and order of operations info. - // Statement blocks must only return code. - goog.asserts.assertString(code, 'Expecting code from statement block "%s".', - targetBlock && targetBlock.type); - if (code) { - code = this.prefixLines(/** @type {string} */ (code), this.INDENT); - } - return code; -}; - -/** - * Add an infinite loop trap to the contents of a loop. - * If loop is empty, add a statment prefix for the loop block. - * @param {string} branch Code for loop contents. - * @param {string} id ID of enclosing block. - * @return {string} Loop contents, with infinite loop trap added. - */ -Blockly.Generator.prototype.addLoopTrap = function(branch, id) { - id = id.replace(/\$/g, '$$$$'); // Issue 251. - if (this.INFINITE_LOOP_TRAP) { - branch = this.INFINITE_LOOP_TRAP.replace(/%1/g, '\'' + id + '\'') + branch; - } - if (this.STATEMENT_PREFIX) { - branch += this.prefixLines(this.STATEMENT_PREFIX.replace(/%1/g, - '\'' + id + '\''), this.INDENT); - } - return branch; -}; - -/** - * Comma-separated list of reserved words. - * @type {string} - * @private - */ -Blockly.Generator.prototype.RESERVED_WORDS_ = ''; - -/** - * Add one or more words to the list of reserved words for this language. - * @param {string} words Comma-separated list of words to add to the list. - * No spaces. Duplicates are ok. - */ -Blockly.Generator.prototype.addReservedWords = function(words) { - this.RESERVED_WORDS_ += words + ','; -}; - -/** - * This is used as a placeholder in functions defined using - * Blockly.Generator.provideFunction_. It must not be legal code that could - * legitimately appear in a function definition (or comment), and it must - * not confuse the regular expression parser. - * @type {string} - * @private - */ -Blockly.Generator.prototype.FUNCTION_NAME_PLACEHOLDER_ = '{leCUI8hutHZI4480Dc}'; - -/** - * Define a function to be included in the generated code. - * The first time this is called with a given desiredName, the code is - * saved and an actual name is generated. Subsequent calls with the - * same desiredName have no effect but have the same return value. - * - * It is up to the caller to make sure the same desiredName is not - * used for different code values. - * - * The code gets output when Blockly.Generator.finish() is called. - * - * @param {string} desiredName The desired name of the function (e.g., isPrime). - * @param {!Array.} code A list of statements. Use ' ' for indents. - * @return {string} The actual name of the new function. This may differ - * from desiredName if the former has already been taken by the user. - * @private - */ -Blockly.Generator.prototype.provideFunction_ = function(desiredName, code) { - if (!this.definitions_[desiredName]) { - var functionName = this.variableDB_.getDistinctName(desiredName, - Blockly.Procedures.NAME_TYPE); - this.functionNames_[desiredName] = functionName; - var codeText = code.join('\n').replace( - this.FUNCTION_NAME_PLACEHOLDER_REGEXP_, functionName); - // Change all ' ' indents into the desired indent. - // To avoid an infinite loop of replacements, change all indents to '\0' - // character first, then replace them all with the indent. - // We are assuming that no provided functions contain a literal null char. - var oldCodeText; - while (oldCodeText != codeText) { - oldCodeText = codeText; - codeText = codeText.replace(/^(( {2})*) {2}/gm, '$1\0'); - } - codeText = codeText.replace(/\0/g, this.INDENT); - this.definitions_[desiredName] = codeText; - } - return this.functionNames_[desiredName]; -}; - -/** - * Hook for code to run before code generation starts. - * Subclasses may override this, e.g. to initialise the database of variable - * names. - * @param {!Blockly.Workspace} _workspace Workspace to generate code from. - */ -Blockly.Generator.prototype.init = function(_workspace) { - // Optionally override -}; - -/** - * Common tasks for generating code from blocks. This is called from - * blockToCode and is called on every block, not just top level blocks. - * Subclasses may override this, e.g. to generate code for statements following - * the block, or to handle comments for the specified block and any connected - * value blocks. - * @param {!Blockly.Block} _block The current block. - * @param {string} code The JavaScript code created for this block. - * @return {string} JavaScript code with comments and subsequent blocks added. - * @private - */ -Blockly.Generator.prototype.scrub_ = function(_block, code) { - // Optionally override - return code; -}; - -/** - * Hook for code to run at end of code generation. - * Subclasses may override this, e.g. to prepend the generated code with the - * variable definitions. - * @param {string} code Generated code. - * @return {string} Completed code. - */ -Blockly.Generator.prototype.finish = function(code) { - // Optionally override - return code; -}; - -/** - * Naked values are top-level blocks with outputs that aren't plugged into - * anything. - * Subclasses may override this, e.g. if their language does not allow - * naked values. - * @param {string} line Line of generated code. - * @return {string} Legal line of code. - */ -Blockly.Generator.prototype.scrubNakedValue = function(line) { - // Optionally override - return line; -}; diff --git a/core/gesture.js b/core/gesture.js deleted file mode 100644 index 1e9ec9a49d..0000000000 --- a/core/gesture.js +++ /dev/null @@ -1,1011 +0,0 @@ -/** - * @license - * Visual Blocks Editor - * - * Copyright 2017 Google Inc. - * https://developers.google.com/blockly/ - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @fileoverview The class representing an in-progress gesture, usually a drag - * or a tap. - * @author fenichel@google.com (Rachel Fenichel) - */ -'use strict'; - -goog.provide('Blockly.Gesture'); - -goog.require('Blockly.BlockAnimations'); -goog.require('Blockly.BlockDragger'); -goog.require('Blockly.BubbleDragger'); -goog.require('Blockly.constants'); -goog.require('Blockly.Events.Ui'); -goog.require('Blockly.FlyoutDragger'); -goog.require('Blockly.scratchBlocksUtils'); -goog.require('Blockly.Tooltip'); -goog.require('Blockly.Touch'); -goog.require('Blockly.WorkspaceDragger'); - -goog.require('goog.asserts'); -goog.require('goog.math.Coordinate'); - - -/* - * Note: In this file "start" refers to touchstart, mousedown, and pointerstart - * events. "End" refers to touchend, mouseup, and pointerend events. - */ -// TODO: Consider touchcancel/pointercancel. - - -/** - * Class for one gesture. - * @param {!Event} e The event that kicked off this gesture. - * @param {!Blockly.WorkspaceSvg} creatorWorkspace The workspace that created - * this gesture and has a reference to it. - * @constructor - */ -Blockly.Gesture = function(e, creatorWorkspace) { - - /** - * The position of the mouse when the gesture started. Units are css pixels, - * with (0, 0) at the top left of the browser window (mouseEvent clientX/Y). - * @type {goog.math.Coordinate} - */ - this.mouseDownXY_ = null; - - /** - * How far the mouse has moved during this drag, in pixel units. - * (0, 0) is at this.mouseDownXY_. - * @type {goog.math.Coordinate} - * @private - */ - this.currentDragDeltaXY_ = null; - - /** - * The bubble that the gesture started on, or null if it did not start on a - * bubble. - * @type {Blockly.Bubble} - * @private - */ - this.startBubble_ = null; - - /** - * The field that the gesture started on, or null if it did not start on a - * field. - * @type {Blockly.Field} - * @private - */ - this.startField_ = null; - - /** - * The block that the gesture started on, or null if it did not start on a - * block. - * @type {Blockly.BlockSvg} - * @private - */ - this.startBlock_ = null; - - /** - * The block that this gesture targets. If the gesture started on a - * shadow block, this is the first non-shadow parent of the block. If the - * gesture started in the flyout, this is the root block of the block group - * that was clicked or dragged. - * @type {Blockly.BlockSvg} - * @private - */ - this.targetBlock_ = null; - - /** - * The workspace that the gesture started on. There may be multiple - * workspaces on a page; this is more accurate than using - * Blockly.getMainWorkspace(). - * @type {Blockly.WorkspaceSvg} - * @private - */ - this.startWorkspace_ = null; - - /** - * The workspace that created this gesture. This workspace keeps a reference - * to the gesture, which will need to be cleared at deletion. - * This may be different from the start workspace. For instance, a flyout is - * a workspace, but its parent workspace manages gestures for it. - * @type {Blockly.WorkspaceSvg} - * @private - */ - this.creatorWorkspace_ = creatorWorkspace; - - /** - * Whether the pointer has at any point moved out of the drag radius. - * A gesture that exceeds the drag radius is a drag even if it ends exactly at - * its start point. - * @type {boolean} - * @private - */ - this.hasExceededDragRadius_ = false; - - /** - * Whether the workspace is currently being dragged. - * @type {boolean} - * @private - */ - this.isDraggingWorkspace_ = false; - - /** - * Whether the block is currently being dragged. - * @type {boolean} - * @private - */ - this.isDraggingBlock_ = false; - - /** - * Whether the bubble is currently being dragged. - * @type {boolean} - * @private - */ - this.isDraggingBubble_ = false; - - /** - * The event that most recently updated this gesture. - * @type {!Event} - * @private - */ - this.mostRecentEvent_ = e; - - /** - * A handle to use to unbind a mouse move listener at the end of a drag. - * Opaque data returned from Blockly.bindEventWithChecks_. - * @type {Array.} - * @private - */ - this.onMoveWrapper_ = null; - - /** - * A handle to use to unbind a mouse up listener at the end of a drag. - * Opaque data returned from Blockly.bindEventWithChecks_. - * @type {Array.} - * @private - */ - this.onUpWrapper_ = null; - - /** - * The object tracking a bubble drag, or null if none is in progress. - * @type {Blockly.BubbleDragger} - * @private - */ - this.bubbleDragger_ = null; - - /** - * The object tracking a block drag, or null if none is in progress. - * @type {Blockly.BlockDragger} - * @private - */ - this.blockDragger_ = null; - - /** - * The object tracking a workspace or flyout workspace drag, or null if none - * is in progress. - * @type {Blockly.WorkspaceDragger} - * @private - */ - this.workspaceDragger_ = null; - - /** - * The flyout a gesture started in, if any. - * @type {Blockly.Flyout} - * @private - */ - this.flyout_ = null; - - /** - * Boolean for sanity-checking that some code is only called once. - * @type {boolean} - * @private - */ - this.calledUpdateIsDragging_ = false; - - /** - * Boolean for sanity-checking that some code is only called once. - * @type {boolean} - * @private - */ - this.hasStarted_ = false; - - /** - * Boolean used internally to break a cycle in disposal. - * @type {boolean} - * @private - */ - this.isEnding_ = false; - - /** - * True if dragging from the target block should duplicate the target block - * and drag the duplicate instead. This has a lot of side effects. - * @type {boolean} - * @private - */ - this.shouldDuplicateOnDrag_ = false; -}; - -/** - * Sever all links from this object. - * @package - */ -Blockly.Gesture.prototype.dispose = function() { - Blockly.Touch.clearTouchIdentifier(); - Blockly.Tooltip.unblock(); - // Clear the owner's reference to this gesture. - this.creatorWorkspace_.clearGesture(); - - if (this.onMoveWrapper_) { - Blockly.unbindEvent_(this.onMoveWrapper_); - } - if (this.onUpWrapper_) { - Blockly.unbindEvent_(this.onUpWrapper_); - } - - - this.startField_ = null; - this.startBlock_ = null; - this.targetBlock_ = null; - this.startWorkspace_ = null; - this.flyout_ = null; - - if (this.blockDragger_) { - this.blockDragger_.dispose(); - this.blockDragger_ = null; - } - if (this.workspaceDragger_) { - this.workspaceDragger_.dispose(); - this.workspaceDragger_ = null; - } - if (this.bubbleDragger_) { - this.bubbleDragger_.dispose(); - this.bubbleDragger_ = null; - } -}; - -/** - * Update internal state based on an event. - * @param {!Event} e The most recent mouse or touch event. - * @private - */ -Blockly.Gesture.prototype.updateFromEvent_ = function(e) { - var currentXY = new goog.math.Coordinate(e.clientX, e.clientY); - var changed = this.updateDragDelta_(currentXY); - // Exceeded the drag radius for the first time. - if (changed) { - this.updateIsDragging_(); - Blockly.longStop_(); - } - this.mostRecentEvent_ = e; -}; - -/** - * DO MATH to set currentDragDeltaXY_ based on the most recent mouse position. - * @param {!goog.math.Coordinate} currentXY The most recent mouse/pointer - * position, in pixel units, with (0, 0) at the window's top left corner. - * @return {boolean} True if the drag just exceeded the drag radius for the - * first time. - * @private - */ -Blockly.Gesture.prototype.updateDragDelta_ = function(currentXY) { - this.currentDragDeltaXY_ = goog.math.Coordinate.difference(currentXY, - this.mouseDownXY_); - - if (!this.hasExceededDragRadius_) { - var currentDragDelta = goog.math.Coordinate.magnitude( - this.currentDragDeltaXY_); - - // The flyout has a different drag radius from the rest of Blockly. - var limitRadius = this.flyout_ ? Blockly.FLYOUT_DRAG_RADIUS : - Blockly.DRAG_RADIUS; - - this.hasExceededDragRadius_ = currentDragDelta > limitRadius; - return this.hasExceededDragRadius_; - } - return false; -}; - -/** - * Update this gesture to record whether a block is being dragged from the - * flyout. - * This function should be called on a mouse/touch move event the first time the - * drag radius is exceeded. It should be called no more than once per gesture. - * If a block should be dragged from the flyout this function creates the new - * block on the main workspace and updates targetBlock_ and startWorkspace_. - * @return {boolean} True if a block is being dragged from the flyout. - * @private - */ -Blockly.Gesture.prototype.updateIsDraggingFromFlyout_ = function() { - // Disabled blocks may not be dragged from the flyout. - if (this.targetBlock_.disabled) { - return false; - } - if (!this.flyout_.isScrollable() || - this.flyout_.isDragTowardWorkspace(this.currentDragDeltaXY_)) { - this.startWorkspace_ = this.flyout_.targetWorkspace_; - this.startWorkspace_.updateScreenCalculationsIfScrolled(); - // Start the event group now, so that the same event group is used for block - // creation and block dragging. - if (!Blockly.Events.getGroup()) { - Blockly.Events.setGroup(true); - } - // The start block is no longer relevant, because this is a drag. - this.startBlock_ = null; - this.targetBlock_ = this.flyout_.createBlock(this.targetBlock_); - this.targetBlock_.select(); - return true; - } - return false; -}; - -/** - * Update this gesture to record whether a bubble is being dragged. - * This function should be called on a mouse/touch move event the first time the - * drag radius is exceeded. It should be called no more than once per gesture. - * If a bubble should be dragged this function creates the necessary - * BubbleDragger and starts the drag. - * @return {boolean} true if a bubble is being dragged. - * @private - */ -Blockly.Gesture.prototype.updateIsDraggingBubble_ = function() { - if (!this.startBubble_) { - return false; - } - - this.isDraggingBubble_ = true; - this.startDraggingBubble_(); - return true; -}; - -/** - * Update this gesture to record whether a block is being dragged. - * This function should be called on a mouse/touch move event the first time the - * drag radius is exceeded. It should be called no more than once per gesture. - * If a block should be dragged, either from the flyout or in the workspace, - * this function creates the necessary BlockDragger and starts the drag. - * @return {boolean} true if a block is being dragged. - * @private - */ -Blockly.Gesture.prototype.updateIsDraggingBlock_ = function() { - if (!this.targetBlock_) { - return false; - } - - if (this.flyout_) { - this.isDraggingBlock_ = this.updateIsDraggingFromFlyout_(); - } else if (this.targetBlock_.isMovable() || this.shouldDuplicateOnDrag_){ - this.isDraggingBlock_ = true; - } - - if (this.isDraggingBlock_) { - this.startDraggingBlock_(); - return true; - } - return false; -}; - -/** - * Update this gesture to record whether a workspace is being dragged. - * This function should be called on a mouse/touch move event the first time the - * drag radius is exceeded. It should be called no more than once per gesture. - * If a workspace is being dragged this function creates the necessary - * WorkspaceDragger or FlyoutDragger and starts the drag. - * @private - */ -Blockly.Gesture.prototype.updateIsDraggingWorkspace_ = function() { - var wsMovable = this.flyout_ ? this.flyout_.isScrollable() : - this.startWorkspace_ && this.startWorkspace_.isDraggable(); - - if (!wsMovable) { - return; - } - - if (this.flyout_) { - this.workspaceDragger_ = new Blockly.FlyoutDragger(this.flyout_); - } else { - this.workspaceDragger_ = new Blockly.WorkspaceDragger(this.startWorkspace_); - } - - this.isDraggingWorkspace_ = true; - this.workspaceDragger_.startDrag(); -}; - -/** - * Update this gesture to record whether anything is being dragged. - * This function should be called on a mouse/touch move event the first time the - * drag radius is exceeded. It should be called no more than once per gesture. - * @private - */ -Blockly.Gesture.prototype.updateIsDragging_ = function() { - // Sanity check. - goog.asserts.assert(!this.calledUpdateIsDragging_, - 'updateIsDragging_ should only be called once per gesture.'); - this.calledUpdateIsDragging_ = true; - - // First check if it was a bubble drag. Bubbles always sit on top of blocks. - if (this.updateIsDraggingBubble_()) { - return; - } - // Then check if it was a block drag. - if (this.updateIsDraggingBlock_()) { - return; - } - // Then check if it's a workspace drag. - this.updateIsDraggingWorkspace_(); -}; - -/** - * Create a block dragger and start dragging the selected block. - * @private - */ -Blockly.Gesture.prototype.startDraggingBlock_ = function() { - if (this.shouldDuplicateOnDrag_) { - this.duplicateOnDrag_(); - } - this.blockDragger_ = new Blockly.BlockDragger(this.targetBlock_, - this.startWorkspace_); - this.blockDragger_.startBlockDrag(this.currentDragDeltaXY_); - this.blockDragger_.dragBlock(this.mostRecentEvent_, - this.currentDragDeltaXY_); -}; - -/** - * Create a bubble dragger and start dragging the selected bubble. - * TODO (fenichel): Possibly combine this and startDraggingBlock_. - * @private - */ -Blockly.Gesture.prototype.startDraggingBubble_ = function() { - this.bubbleDragger_ = new Blockly.BubbleDragger(this.startBubble_, - this.startWorkspace_); - this.bubbleDragger_.startBubbleDrag(); - this.bubbleDragger_.dragBubble(this.mostRecentEvent_, - this.currentDragDeltaXY_); -}; -/** - * Start a gesture: update the workspace to indicate that a gesture is in - * progress and bind mousemove and mouseup handlers. - * @param {!Event} e A mouse down or touch start event. - * @package - */ -Blockly.Gesture.prototype.doStart = function(e) { - if (Blockly.utils.isTargetInput(e)) { - this.cancel(); - return; - } - this.hasStarted_ = true; - - Blockly.BlockAnimations.disconnectUiStop(); - this.startWorkspace_.updateScreenCalculationsIfScrolled(); - if (this.startWorkspace_.isMutator) { - // Mutator's coordinate system could be out of date because the bubble was - // dragged, the block was moved, the parent workspace zoomed, etc. - this.startWorkspace_.resize(); - } - this.startWorkspace_.markFocused(); - this.mostRecentEvent_ = e; - - // Hide chaff also hides the flyout, so don't do it if the click is in a flyout. - Blockly.hideChaff(!!this.flyout_); - Blockly.Tooltip.block(); - - if (this.targetBlock_) { - this.targetBlock_.select(); - } - - if (Blockly.utils.isRightButton(e)) { - this.handleRightClick(e); - return; - } - - if (goog.string.caseInsensitiveEquals(e.type, 'touchstart')) { - Blockly.longStart_(e, this); - } - - this.mouseDownXY_ = new goog.math.Coordinate(e.clientX, e.clientY); - this.currentDragDeltaXY_ = new goog.math.Coordinate(0, 0); - - this.bindMouseEvents(e); -}; - -/** - * Bind gesture events. - * @param {!Event} e A mouse down or touch start event. - * @package - */ -Blockly.Gesture.prototype.bindMouseEvents = function(e) { - this.onMoveWrapper_ = Blockly.bindEventWithChecks_( - document, 'mousemove', null, this.handleMove.bind(this)); - this.onUpWrapper_ = Blockly.bindEventWithChecks_( - document, 'mouseup', null, this.handleUp.bind(this)); - - e.preventDefault(); - e.stopPropagation(); -}; - -/** - * Handle a mouse move or touch move event. - * @param {!Event} e A mouse move or touch move event. - * @package - */ -Blockly.Gesture.prototype.handleMove = function(e) { - var stopPropagation = true; - this.updateFromEvent_(e); - if (this.isDraggingWorkspace_) { - this.workspaceDragger_.drag(this.currentDragDeltaXY_); - } else if (this.isDraggingBlock_) { - if (this.blockDragger_.dragBlock( - this.mostRecentEvent_, this.currentDragDeltaXY_)) { - stopPropagation = false; - } - } else if (this.isDraggingBubble_) { - this.bubbleDragger_.dragBubble(this.mostRecentEvent_, - this.currentDragDeltaXY_); - } - - if (stopPropagation) { - e.preventDefault(); - e.stopPropagation(); - } -}; - -/** - * Handle a mouse up or touch end event. - * @param {!Event} e A mouse up or touch end event. - * @package - */ -Blockly.Gesture.prototype.handleUp = function(e) { - this.updateFromEvent_(e); - Blockly.longStop_(); - - if (this.isEnding_) { - return; - } - this.isEnding_ = true; - // The ordering of these checks is important: drags have higher priority than - // clicks. Fields have higher priority than blocks; blocks have higher - // priority than workspaces. - // The ordering within drags does not matter, because the three types of - // dragging are exclusive. - if (this.isDraggingBubble_) { - this.bubbleDragger_.endBubbleDrag(e, this.currentDragDeltaXY_); - } else if (this.isDraggingBlock_) { - this.blockDragger_.endBlockDrag(e, this.currentDragDeltaXY_); - } else if (this.isDraggingWorkspace_) { - this.workspaceDragger_.endDrag(this.currentDragDeltaXY_); - } else if (this.isBubbleClick_()) { - // Bubbles are in front of all fields and blocks. - this.doBubbleClick_(); - } else if (this.isFieldClick_()) { - this.doFieldClick_(); - } else if (this.isBlockClick_()) { - this.doBlockClick_(); - } else if (this.isWorkspaceClick_()) { - this.doWorkspaceClick_(); - } - - e.preventDefault(); - e.stopPropagation(); - - this.dispose(); -}; - -/** - * Cancel an in-progress gesture. If a workspace or block drag is in progress, - * end the drag at the most recent location. - * @package - */ -Blockly.Gesture.prototype.cancel = function() { - // Disposing of a block cancels in-progress drags, but dragging to a delete - // area disposes of a block and leads to recursive disposal. Break that cycle. - if (this.isEnding_) { - console.log('Trying to cancel a gesture recursively.'); - return; - } - this.isEnding_ = true; - Blockly.longStop_(); - if (this.isDraggingBubble_) { - this.bubbleDragger_.endBubbleDrag(this.mostRecentEvent_, - this.currentDragDeltaXY_); - } else if (this.isDraggingBlock_) { - this.blockDragger_.endBlockDrag(this.mostRecentEvent_, - this.currentDragDeltaXY_); - } else if (this.isDraggingWorkspace_) { - this.workspaceDragger_.endDrag(this.currentDragDeltaXY_); - } - this.dispose(); -}; - -/** - * Handle a real or faked right-click event by showing a context menu. - * @param {!Event} e A mouse move or touch move event. - * @package - */ -Blockly.Gesture.prototype.handleRightClick = function(e) { - if (this.targetBlock_) { - this.bringBlockToFront_(); - Blockly.hideChaff(this.flyout_); - this.targetBlock_.showContextMenu_(e); - } else if (this.startBubble_) { - this.startBubble_.showContextMenu_(e); - } else if (this.startWorkspace_ && !this.flyout_) { - Blockly.hideChaff(); - this.startWorkspace_.showContextMenu_(e); - } - - // TODO: Handle right-click on a bubble. - e.preventDefault(); - e.stopPropagation(); - - this.dispose(); -}; - -/** - * Handle a mousedown/touchstart event on a workspace. - * @param {!Event} e A mouse down or touch start event. - * @param {!Blockly.Workspace} ws The workspace the event hit. - * @package - */ -Blockly.Gesture.prototype.handleWsStart = function(e, ws) { - goog.asserts.assert(!this.hasStarted_, - 'Tried to call gesture.handleWsStart, but the gesture had already been ' + - 'started.'); - this.setStartWorkspace_(ws); - this.mostRecentEvent_ = e; - this.doStart(e); -}; - -/** - * Handle a mousedown/touchstart event on a flyout. - * @param {!Event} e A mouse down or touch start event. - * @param {!Blockly.Flyout} flyout The flyout the event hit. - * @package - */ -Blockly.Gesture.prototype.handleFlyoutStart = function(e, flyout) { - goog.asserts.assert(!this.hasStarted_, - 'Tried to call gesture.handleFlyoutStart, but the gesture had already ' + - 'been started.'); - this.setStartFlyout_(flyout); - this.handleWsStart(e, flyout.getWorkspace()); -}; - -/** - * Handle a mousedown/touchstart event on a block. - * @param {!Event} e A mouse down or touch start event. - * @param {!Blockly.BlockSvg} block The block the event hit. - * @package - */ -Blockly.Gesture.prototype.handleBlockStart = function(e, block) { - goog.asserts.assert(!this.hasStarted_, - 'Tried to call gesture.handleBlockStart, but the gesture had already ' + - 'been started.'); - this.setStartBlock(block); - this.mostRecentEvent_ = e; -}; - -/** - * Handle a mousedown/touchstart event on a bubble. - * @param {!Event} e A mouse down or touch start event. - * @param {!Blockly.Bubble} bubble The bubble the event hit. - * @package - */ -Blockly.Gesture.prototype.handleBubbleStart = function(e, bubble) { - goog.asserts.assert(!this.hasStarted_, - 'Tried to call gesture.handleBubbleStart, but the gesture had already ' + - 'been started.'); - this.setStartBubble(bubble); - this.mostRecentEvent_ = e; -}; - -/* Begin functions defining what actions to take to execute clicks on each type - * of target. Any developer wanting to add behaviour on clicks should modify - * only this code. */ - -/** - * Execute a bubble click. - * @private - */ -Blockly.Gesture.prototype.doBubbleClick_ = function() { - // TODO (github.com/google/blockly/issues/1673): Consistent handling of single - // clicks. - this.startBubble_.setFocus && this.startBubble_.setFocus(); - this.startBubble_.select && this.startBubble_.select(); -}; - -/** - * Execute a field click. - * @private - */ -Blockly.Gesture.prototype.doFieldClick_ = function() { - this.startField_.showEditor_(); - this.bringBlockToFront_(); -}; - -/** - * Execute a block click. - * @private - */ -Blockly.Gesture.prototype.doBlockClick_ = function() { - // Block click in an autoclosing flyout. - if (this.flyout_ && this.flyout_.autoClose) { - if (!this.targetBlock_.disabled) { - if (!Blockly.Events.getGroup()) { - Blockly.Events.setGroup(true); - } - var newBlock = this.flyout_.createBlock(this.targetBlock_); - newBlock.scheduleSnapAndBump(); - } - } else { - // A field is being edited if either the WidgetDiv or DropDownDiv is currently open. - // If a field is being edited, don't fire any click events. - var fieldEditing = Blockly.WidgetDiv.isVisible() || Blockly.DropDownDiv.isVisible(); - if (!fieldEditing) { - Blockly.Events.fire( - new Blockly.Events.Ui(this.startBlock_, 'click', undefined, undefined)); - // Scratch-specific: also fire a "stack click" event for this stack. - // This is used to toggle the stack when any block in the stack is clicked. - var rootBlock = this.startBlock_.getRootBlock(); - Blockly.Events.fire( - new Blockly.Events.Ui(rootBlock, 'stackclick', undefined, undefined)); - } - } - this.bringBlockToFront_(); - Blockly.Events.setGroup(false); -}; - -/** - * Execute a workspace click. - * @private - */ -Blockly.Gesture.prototype.doWorkspaceClick_ = function() { - if (Blockly.selected) { - Blockly.selected.unselect(); - } -}; - -/* End functions defining what actions to take to execute clicks on each type - * of target. */ - -// TODO (fenichel): Move bubbles to the front. -/** - * Move the dragged/clicked block to the front of the workspace so that it is - * not occluded by other blocks. - * @private - */ -Blockly.Gesture.prototype.bringBlockToFront_ = function() { - // Blocks in the flyout don't overlap, so skip the work. - if (this.targetBlock_ && !this.flyout_) { - this.targetBlock_.bringToFront(); - } -}; - -/* Begin functions for populating a gesture at mouse down. */ - -/** - * Record the field that a gesture started on. - * @param {Blockly.Field} field The field the gesture started on. - * @package - */ -Blockly.Gesture.prototype.setStartField = function(field) { - goog.asserts.assert(!this.hasStarted_, - 'Tried to call gesture.setStartField, but the gesture had already been ' + - 'started.'); - if (!this.startField_) { - this.startField_ = field; - } -}; - -/** - * Record the bubble that a gesture started on - * @param {Blockly.Bubble} bubble The bubble the gesture started on. - * @package - */ -Blockly.Gesture.prototype.setStartBubble = function(bubble) { - if (!this.startBubble_) { - this.startBubble_ = bubble; - } -}; - -/** - * Record the block that a gesture started on, and set the target block - * appropriately. - * @param {Blockly.BlockSvg} block The block the gesture started on. - * @package - */ -Blockly.Gesture.prototype.setStartBlock = function(block) { - // If the gesture already went through a bubble, don't set the start block. - if (!this.startBlock_ && !this.startBubble_) { - this.startBlock_ = block; - this.shouldDuplicateOnDrag_ = - Blockly.scratchBlocksUtils.isShadowArgumentReporter(block); - if (block.isInFlyout && block != block.getRootBlock()) { - this.setTargetBlock_(block.getRootBlock()); - } else { - this.setTargetBlock_(block); - } - } -}; - -/** - * Record the block that a gesture targets, meaning the block that will be - * dragged if this turns into a drag. If this block is a shadow, that will be - * its first non-shadow parent. - * @param {Blockly.BlockSvg} block The block the gesture targets. - * @private - */ -Blockly.Gesture.prototype.setTargetBlock_ = function(block) { - if (block.isShadow() && !this.shouldDuplicateOnDrag_) { - this.setTargetBlock_(block.getParent()); - } else { - this.targetBlock_ = block; - } -}; - -/** - * Record the workspace that a gesture started on. - * @param {Blockly.WorkspaceSvg} ws The workspace the gesture started on. - * @private - */ -Blockly.Gesture.prototype.setStartWorkspace_ = function(ws) { - if (!this.startWorkspace_) { - this.startWorkspace_ = ws; - } -}; - -/** - * Record the flyout that a gesture started on. - * @param {Blockly.Flyout} flyout The flyout the gesture started on. - * @private - */ -Blockly.Gesture.prototype.setStartFlyout_ = function(flyout) { - if (!this.flyout_) { - this.flyout_ = flyout; - } -}; - -/* End functions for populating a gesture at mouse down. */ - -/* Begin helper functions defining types of clicks. Any developer wanting - * to change the definition of a click should modify only this code. */ - -/** - * Whether this gesture is a click on a bubble. This should only be called when - * ending a gesture (mouse up, touch end). - * @return {boolean} whether this gesture was a click on a bubble. - * @private - */ -Blockly.Gesture.prototype.isBubbleClick_ = function() { - // A bubble click starts on a bubble and never escapes the drag radius. - var hasStartBubble = !!this.startBubble_; - return hasStartBubble && !this.hasExceededDragRadius_; -}; - -/** - * Whether this gesture is a click on a block. This should only be called when - * ending a gesture (mouse up, touch end). - * @return {boolean} whether this gesture was a click on a block. - * @private - */ -Blockly.Gesture.prototype.isBlockClick_ = function() { - // A block click starts on a block, never escapes the drag radius, and is not - // a field click. - var hasStartBlock = !!this.startBlock_; - return hasStartBlock && !this.hasExceededDragRadius_ && !this.isFieldClick_(); -}; - -/** - * Whether this gesture is a click on a field. This should only be called when - * ending a gesture (mouse up, touch end). - * @return {boolean} whether this gesture was a click on a field. - * @private - */ -Blockly.Gesture.prototype.isFieldClick_ = function() { - var fieldEditable = this.startField_ ? - this.startField_.isCurrentlyEditable() : false; - return fieldEditable && !this.hasExceededDragRadius_; -}; - -/** - * Whether this gesture is a click on a workspace. This should only be called - * when ending a gesture (mouse up, touch end). - * @return {boolean} whether this gesture was a click on a workspace. - * @private - */ -Blockly.Gesture.prototype.isWorkspaceClick_ = function() { - var onlyTouchedWorkspace = !this.startBlock_ && !this.startBubble_ && - !this.startField_; - return onlyTouchedWorkspace && !this.hasExceededDragRadius_; -}; - -/* End helper functions defining types of clicks. */ - -/** - * Whether this gesture is a drag of either a workspace or block. - * This function is called externally to block actions that cannot be taken - * mid-drag (e.g. using the keyboard to delete the selected blocks). - * @return {boolean} true if this gesture is a drag of a workspace or block. - * @package - */ -Blockly.Gesture.prototype.isDragging = function() { - return this.isDraggingWorkspace_ || this.isDraggingBlock_ || - this.isDraggingBubble_; -}; - -/** - * Whether this gesture has already been started. In theory every mouse down - * has a corresponding mouse up, but in reality it is possible to lose a - * mouse up, leaving an in-process gesture hanging. - * @return {boolean} whether this gesture was a click on a workspace. - * @package - */ -Blockly.Gesture.prototype.hasStarted = function() { - return this.hasStarted_; -}; - -/* Scratch-specific */ - -/** - * Don't even think about using this function before talking to rachel-fenichel. - * - * Force a drag to start without clicking and dragging the block itself. Used - * to attach duplicated blocks to the mouse pointer. - * @param {!Object} fakeEvent An object with the properties needed to start a - * drag, including clientX and clientY. - * @param {!Blockly.BlockSvg} block The block to start dragging. - * @package - */ -Blockly.Gesture.prototype.forceStartBlockDrag = function(fakeEvent, block) { - this.handleBlockStart(fakeEvent, block); - this.handleWsStart(fakeEvent, block.workspace); - this.isDraggingBlock_ = true; - this.hasExceededDragRadius_ = true; - this.startDraggingBlock_(); -}; - -/** - * Duplicate the target block and start dragging the duplicated block. - * This should be done once we are sure that it is a block drag, and no earlier. - * Specifically for argument reporters in custom block defintions. - * @private - */ -Blockly.Gesture.prototype.duplicateOnDrag_ = function() { - var newBlock = null; - Blockly.Events.disable(); - try { - // Note: targetBlock_ should have no children. If it has children we would - // need to update shadow block IDs to avoid problems in the VM. - // Resizes will be reenabled at the end of the drag. - this.startWorkspace_.setResizesEnabled(false); - var xmlBlock = Blockly.Xml.blockToDom(this.targetBlock_); - newBlock = Blockly.Xml.domToBlock(xmlBlock, this.startWorkspace_); - - // Move the duplicate to original position. - var xy = this.targetBlock_.getRelativeToSurfaceXY(); - newBlock.moveBy(xy.x, xy.y); - newBlock.setShadow(false); - } finally { - Blockly.Events.enable(); - } - if (!newBlock) { - // Something went wrong. - console.error('Something went wrong while duplicating a block.'); - return; - } - if (Blockly.Events.isEnabled()) { - Blockly.Events.fire(new Blockly.Events.BlockCreate(newBlock)); - } - newBlock.select(); - this.targetBlock_ = newBlock; -}; diff --git a/core/grid.js b/core/grid.js deleted file mode 100644 index 781bf22995..0000000000 --- a/core/grid.js +++ /dev/null @@ -1,227 +0,0 @@ -/** - * @license - * Visual Blocks Editor - * - * Copyright 2017 Google Inc. - * https://developers.google.com/blockly/ - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @fileoverview Object for configuring and updating a workspace grid in - * Blockly. - * @author fenichel@google.com (Rachel Fenichel) - */ -'use strict'; - -goog.provide('Blockly.Grid'); - -goog.require('Blockly.utils'); - -goog.require('goog.userAgent'); - - -/** - * Class for a workspace's grid. - * @param {!SVGElement} pattern The grid's SVG pattern, created during injection. - * @param {!Object} options A dictionary of normalized options for the grid. - * See grid documentation: - * https://developers.google.com/blockly/guides/configure/web/grid - * @constructor - */ -Blockly.Grid = function(pattern, options) { - /** - * The grid's SVG pattern, created during injection. - * @type {!SVGElement} - * @private - */ - this.gridPattern_ = pattern; - - /** - * The spacing of the grid lines (in px). - * @type {number} - * @private - */ - this.spacing_ = options['spacing']; - - /** - * How long the grid lines should be (in px). - * @type {number} - * @private - */ - this.length_ = options['length']; - - /** - * The horizontal grid line, if it exists. - * @type {SVGElement} - * @private - */ - this.line1_ = pattern.firstChild; - - /** - * The vertical grid line, if it exists. - * @type {SVGElement} - * @private - */ - this.line2_ = this.line1_ && this.line1_.nextSibling; - - /** - * Whether blocks should snap to the grid. - * @type {boolean} - * @private - */ - this.snapToGrid_ = options['snap']; -}; - -/** - * The scale of the grid, used to set stroke width on grid lines. - * This should always be the same as the workspace scale. - * @type {number} - * @private - */ -Blockly.Grid.prototype.scale_ = 1; - -/** - * Dispose of this grid and unlink from the DOM. - * @package - */ -Blockly.Grid.prototype.dispose = function() { - this.gridPattern_ = null; -}; - -/** - * Whether blocks should snap to the grid, based on the initial configuration. - * @return {boolean} True if blocks should snap, false otherwise. - * @package - */ -Blockly.Grid.prototype.shouldSnap = function() { - return this.snapToGrid_; -}; - -/** - * Get the spacing of the grid points (in px). - * @return {number} The spacing of the grid points. - * @package - */ -Blockly.Grid.prototype.getSpacing = function() { - return this.spacing_; -}; - -/** - * Get the id of the pattern element, which should be randomized to avoid - * conflicts with other Blockly instances on the page. - * @return {string} The pattern ID. - * @package - */ -Blockly.Grid.prototype.getPatternId = function() { - return this.gridPattern_.id; -}; - -/** - * Update the grid with a new scale. - * @param {number} scale The new workspace scale. - * @package - */ -Blockly.Grid.prototype.update = function(scale) { - this.scale_ = scale; - // MSIE freaks if it sees a 0x0 pattern, so set empty patterns to 100x100. - var safeSpacing = (this.spacing_ * scale) || 100; - - this.gridPattern_.setAttribute('width', safeSpacing); - this.gridPattern_.setAttribute('height', safeSpacing); - - var half = Math.floor(this.spacing_ / 2) + 0.5; - var start = half - this.length_ / 2; - var end = half + this.length_ / 2; - - half *= scale; - start *= scale; - end *= scale; - - this.setLineAttributes_(this.line1_, scale, start, end, half, half); - this.setLineAttributes_(this.line2_, scale, half, half, start, end); -}; - -/** - * Set the attributes on one of the lines in the grid. Use this to update the - * length and stroke width of the grid lines. - * @param {!SVGElement} line Which line to update. - * @param {number} width The new stroke size (in px). - * @param {number} x1 The new x start position of the line (in px). - * @param {number} x2 The new x end position of the line (in px). - * @param {number} y1 The new y start position of the line (in px). - * @param {number} y2 The new y end position of the line (in px). - * @private - */ -Blockly.Grid.prototype.setLineAttributes_ = function(line, width, x1, x2, y1, y2) { - if (line) { - line.setAttribute('stroke-width', width); - line.setAttribute('x1', x1); - line.setAttribute('y1', y1); - line.setAttribute('x2', x2); - line.setAttribute('y2', y2); - } -}; - -/** - * Move the grid to a new x and y position, and make sure that change is visible. - * @param {number} x The new x position of the grid (in px). - * @param {number} y The new y position ofthe grid (in px). - * @package - */ -Blockly.Grid.prototype.moveTo = function(x, y) { - this.gridPattern_.setAttribute('x', x); - this.gridPattern_.setAttribute('y', y); - - if (goog.userAgent.IE || goog.userAgent.EDGE) { - // IE/Edge doesn't notice that the x/y offsets have changed. - // Force an update. - this.update(this.scale_); - } -}; - -/** - * Create the DOM for the grid described by options. - * @param {string} rnd A random ID to append to the pattern's ID. - * @param {!Object} gridOptions The object containing grid configuration. - * @param {!SVGElement} defs The root SVG element for this workspace's defs. - * @return {!SVGElement} The SVG element for the grid pattern. - * @package - */ -Blockly.Grid.createDom = function(rnd, gridOptions, defs) { - /* - - - - - */ - var gridPattern = Blockly.utils.createSvgElement('pattern', - { - 'id': 'blocklyGridPattern' + rnd, - 'patternUnits': 'userSpaceOnUse' - }, defs); - if (gridOptions['length'] > 0 && gridOptions['spacing'] > 0) { - Blockly.utils.createSvgElement('line', - {'stroke': gridOptions['colour']}, gridPattern); - if (gridOptions['length'] > 1) { - Blockly.utils.createSvgElement('line', - {'stroke': gridOptions['colour']}, gridPattern); - } - // x1, y1, x1, x2 properties will be set later in update. - } else { - // Edge 16 doesn't handle empty patterns - Blockly.utils.createSvgElement('line', {}, gridPattern); - } - return gridPattern; -}; diff --git a/core/icon.js b/core/icon.js deleted file mode 100644 index b51d90efd1..0000000000 --- a/core/icon.js +++ /dev/null @@ -1,205 +0,0 @@ -/** - * @license - * Visual Blocks Editor - * - * Copyright 2013 Google Inc. - * https://developers.google.com/blockly/ - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @fileoverview Object representing an icon on a block. - * @author fraser@google.com (Neil Fraser) - */ -'use strict'; - -goog.provide('Blockly.Icon'); - -goog.require('goog.dom'); -goog.require('goog.math.Coordinate'); - - -/** - * Class for an icon. - * @param {Blockly.Block} block The block associated with this icon. - * @constructor - */ -Blockly.Icon = function(block) { - this.block_ = block; -}; - -/** - * Does this icon get hidden when the block is collapsed. - */ -Blockly.Icon.prototype.collapseHidden = true; - -/** - * Height and width of icons. - */ -Blockly.Icon.prototype.SIZE = 17; - -/** - * Bubble UI (if visible). - * @type {Blockly.Bubble} - * @protected - */ -Blockly.Icon.prototype.bubble_ = null; - -/** - * Absolute coordinate of icon's center. - * @type {goog.math.Coordinate} - * @protected - */ -Blockly.Icon.prototype.iconXY_ = null; - -/** - * Create the icon on the block. - */ -Blockly.Icon.prototype.createIcon = function() { - if (this.iconGroup_) { - // Icon already exists. - return; - } - /* Here's the markup that will be generated: - - ... - - */ - this.iconGroup_ = Blockly.utils.createSvgElement('g', - {'class': 'blocklyIconGroup'}, null); - if (this.block_.isInFlyout) { - Blockly.utils.addClass( - /** @type {!Element} */ (this.iconGroup_), 'blocklyIconGroupReadonly'); - } - this.drawIcon_(this.iconGroup_); - - this.block_.getSvgRoot().appendChild(this.iconGroup_); - Blockly.bindEventWithChecks_( - this.iconGroup_, 'mouseup', this, this.iconClick_); - this.updateEditable(); -}; - -/** - * Dispose of this icon. - */ -Blockly.Icon.prototype.dispose = function() { - // Dispose of and unlink the icon. - goog.dom.removeNode(this.iconGroup_); - this.iconGroup_ = null; - // Dispose of and unlink the bubble. - this.setVisible(false); - this.block_ = null; -}; - -/** - * Add or remove the UI indicating if this icon may be clicked or not. - */ -Blockly.Icon.prototype.updateEditable = function() { -}; - -/** - * Is the associated bubble visible? - * @return {boolean} True if the bubble is visible. - */ -Blockly.Icon.prototype.isVisible = function() { - return !!this.bubble_; -}; - -/** - * Clicking on the icon toggles if the bubble is visible. - * @param {!Event} e Mouse click event. - * @protected - */ -Blockly.Icon.prototype.iconClick_ = function(e) { - if (this.block_.workspace.isDragging()) { - // Drag operation is concluding. Don't open the editor. - return; - } - if (!this.block_.isInFlyout && !Blockly.utils.isRightButton(e)) { - this.setVisible(!this.isVisible()); - } -}; - -/** - * Change the colour of the associated bubble to match its block. - */ -Blockly.Icon.prototype.updateColour = function() { - if (this.isVisible()) { - this.bubble_.setColour(this.block_.getColour()); - } -}; - -/** - * Render the icon. - * @param {number} cursorX Horizontal offset at which to position the icon. - * @return {number} Horizontal offset for next item to draw. - */ -Blockly.Icon.prototype.renderIcon = function(cursorX) { - if (this.collapseHidden && this.block_.isCollapsed()) { - this.iconGroup_.setAttribute('display', 'none'); - return cursorX; - } - this.iconGroup_.setAttribute('display', 'block'); - - var TOP_MARGIN = 5; - var width = this.SIZE; - if (this.block_.RTL) { - cursorX -= width; - } - this.iconGroup_.setAttribute('transform', - 'translate(' + cursorX + ',' + TOP_MARGIN + ')'); - this.computeIconLocation(); - if (this.block_.RTL) { - cursorX -= Blockly.BlockSvg.SEP_SPACE_X; - } else { - cursorX += width + Blockly.BlockSvg.SEP_SPACE_X; - } - return cursorX; -}; - -/** - * Notification that the icon has moved. Update the arrow accordingly. - * @param {!goog.math.Coordinate} xy Absolute location in workspace coordinates. - */ -Blockly.Icon.prototype.setIconLocation = function(xy) { - this.iconXY_ = xy; - if (this.isVisible()) { - this.bubble_.setAnchorLocation(xy); - } -}; - -/** - * Notification that the icon has moved, but we don't really know where. - * Recompute the icon's location from scratch. - */ -Blockly.Icon.prototype.computeIconLocation = function() { - // Find coordinates for the centre of the icon and update the arrow. - var blockXY = this.block_.getRelativeToSurfaceXY(); - var iconXY = Blockly.utils.getRelativeXY(this.iconGroup_); - var newXY = new goog.math.Coordinate( - blockXY.x + iconXY.x + this.SIZE / 2, - blockXY.y + iconXY.y + this.SIZE / 2); - if (!goog.math.Coordinate.equals(this.getIconLocation(), newXY)) { - this.setIconLocation(newXY); - } -}; - -/** - * Returns the center of the block's icon relative to the surface. - * @return {!goog.math.Coordinate} Object with x and y properties in workspace - * coordinates. - */ -Blockly.Icon.prototype.getIconLocation = function() { - return this.iconXY_; -}; diff --git a/core/inject.js b/core/inject.js deleted file mode 100644 index 7b0dbddc7b..0000000000 --- a/core/inject.js +++ /dev/null @@ -1,491 +0,0 @@ -/** - * @license - * Visual Blocks Editor - * - * Copyright 2011 Google Inc. - * https://developers.google.com/blockly/ - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @fileoverview Functions for injecting Blockly into a web page. - * @author fraser@google.com (Neil Fraser) - */ -'use strict'; - -goog.provide('Blockly.inject'); - -goog.require('Blockly.BlockDragSurfaceSvg'); -goog.require('Blockly.Css'); -goog.require('Blockly.constants'); -goog.require('Blockly.DropDownDiv'); -goog.require('Blockly.Grid'); -goog.require('Blockly.Options'); -goog.require('Blockly.WorkspaceSvg'); -goog.require('Blockly.WorkspaceDragSurfaceSvg'); -goog.require('goog.dom'); -goog.require('goog.ui.Component'); -goog.require('goog.userAgent'); - -/** - * Inject a Blockly editor into the specified container element (usually a div). - * @param {!Element|string} container Containing element, or its ID, - * or a CSS selector. - * @param {Object=} opt_options Optional dictionary of options. - * @return {!Blockly.Workspace} Newly created main workspace. - */ -Blockly.inject = function(container, opt_options) { - if (goog.isString(container)) { - container = document.getElementById(container) || - document.querySelector(container); - } - // Verify that the container is in document. - if (!goog.dom.contains(document, container)) { - throw 'Error: container is not in current document.'; - } - var options = new Blockly.Options(opt_options || {}); - var subContainer = goog.dom.createDom('div', 'injectionDiv'); - container.appendChild(subContainer); - - // Open the Field text cache and leave it open. See this issue for more information - // https://github.com/LLK/scratch-blocks/issues/1004 - Blockly.Field.startCache(); - - var svg = Blockly.createDom_(subContainer, options); - - // Create surfaces for dragging things. These are optimizations - // so that the broowser does not repaint during the drag. - var blockDragSurface = new Blockly.BlockDragSurfaceSvg(subContainer); - var workspaceDragSurface = new Blockly.WorkspaceDragSurfaceSvg(subContainer); - - var workspace = Blockly.createMainWorkspace_(svg, options, blockDragSurface, - workspaceDragSurface); - Blockly.init_(workspace); - Blockly.mainWorkspace = workspace; - - Blockly.svgResize(workspace); - return workspace; -}; - -/** - * Create the SVG image. - * @param {!Element} container Containing element. - * @param {!Blockly.Options} options Dictionary of options. - * @return {!Element} Newly created SVG image. - * @private - */ -Blockly.createDom_ = function(container, options) { - // Sadly browsers (Chrome vs Firefox) are currently inconsistent in laying - // out content in RTL mode. Therefore Blockly forces the use of LTR, - // then manually positions content in RTL as needed. - container.setAttribute('dir', 'LTR'); - // Closure can be trusted to create HTML widgets with the proper direction. - goog.ui.Component.setDefaultRightToLeft(options.RTL); - - // Load CSS. - Blockly.Css.inject(options.hasCss, options.pathToMedia); - - // Build the SVG DOM. - /* - - ... - - */ - var svg = Blockly.utils.createSvgElement('svg', { - 'xmlns': 'http://www.w3.org/2000/svg', - 'xmlns:html': 'http://www.w3.org/1999/xhtml', - 'xmlns:xlink': 'http://www.w3.org/1999/xlink', - 'version': '1.1', - 'class': 'blocklySvg' - }, container); - /* - - ... filters go here ... - - */ - var defs = Blockly.utils.createSvgElement('defs', {}, svg); - // Each filter/pattern needs a unique ID for the case of multiple Blockly - // instances on a page. Browser behaviour becomes undefined otherwise. - // https://neil.fraser.name/news/2015/11/01/ - // TODO (tmickel): Look into whether block highlighting still works. - // Reference commit: - // https://github.com/google/blockly/commit/144be4d49f36fdba260a26edbd170ae75bbc37a6 - var rnd = String(Math.random()).substring(2); - - // Using a dilate distorts the block shape. - // Instead use a gaussian blur, and then set all alpha to 1 with a transfer. - var stackGlowFilter = Blockly.utils.createSvgElement('filter', - { - 'id': 'blocklyStackGlowFilter' + rnd, - 'height': '160%', - 'width': '180%', - y: '-30%', - x: '-40%' - }, - defs); - options.stackGlowBlur = Blockly.utils.createSvgElement('feGaussianBlur', - { - 'in': 'SourceGraphic', - 'stdDeviation': Blockly.Colours.stackGlowSize - }, - stackGlowFilter); - // Set all gaussian blur pixels to 1 opacity before applying flood - var componentTransfer = Blockly.utils.createSvgElement('feComponentTransfer', {'result': 'outBlur'}, stackGlowFilter); - Blockly.utils.createSvgElement('feFuncA', - { - 'type': 'table', - 'tableValues': '0' + goog.string.repeat(' 1', 16) - }, - componentTransfer); - // Color the highlight - Blockly.utils.createSvgElement('feFlood', - { - 'flood-color': Blockly.Colours.stackGlow, - 'flood-opacity': Blockly.Colours.stackGlowOpacity, - 'result': 'outColor' - }, - stackGlowFilter); - Blockly.utils.createSvgElement('feComposite', - { - 'in': 'outColor', - 'in2': 'outBlur', - 'operator': 'in', - 'result': 'outGlow' - }, - stackGlowFilter); - Blockly.utils.createSvgElement('feComposite', - { - 'in': 'SourceGraphic', - 'in2': 'outGlow', - 'operator': 'over' - }, - stackGlowFilter); - - // Filter for replacement marker - var replacementGlowFilter = Blockly.utils.createSvgElement('filter', - { - 'id': 'blocklyReplacementGlowFilter' + rnd, - 'height': '160%', - 'width': '180%', - y: '-30%', - x: '-40%' - }, - defs); - Blockly.utils.createSvgElement('feGaussianBlur', - { - 'in': 'SourceGraphic', - 'stdDeviation': Blockly.Colours.replacementGlowSize - }, - replacementGlowFilter); - // Set all gaussian blur pixels to 1 opacity before applying flood - var componentTransfer = Blockly.utils.createSvgElement('feComponentTransfer', - {'result': 'outBlur'}, replacementGlowFilter); - Blockly.utils.createSvgElement('feFuncA', - { - 'type': 'table', - 'tableValues': '0' + goog.string.repeat(' 1', 16) - }, - componentTransfer); - // Color the highlight - Blockly.utils.createSvgElement('feFlood', - { - 'flood-color': Blockly.Colours.replacementGlow, - 'flood-opacity': Blockly.Colours.replacementGlowOpacity, - 'result': 'outColor' - }, - replacementGlowFilter); - Blockly.utils.createSvgElement('feComposite', - { - 'in': 'outColor', - 'in2': 'outBlur', - 'operator': 'in', - 'result': 'outGlow' - }, - replacementGlowFilter); - Blockly.utils.createSvgElement('feComposite', - { - 'in': 'SourceGraphic', - 'in2': 'outGlow', - 'operator': 'over' - }, - replacementGlowFilter); - /* - - - - - */ - var disabledPattern = Blockly.utils.createSvgElement('pattern', - { - 'id': 'blocklyDisabledPattern' + rnd, - 'patternUnits': 'userSpaceOnUse', - 'width': 10, - 'height': 10 - }, - defs); - Blockly.utils.createSvgElement('rect', - { - 'width': 10, - 'height': 10, - 'fill': '#aaa' - }, - disabledPattern); - Blockly.utils.createSvgElement('path', - { - 'd': 'M 0 0 L 10 10 M 10 0 L 0 10', - 'stroke': '#cc0' - }, - disabledPattern); - options.stackGlowFilterId = stackGlowFilter.id; - options.replacementGlowFilterId = replacementGlowFilter.id; - options.disabledPatternId = disabledPattern.id; - - options.gridPattern = Blockly.Grid.createDom(rnd, options.gridOptions, defs); - return svg; -}; - -/** - * Create a main workspace and add it to the SVG. - * @param {!Element} svg SVG element with pattern defined. - * @param {!Blockly.Options} options Dictionary of options. - * @param {!Blockly.BlockDragSurfaceSvg} blockDragSurface Drag surface SVG - * for the blocks. - * @param {!Blockly.WorkspaceDragSurfaceSvg} workspaceDragSurface Drag surface - * SVG for the workspace. - * @return {!Blockly.Workspace} Newly created main workspace. - * @private - */ -Blockly.createMainWorkspace_ = function(svg, options, blockDragSurface, workspaceDragSurface) { - options.parentWorkspace = null; - var mainWorkspace = new Blockly.WorkspaceSvg(options, blockDragSurface, workspaceDragSurface); - mainWorkspace.scale = options.zoomOptions.startScale; - svg.appendChild(mainWorkspace.createDom('blocklyMainBackground')); - - if (!options.hasCategories && options.languageTree) { - // Add flyout as an that is a sibling of the workspace svg. - var flyout = mainWorkspace.addFlyout_('svg'); - Blockly.utils.insertAfter(flyout, svg); - } - - // A null translation will also apply the correct initial scale. - mainWorkspace.translate(0, 0); - Blockly.mainWorkspace = mainWorkspace; - - if (!options.readOnly && !options.hasScrollbars) { - var workspaceChanged = function() { - if (!mainWorkspace.isDragging()) { - var metrics = mainWorkspace.getMetrics(); - var edgeLeft = metrics.viewLeft + metrics.absoluteLeft; - var edgeTop = metrics.viewTop + metrics.absoluteTop; - if (metrics.contentTop < edgeTop || - metrics.contentTop + metrics.contentHeight > - metrics.viewHeight + edgeTop || - metrics.contentLeft < - (options.RTL ? metrics.viewLeft : edgeLeft) || - metrics.contentLeft + metrics.contentWidth > (options.RTL ? - metrics.viewWidth : metrics.viewWidth + edgeLeft)) { - // One or more blocks may be out of bounds. Bump them back in. - var MARGIN = 25; - var blocks = mainWorkspace.getTopBlocks(false); - for (var b = 0, block; block = blocks[b]; b++) { - var blockXY = block.getRelativeToSurfaceXY(); - var blockHW = block.getHeightWidth(); - // Bump any block that's above the top back inside. - var overflowTop = edgeTop + MARGIN - blockHW.height - blockXY.y; - if (overflowTop > 0) { - block.moveBy(0, overflowTop); - } - // Bump any block that's below the bottom back inside. - var overflowBottom = - edgeTop + metrics.viewHeight - MARGIN - blockXY.y; - if (overflowBottom < 0) { - block.moveBy(0, overflowBottom); - } - // Bump any block that's off the left back inside. - var overflowLeft = MARGIN + edgeLeft - - blockXY.x - (options.RTL ? 0 : blockHW.width); - if (overflowLeft > 0) { - block.moveBy(overflowLeft, 0); - } - // Bump any block that's off the right back inside. - var overflowRight = edgeLeft + metrics.viewWidth - MARGIN - - blockXY.x + (options.RTL ? blockHW.width : 0); - if (overflowRight < 0) { - block.moveBy(overflowRight, 0); - } - } - } - } - }; - mainWorkspace.addChangeListener(workspaceChanged); - } - // The SVG is now fully assembled. - Blockly.svgResize(mainWorkspace); - Blockly.WidgetDiv.createDom(); - Blockly.DropDownDiv.createDom(); - Blockly.Tooltip.createDom(); - return mainWorkspace; -}; - -/** - * Initialize Blockly with various handlers. - * @param {!Blockly.Workspace} mainWorkspace Newly created main workspace. - * @private - */ -Blockly.init_ = function(mainWorkspace) { - var options = mainWorkspace.options; - var svg = mainWorkspace.getParentSvg(); - - // Suppress the browser's context menu. - Blockly.bindEventWithChecks_(svg.parentNode, 'contextmenu', null, - function(e) { - if (!Blockly.utils.isTargetInput(e)) { - e.preventDefault(); - } - }); - - var workspaceResizeHandler = Blockly.bindEventWithChecks_(window, 'resize', - null, - function() { - Blockly.hideChaffOnResize(true); - Blockly.svgResize(mainWorkspace); - }); - mainWorkspace.setResizeHandlerWrapper(workspaceResizeHandler); - - Blockly.inject.bindDocumentEvents_(); - - if (options.languageTree) { - if (mainWorkspace.toolbox_) { - mainWorkspace.toolbox_.init(mainWorkspace); - } else if (mainWorkspace.flyout_) { - // Build a fixed flyout with the root blocks. - mainWorkspace.flyout_.init(mainWorkspace); - mainWorkspace.flyout_.show(options.languageTree.childNodes); - mainWorkspace.flyout_.scrollToStart(); - // Translate the workspace to avoid the fixed flyout. - if (options.horizontalLayout) { - mainWorkspace.scrollY = mainWorkspace.flyout_.height_; - if (options.toolboxPosition == Blockly.TOOLBOX_AT_BOTTOM) { - mainWorkspace.scrollY *= -1; - } - } else { - mainWorkspace.scrollX = mainWorkspace.flyout_.width_; - if (options.toolboxPosition == Blockly.TOOLBOX_AT_RIGHT) { - mainWorkspace.scrollX *= -1; - } - } - mainWorkspace.translate(mainWorkspace.scrollX, mainWorkspace.scrollY); - } - } - - if (options.hasScrollbars) { - mainWorkspace.scrollbar = new Blockly.ScrollbarPair(mainWorkspace); - mainWorkspace.scrollbar.resize(); - } - - // Load the sounds. - if (options.hasSounds) { - Blockly.inject.loadSounds_(options.pathToMedia, mainWorkspace); - } -}; - -/** - * Bind document events, but only once. Destroying and reinjecting Blockly - * should not bind again. - * Bind events for scrolling the workspace. - * Most of these events should be bound to the SVG's surface. - * However, 'mouseup' has to be on the whole document so that a block dragged - * out of bounds and released will know that it has been released. - * Also, 'keydown' has to be on the whole document since the browser doesn't - * understand a concept of focus on the SVG image. - * @private - */ -Blockly.inject.bindDocumentEvents_ = function() { - if (!Blockly.documentEventsBound_) { - Blockly.bindEventWithChecks_(document, 'keydown', null, Blockly.onKeyDown_); - // longStop needs to run to stop the context menu from showing up. It - // should run regardless of what other touch event handlers have run. - Blockly.bindEvent_(document, 'touchend', null, Blockly.longStop_); - Blockly.bindEvent_(document, 'touchcancel', null, Blockly.longStop_); - // Some iPad versions don't fire resize after portrait to landscape change. - if (goog.userAgent.IPAD) { - Blockly.bindEventWithChecks_(window, 'orientationchange', document, - function() { - // TODO(#397): Fix for multiple blockly workspaces. - Blockly.svgResize(Blockly.getMainWorkspace()); - }); - } - } - Blockly.documentEventsBound_ = true; -}; - -/** - * Load sounds for the given workspace. - * @param {string} pathToMedia The path to the media directory. - * @param {!Blockly.Workspace} workspace The workspace to load sounds for. - * @private - */ -Blockly.inject.loadSounds_ = function(pathToMedia, workspace) { - var audioMgr = workspace.getAudioManager(); - audioMgr.load( - [ - pathToMedia + 'click.mp3', - pathToMedia + 'click.wav', - pathToMedia + 'click.ogg' - ], - 'click'); - audioMgr.load( - [ - pathToMedia + 'delete.mp3', - pathToMedia + 'delete.ogg', - pathToMedia + 'delete.wav' - ], - 'delete'); - - // Bind temporary hooks that preload the sounds. - var soundBinds = []; - var unbindSounds = function() { - while (soundBinds.length) { - Blockly.unbindEvent_(soundBinds.pop()); - } - audioMgr.preload(); - }; - - // opt_noCaptureIdentifier is true because this is an action to take on a - // click, not a drag. - // Android ignores any sound not loaded as a result of a user action. - soundBinds.push( - Blockly.bindEventWithChecks_(document, 'mousemove', null, unbindSounds, - /* opt_noCaptureIdentifier */ true)); - soundBinds.push( - Blockly.bindEventWithChecks_(document, 'touchstart', null, unbindSounds, - /* opt_noCaptureIdentifier */ true)); -}; - -/** - * Modify the block tree on the existing toolbox. - * @param {Node|string} tree DOM tree of blocks, or text representation of same. - * @deprecated April 2015 - */ -Blockly.updateToolbox = function(tree) { - console.warn('Deprecated call to Blockly.updateToolbox, ' + - 'use workspace.updateToolbox instead.'); - Blockly.getMainWorkspace().updateToolbox(tree); -}; diff --git a/core/input.js b/core/input.js deleted file mode 100644 index 91bb4f12bf..0000000000 --- a/core/input.js +++ /dev/null @@ -1,285 +0,0 @@ -/** - * @license - * Visual Blocks Editor - * - * Copyright 2012 Google Inc. - * https://developers.google.com/blockly/ - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @fileoverview Object representing an input (value, statement, or dummy). - * @author fraser@google.com (Neil Fraser) - */ -'use strict'; - -goog.provide('Blockly.Input'); - -goog.require('Blockly.Connection'); -goog.require('Blockly.FieldLabel'); -goog.require('goog.asserts'); - - -/** - * Class for an input with an optional field. - * @param {number} type The type of the input. - * @param {string} name Language-neutral identifier which may used to find this - * input again. - * @param {!Blockly.Block} block The block containing this input. - * @param {Blockly.Connection} connection Optional connection for this input. - * @constructor - */ -Blockly.Input = function(type, name, block, connection) { - if (type != Blockly.DUMMY_INPUT && !name) { - throw 'Value inputs and statement inputs must have non-empty name.'; - } - /** @type {number} */ - this.type = type; - /** @type {string} */ - this.name = name; - /** - * @type {!Blockly.Block} - * @private - */ - this.sourceBlock_ = block; - /** @type {Blockly.Connection} */ - this.connection = connection; - /** @type {!Array.} */ - this.fieldRow = []; - - /** - * The shape that is displayed when this input is rendered but not filled. - * @type {SVGElement} - * @package - */ - this.outlinePath = null; -}; - -/** - * Alignment of input's fields (left, right or centre). - * @type {number} - */ -Blockly.Input.prototype.align = Blockly.ALIGN_LEFT; - -/** - * Is the input visible? - * @type {boolean} - * @private - */ -Blockly.Input.prototype.visible_ = true; - -/** - * Add a field (or label from string), and all prefix and suffix fields, to the - * end of the input's field row. - * @param {string|!Blockly.Field} field Something to add as a field. - * @param {string=} opt_name Language-neutral identifier which may used to find - * this field again. Should be unique to the host block. - * @return {!Blockly.Input} The input being append to (to allow chaining). - */ -Blockly.Input.prototype.appendField = function(field, opt_name) { - this.insertFieldAt(this.fieldRow.length, field, opt_name); - return this; -}; - -/** - * Inserts a field (or label from string), and all prefix and suffix fields, at - * the location of the input's field row. - * @param {number} index The index at which to insert field. - * @param {string|!Blockly.Field} field Something to add as a field. - * @param {string=} opt_name Language-neutral identifier which may used to find - * this field again. Should be unique to the host block. - * @return {number} The index following the last inserted field. - */ -Blockly.Input.prototype.insertFieldAt = function(index, field, opt_name) { - if (index < 0 || index > this.fieldRow.length) { - throw new Error('index ' + index + ' out of bounds.'); - } - - // Empty string, Null or undefined generates no field, unless field is named. - if (!field && !opt_name) { - return this; - } - // Generate a FieldLabel when given a plain text field. - if (goog.isString(field)) { - field = new Blockly.FieldLabel(/** @type {string} */ (field)); - } - field.setSourceBlock(this.sourceBlock_); - if (this.sourceBlock_.rendered) { - field.init(); - } - field.name = opt_name; - - if (field.prefixField) { - // Add any prefix. - index = this.insertFieldAt(index, field.prefixField); - } - // Add the field to the field row. - this.fieldRow.splice(index, 0, field); - ++index; - if (field.suffixField) { - // Add any suffix. - index = this.insertFieldAt(index, field.suffixField); - } - - if (this.sourceBlock_.rendered) { - this.sourceBlock_.render(); - // Adding a field will cause the block to change shape. - this.sourceBlock_.bumpNeighbours_(); - } - return index; -}; - -/** - * Remove a field from this input. - * @param {string} name The name of the field. - * @throws {goog.asserts.AssertionError} if the field is not present. - */ -Blockly.Input.prototype.removeField = function(name) { - for (var i = 0, field; field = this.fieldRow[i]; i++) { - if (field.name === name) { - field.dispose(); - this.fieldRow.splice(i, 1); - if (this.sourceBlock_.rendered) { - this.sourceBlock_.render(); - // Removing a field will cause the block to change shape. - this.sourceBlock_.bumpNeighbours_(); - } - return; - } - } - goog.asserts.fail('Field "%s" not found.', name); -}; - -/** - * Gets whether this input is visible or not. - * @return {boolean} True if visible. - */ -Blockly.Input.prototype.isVisible = function() { - return this.visible_; -}; - -/** - * Sets whether this input is visible or not. - * Used to collapse/uncollapse a block. - * @param {boolean} visible True if visible. - * @return {!Array.} List of blocks to render. - */ -Blockly.Input.prototype.setVisible = function(visible) { - var renderList = []; - if (this.visible_ == visible) { - return renderList; - } - this.visible_ = visible; - - var display = visible ? 'block' : 'none'; - for (var y = 0, field; field = this.fieldRow[y]; y++) { - field.setVisible(visible); - } - if (this.connection) { - // Has a connection. - if (visible) { - renderList = this.connection.unhideAll(); - } else { - this.connection.hideAll(); - } - var child = this.connection.targetBlock(); - if (child) { - child.getSvgRoot().style.display = display; - if (!visible) { - child.rendered = false; - } - } - } - return renderList; -}; - -/** - * Change a connection's compatibility. - * @param {string|Array.|null} check Compatible value type or - * list of value types. Null if all types are compatible. - * @return {!Blockly.Input} The input being modified (to allow chaining). - */ -Blockly.Input.prototype.setCheck = function(check) { - if (!this.connection) { - throw 'This input does not have a connection.'; - } - this.connection.setCheck(check); - return this; -}; - -/** - * Change the alignment of the connection's field(s). - * @param {number} align One of Blockly.ALIGN_LEFT, ALIGN_CENTRE, ALIGN_RIGHT. - * In RTL mode directions are reversed, and ALIGN_RIGHT aligns to the left. - * @return {!Blockly.Input} The input being modified (to allow chaining). - */ -Blockly.Input.prototype.setAlign = function(align) { - this.align = align; - if (this.sourceBlock_.rendered) { - this.sourceBlock_.render(); - } - return this; -}; - -/** - * Initialize the fields on this input. - */ -Blockly.Input.prototype.init = function() { - if (!this.sourceBlock_.workspace.rendered) { - return; // Headless blocks don't need fields initialized. - } - for (var i = 0; i < this.fieldRow.length; i++) { - this.fieldRow[i].init(this.sourceBlock_); - } -}; - -/** - * Sever all links to this input. - */ -Blockly.Input.prototype.dispose = function() { - if (this.outlinePath) { - goog.dom.removeNode(this.outlinePath); - } - for (var i = 0, field; field = this.fieldRow[i]; i++) { - field.dispose(); - } - if (this.connection) { - this.connection.dispose(); - } - this.sourceBlock_ = null; -}; - -/** - * Create the input shape path element and attach it to the given SVG element. - * @param {!SVGElement} svgRoot The parent on which ot append the new element. - * @package - */ -Blockly.Input.prototype.initOutlinePath = function(svgRoot) { - if (!this.sourceBlock_.workspace.rendered) { - return; // Headless blocks don't need field outlines. - } - if (this.outlinePath) { - return; - } - if (this.type == Blockly.INPUT_VALUE) { - this.outlinePath = Blockly.utils.createSvgElement( - 'path', - { - 'class': 'blocklyPath', - 'style': 'visibility: hidden', // Hide by default - shown when not connected. - 'd': '' // IE doesn't like paths without the data definition, set an empty default - }, - svgRoot); - } -}; diff --git a/core/insertion_marker_manager.js b/core/insertion_marker_manager.js deleted file mode 100644 index 2136a43f33..0000000000 --- a/core/insertion_marker_manager.js +++ /dev/null @@ -1,678 +0,0 @@ -/** - * @license - * Visual Blocks Editor - * - * Copyright 2017 Google Inc. - * https://developers.google.com/blockly/ - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @fileoverview Class that controls updates to connections during drags. - * @author fenichel@google.com (Rachel Fenichel) - */ -'use strict'; - -goog.provide('Blockly.InsertionMarkerManager'); - -goog.require('Blockly.BlockAnimations'); -goog.require('Blockly.Events.BlockMove'); -goog.require('Blockly.RenderedConnection'); - -goog.require('goog.math.Coordinate'); - - -/** - * Class that controls updates to connections during drags. It is primarily - * responsible for finding the closest eligible connection and highlighting or - * unhiglighting it as needed during a drag. - * @param {!Blockly.BlockSvg} block The top block in the stack being dragged. - * @constructor - */ -Blockly.InsertionMarkerManager = function(block) { - Blockly.selected = block; - - /** - * The top block in the stack being dragged. - * Does not change during a drag. - * @type {!Blockly.Block} - * @private - */ - this.topBlock_ = block; - - /** - * The workspace on which these connections are being dragged. - * Does not change during a drag. - * @type {!Blockly.WorkspaceSvg} - * @private - */ - this.workspace_ = block.workspace; - - /** - * The last connection on the stack, if it's not the last connection on the - * first block. - * Set in initAvailableConnections, if at all. - * @type {Blockly.RenderedConnection} - * @private - */ - this.lastOnStack_ = null; - - /** - * The insertion marker corresponding to the last block in the stack, if - * that's not the same as the first block in the stack. - * Set in initAvailableConnections, if at all - * @type {Blockly.BlockSvg} - * @private - */ - this.lastMarker_ = null; - - /** - * The insertion marker that shows up between blocks to show where a block - * would go if dropped immediately. - * This is the scratch-blocks equivalent of connection highlighting. - * @type {Blockly.BlockSvg} - * @private - */ - this.firstMarker_ = this.createMarkerBlock_(this.topBlock_); - - /** - * The connection that this block would connect to if released immediately. - * Updated on every mouse move. - * This is not on any of the blocks that are being dragged. - * @type {Blockly.RenderedConnection} - * @private - */ - this.closestConnection_ = null; - - /** - * The connection that would connect to this.closestConnection_ if this block - * were released immediately. - * Updated on every mouse move. - * This is on the top block that is being dragged or the last block in the - * dragging stack. - * @type {Blockly.RenderedConnection} - * @private - */ - this.localConnection_ = null; - - /** - * Whether the block would be deleted if it were dropped immediately. - * Updated on every mouse move. - * @type {boolean} - * @private - */ - this.wouldDeleteBlock_ = false; - - /** - * Connection on the insertion marker block that corresponds to - * this.localConnection_ on the currently dragged block. - * This is part of the scratch-blocks equivalent of connection highlighting. - * @type {Blockly.RenderedConnection} - * @private - */ - this.markerConnection_ = null; - - /** - * Whether we are currently highlighting the block (shadow or real) that would - * be replaced if the drag were released immediately. - * @type {boolean} - * @private - */ - this.highlightingBlock_ = false; - - /** - * The block that is being highlighted for replacement, or null. - * @type {Blockly.BlockSvg} - * @private - */ - this.highlightedBlock_ = null; - - /** - * The connections on the dragging blocks that are available to connect to - * other blocks. This includes all open connections on the top block, as well - * as the last connection on the block stack. - * Does not change during a drag. - * @type {!Array.} - * @private - */ - this.availableConnections_ = this.initAvailableConnections_(); -}; - -/** - * Sever all links from this object. - * @package - */ -Blockly.InsertionMarkerManager.prototype.dispose = function() { - this.topBlock_ = null; - this.workspace_ = null; - this.availableConnections_.length = 0; - this.closestConnection_ = null; - this.localConnection_ = null; - - Blockly.Events.disable(); - try { - if (this.firstMarker_) { - this.firstMarker_.dispose(); - this.firstMarker_ = null; - } - if (this.lastMarker_) { - this.lastMarker_.dispose(); - this.lastMarker_ = null; - } - } finally { - Blockly.Events.enable(); - } - - this.highlightedBlock_ = null; -}; - -/** - * Return whether the block would be deleted if dropped immediately, based on - * information from the most recent move event. - * @return {boolean} true if the block would be deleted if dropped immediately. - * @package - */ -Blockly.InsertionMarkerManager.prototype.wouldDeleteBlock = function() { - return this.wouldDeleteBlock_; -}; - -/** - * Return whether the block would be connected if dropped immediately, based on - * information from the most recent move event. - * @return {boolean} True if the block would be connected if dropped - * immediately. - * @package - */ -Blockly.InsertionMarkerManager.prototype.wouldConnectBlock = function() { - return !!this.closestConnection_; -}; - -/** - * Connect to the closest connection and render the results. - * This should be called at the end of a drag. - * @package - */ -Blockly.InsertionMarkerManager.prototype.applyConnections = function() { - if (this.closestConnection_) { - // Don't fire events for insertion markers. - Blockly.Events.disable(); - this.hidePreview_(); - Blockly.Events.enable(); - // Connect two blocks together. - this.localConnection_.connect(this.closestConnection_); - if (this.topBlock_.rendered) { - // Trigger a connection animation. - // Determine which connection is inferior (lower in the source stack). - var inferiorConnection = this.localConnection_.isSuperior() ? - this.closestConnection_ : this.localConnection_; - Blockly.BlockAnimations.connectionUiEffect( - inferiorConnection.getSourceBlock()); - // Bring the just-edited stack to the front. - var rootBlock = this.topBlock_.getRootBlock(); - rootBlock.bringToFront(); - } - } -}; - -/** - * Update highlighted connections based on the most recent move location. - * @param {!goog.math.Coordinate} dxy Position relative to drag start, - * in workspace units. - * @param {?number} deleteArea One of {@link Blockly.DELETE_AREA_TRASH}, - * {@link Blockly.DELETE_AREA_TOOLBOX}, or {@link Blockly.DELETE_AREA_NONE}. - * @package - */ -Blockly.InsertionMarkerManager.prototype.update = function(dxy, deleteArea) { - var candidate = this.getCandidate_(dxy); - - this.wouldDeleteBlock_ = this.shouldDelete_(candidate, deleteArea); - var shouldUpdate = this.wouldDeleteBlock_ || - this.shouldUpdatePreviews_(candidate, dxy); - - if (shouldUpdate) { - // Don't fire events for insertion marker creation or movement. - Blockly.Events.disable(); - this.maybeHidePreview_(candidate); - this.maybeShowPreview_(candidate); - Blockly.Events.enable(); - } -}; - -/**** Begin initialization functions ****/ - -/** - * Create an insertion marker that represents the given block. - * @param {!Blockly.BlockSvg} sourceBlock The block that the insertion marker - * will represent. - * @return {!Blockly.BlockSvg} The insertion marker that represents the given - * block. - * @private - */ -Blockly.InsertionMarkerManager.prototype.createMarkerBlock_ = function(sourceBlock) { - var imType = sourceBlock.type; - - Blockly.Events.disable(); - try { - var result = this.workspace_.newBlock(imType); - result.setInsertionMarker(true, sourceBlock.width); - if (sourceBlock.mutationToDom) { - var oldMutationDom = sourceBlock.mutationToDom(); - if (oldMutationDom) { - result.domToMutation(oldMutationDom); - } - } - result.initSvg(); - } finally { - Blockly.Events.enable(); - } - - return result; -}; - -/** - * Populate the list of available connections on this block stack. This should - * only be called once, at the beginning of a drag. - * If the stack has more than one block, this function will populate - * lastOnStack_ and create the corresponding insertion marker. - * @return {!Array.} a list of available - * connections. - * @private - */ -Blockly.InsertionMarkerManager.prototype.initAvailableConnections_ = function() { - var available = this.topBlock_.getConnections_(false); - // Also check the last connection on this stack - var lastOnStack = this.topBlock_.lastConnectionInStack(); - if (lastOnStack && lastOnStack != this.topBlock_.nextConnection) { - available.push(lastOnStack); - this.lastOnStack_ = lastOnStack; - this.lastMarker_ = this.createMarkerBlock_(lastOnStack.sourceBlock_); - } - return available; -}; - -/**** End initialization functions ****/ - - -/** - * Whether the previews (insertion marker and replacement marker) should be - * updated based on the closest candidate and the current drag distance. - * @param {!Object} candidate An object containing a local connection, a closest - * connection, and a radius. Returned by getCandidate_. - * @param {!goog.math.Coordinate} dxy Position relative to drag start, - * in workspace units. - * @return {boolean} whether the preview should be updated. - * @private - */ -Blockly.InsertionMarkerManager.prototype.shouldUpdatePreviews_ = function( - candidate, dxy) { - var candidateLocal = candidate.local; - var candidateClosest = candidate.closest; - var radius = candidate.radius; - - // Found a connection! - if (candidateLocal && candidateClosest) { - if (candidateLocal.type == Blockly.OUTPUT_VALUE) { - // Always update previews for output connections. - return true; - } - // We're already showing an insertion marker. - // Decide whether the new connection has higher priority. - if (this.localConnection_ && this.closestConnection_) { - // The connection was the same as the current connection. - if (this.closestConnection_ == candidateClosest) { - return false; - } - var xDiff = this.localConnection_.x_ + dxy.x - this.closestConnection_.x_; - var yDiff = this.localConnection_.y_ + dxy.y - this.closestConnection_.y_; - var curDistance = Math.sqrt(xDiff * xDiff + yDiff * yDiff); - // Slightly prefer the existing preview over a new preview. - return !(candidateClosest && radius > curDistance - - Blockly.CURRENT_CONNECTION_PREFERENCE); - } else if (!this.localConnection_ && !this.closestConnection_) { - // We weren't showing a preview before, but we should now. - return true; - } else { - console.error('Only one of localConnection_ and closestConnection_ was set.'); - } - } else { // No connection found. - // Only need to update if we were showing a preview before. - return !!(this.localConnection_ && this.closestConnection_); - } - - console.error('Returning true from shouldUpdatePreviews, but it\'s not clear why.'); - return true; -}; - -/** - * Find the nearest valid connection, which may be the same as the current - * closest connection. - * @param {!goog.math.Coordinate} dxy Position relative to drag start, - * in workspace units. - * @return {!Object} candidate An object containing a local connection, a closest - * connection, and a radius. - */ -Blockly.InsertionMarkerManager.prototype.getCandidate_ = function(dxy) { - var radius = this.getStartRadius_(); - var candidateClosest = null; - var candidateLocal = null; - - for (var i = 0; i < this.availableConnections_.length; i++) { - var myConnection = this.availableConnections_[i]; - var neighbour = myConnection.closest(radius, dxy); - if (neighbour.connection) { - candidateClosest = neighbour.connection; - candidateLocal = myConnection; - radius = neighbour.radius; - } - } - return { - closest: candidateClosest, - local: candidateLocal, - radius: radius - }; -}; - -/** - * Decide the radius at which to start searching for the closest connection. - * @return {number} The radius at which to start the search for the closest - * connection. - * @private - */ -Blockly.InsertionMarkerManager.prototype.getStartRadius_ = function() { - // If there is already a connection highlighted, - // increase the radius we check for making new connections. - // Why? When a connection is highlighted, blocks move around when the insertion - // marker is created, which could cause the connection became out of range. - // By increasing radiusConnection when a connection already exists, - // we never "lose" the connection from the offset. - if (this.closestConnection_ && this.localConnection_) { - return Blockly.CONNECTING_SNAP_RADIUS; - } - return Blockly.SNAP_RADIUS; -}; - -/** - * Whether ending the drag would replace a block or insert a block. - * @return {boolean} True if dropping the block immediately would replace - * another block. False if dropping the block immediately would result in - * the block being inserted in a block stack. - * @private - */ -Blockly.InsertionMarkerManager.prototype.shouldReplace_ = function() { - var closest = this.closestConnection_; - var local = this.localConnection_; - - // Dragging a block over an existing block in an input should replace the - // existing block and bump it out. - if (local.type == Blockly.OUTPUT_VALUE) { - return true; // Replace. - } - - // Connecting to a statement input of c-block is an insertion, even if that - // c-block is terminal (e.g. forever). - if (local == local.sourceBlock_.getFirstStatementConnection()) { - return false; // Insert. - } - - // Dragging a terminal block over another (connected) terminal block will - // replace, not insert. - var isTerminalBlock = !this.topBlock_.nextConnection; - var isConnectedTerminal = isTerminalBlock && - local.type == Blockly.PREVIOUS_STATEMENT && closest.isConnected(); - if (isConnectedTerminal) { - return true; // Replace. - } - - // Otherwise it's an insertion. - return false; -}; - -/** - * Whether ending the drag would delete the block. - * @param {!Object} candidate An object containing a local connection, a closest - * connection, and a radius. - * @param {?number} deleteArea One of {@link Blockly.DELETE_AREA_TRASH}, - * {@link Blockly.DELETE_AREA_TOOLBOX}, or {@link Blockly.DELETE_AREA_NONE}. - * @return {boolean} True if dropping the block immediately would replace - * delete the block. False otherwise. - * @private - */ -Blockly.InsertionMarkerManager.prototype.shouldDelete_ = function(candidate, - deleteArea) { - // Prefer connecting over dropping into the trash can, but prefer dragging to - // the toolbox over connecting to other blocks. - var wouldConnect = candidate && !!candidate.closest && - deleteArea != Blockly.DELETE_AREA_TOOLBOX; - var wouldDelete = !!deleteArea && !this.topBlock_.getParent() && - this.topBlock_.isDeletable(); - - return wouldDelete && !wouldConnect; -}; - -/**** Begin preview visibility functions ****/ - -/** - * Show an insertion marker or replacement highlighting during a drag, if - * needed. - * At the beginning of this function, this.localConnection_ and - * this.closestConnection_ should both be null. - * @param {!Object} candidate An object containing a local connection, a closest - * connection, and a radius. - * @private - */ -Blockly.InsertionMarkerManager.prototype.maybeShowPreview_ = function(candidate) { - // Nope, don't add a marker. - if (this.wouldDeleteBlock_) { - return; - } - var closest = candidate.closest; - var local = candidate.local; - - // Nothing to connect to. - if (!closest) { - return; - } - - // Something went wrong and we're trying to connect to an invalid connection. - if (closest == this.closestConnection_ || - closest.sourceBlock_.isInsertionMarker()) { - return; - } - // Add an insertion marker or replacement marker. - this.closestConnection_ = closest; - this.localConnection_ = local; - this.showPreview_(); -}; - -/** - * A preview should be shown. This function figures out if it should be a block - * highlight or an insertion marker, and shows the appropriate one. - * @private - */ -Blockly.InsertionMarkerManager.prototype.showPreview_ = function() { - if (this.shouldReplace_()) { - this.highlightBlock_(); - } else { // Should insert - this.connectMarker_(); - } -}; - -/** - * Show an insertion marker or replacement highlighting during a drag, if - * needed. - * At the end of this function, this.localConnection_ and - * this.closestConnection_ should both be null. - * @param {!Object} candidate An object containing a local connection, a closest - * connection, and a radius. - * @private - */ -Blockly.InsertionMarkerManager.prototype.maybeHidePreview_ = function(candidate) { - // If there's no new preview, remove the old one but don't bother deleting it. - // We might need it later, and this saves disposing of it and recreating it. - if (!candidate.closest) { - this.hidePreview_(); - } - // If there's a new preview and there was an preview before, and either - // connection has changed, remove the old preview. - var hadPreview = this.closestConnection_ && this.localConnection_; - var closestChanged = this.closestConnection_ != candidate.closest; - var localChanged = this.localConnection_ != candidate.local; - - // Also hide if we had a preview before but now we're going to delete instead. - if (hadPreview && (closestChanged || localChanged || this.wouldDeleteBlock_)) { - this.hidePreview_(); - } - - // Either way, clear out old state. - this.markerConnection_ = null; - this.closestConnection_ = null; - this.localConnection_ = null; -}; - -/** - * A preview should be hidden. This function figures out if it is a block - * highlight or an insertion marker, and hides the appropriate one. - * @private - */ -Blockly.InsertionMarkerManager.prototype.hidePreview_ = function() { - if (this.highlightingBlock_) { - this.unhighlightBlock_(); - } else if (this.markerConnection_) { - this.disconnectMarker_(); - } -}; - -/**** End preview visibility functions ****/ - -/**** Begin block highlighting functions ****/ - -/** - * Add highlighting showing which block will be replaced. - * Scratch-specific code, where "highlighting" applies to a block rather than - * a connection. - */ -Blockly.InsertionMarkerManager.prototype.highlightBlock_ = function() { - var closest = this.closestConnection_; - var local = this.localConnection_; - if (closest.targetBlock()) { - this.highlightedBlock_ = closest.targetBlock(); - closest.targetBlock().highlightForReplacement(true); - } else if(local.type == Blockly.OUTPUT_VALUE) { - this.highlightedBlock_ = closest.sourceBlock_; - closest.sourceBlock_.highlightShapeForInput(closest, true); - } - this.highlightingBlock_ = true; -}; - -/** - * Get rid of the highlighting marking the block that will be replaced. - * Scratch-specific code, where "highlighting" applies to a block rather than - * a connection. - */ -Blockly.InsertionMarkerManager.prototype.unhighlightBlock_ = function() { - var closest = this.closestConnection_; - // If there's no block in place, but we're still connecting to a value input, - // then we must have been highlighting an input shape. - if (closest.type == Blockly.INPUT_VALUE && !closest.isConnected()) { - this.highlightedBlock_.highlightShapeForInput(closest, false); - } else { - this.highlightedBlock_.highlightForReplacement(false); - } - this.highlightedBlock_ = null; - this.highlightingBlock_ = false; -}; - -/**** End block highlighting functions ****/ - -/**** Begin insertion marker display functions ****/ - -/** - * Disconnect the insertion marker block in a manner that returns the stack to - * original state. - * @private - */ -Blockly.InsertionMarkerManager.prototype.disconnectMarker_ = function() { - if (!this.markerConnection_) { - console.log('No insertion marker connection to disconnect'); - return; - } - - var imConn = this.markerConnection_; - var imBlock = imConn.sourceBlock_; - var markerNext = imBlock.nextConnection; - var markerPrev = imBlock.previousConnection; - - - // The insertion marker is the first block in a stack, either because it - // doesn't have a previous connection or because the previous connection is - // not connected. Unplug won't do anything in that case. Instead, unplug the - // following block. - if (imConn == markerNext && !(markerPrev && markerPrev.targetConnection)) { - imConn.targetBlock().unplug(false); - } - // Inside of a C-block, first statement connection. - else if (imConn.type == Blockly.NEXT_STATEMENT && imConn != markerNext) { - var innerConnection = imConn.targetConnection; - innerConnection.sourceBlock_.unplug(false); - - var previousBlockNextConnection = - markerPrev ? markerPrev.targetConnection : null; - - imBlock.unplug(true); - if (previousBlockNextConnection) { - previousBlockNextConnection.connect(innerConnection); - } - } else { - imBlock.unplug(true /* healStack */); - } - - if (imConn.targetConnection) { - throw 'markerConnection_ still connected at the end of disconnectInsertionMarker'; - } - - this.markerConnection_ = null; - imBlock.getSvgRoot().setAttribute('visibility', 'hidden'); -}; - -/** - * Add an insertion marker connected to the appropriate blocks. - * @private - */ -Blockly.InsertionMarkerManager.prototype.connectMarker_ = function() { - var local = this.localConnection_; - var closest = this.closestConnection_; - - var isLastInStack = this.lastOnStack_ && local == this.lastOnStack_; - var imBlock = isLastInStack ? this.lastMarker_ : this.firstMarker_; - var imConn = imBlock.getMatchingConnection(local.sourceBlock_, local); - - goog.asserts.assert(imConn != this.markerConnection_, - 'Made it to connectMarker_ even though the marker isn\'t changing'); - - // Render disconnected from everything else so that we have a valid - // connection location. - imBlock.render(); - imBlock.rendered = true; - imBlock.getSvgRoot().setAttribute('visibility', 'visible'); - - // TODO: positionNewBlock should be on Blockly.BlockSvg, not prototype, - // because it doesn't rely on anything in the block it's called on. - imBlock.positionNewBlock(imBlock, imConn, closest); - - // Connect() also renders the insertion marker. - imConn.connect(closest); - this.markerConnection_ = imConn; -}; - -/**** End insertion marker display functions ****/ diff --git a/core/msg.js b/core/msg.js deleted file mode 100644 index 4ebcad1ab7..0000000000 --- a/core/msg.js +++ /dev/null @@ -1,62 +0,0 @@ -/** - * @license - * Visual Blocks Editor - * - * Copyright 2013 Google Inc. - * https://developers.google.com/blockly/ - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @fileoverview Empty name space for the Message singleton. - * @author scr@google.com (Sheridan Rawlins) - */ -'use strict'; - -/** - * Name space for the Msg singleton. - * Msg gets populated in the message files. - */ -goog.provide('Blockly.Msg'); - - -/** - * Back up original getMsg function. - * @type {!Function} - */ -goog.getMsgOrig = goog.getMsg; - -/** - * Gets a localized message. - * Overrides the default Closure function to check for a Blockly.Msg first. - * Used infrequently, only known case is TODAY button in date picker. - * @param {string} str Translatable string, places holders in the form {$foo}. - * @param {Object=} opt_values Maps place holder name to value. - * @return {string} message with placeholders filled. - * @suppress {duplicate} - */ -goog.getMsg = function(str, opt_values) { - var key = goog.getMsg.blocklyMsgMap[str]; - if (key) { - str = Blockly.Msg[key]; - } - return goog.getMsgOrig(str, opt_values); -}; - -/** - * Mapping of Closure messages to Blockly.Msg names. - */ -goog.getMsg.blocklyMsgMap = { - 'Today': 'TODAY' -}; diff --git a/core/mutator.js b/core/mutator.js deleted file mode 100644 index b85afde174..0000000000 --- a/core/mutator.js +++ /dev/null @@ -1,426 +0,0 @@ -/** - * @license - * Visual Blocks Editor - * - * Copyright 2012 Google Inc. - * https://developers.google.com/blockly/ - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @fileoverview Object representing a mutator dialog. A mutator allows the - * user to change the shape of a block using a nested blocks editor. - * @author fraser@google.com (Neil Fraser) - */ -'use strict'; - -goog.provide('Blockly.Mutator'); - -goog.require('Blockly.Bubble'); -goog.require('Blockly.Events.BlockChange'); -goog.require('Blockly.Events.Ui'); -goog.require('Blockly.Icon'); -goog.require('Blockly.WorkspaceSvg'); -goog.require('goog.dom'); - - -/** - * Class for a mutator dialog. - * @param {!Array.} quarkNames List of names of sub-blocks for flyout. - * @extends {Blockly.Icon} - * @constructor - */ -Blockly.Mutator = function(quarkNames) { - Blockly.Mutator.superClass_.constructor.call(this, null); - this.quarkNames_ = quarkNames; -}; -goog.inherits(Blockly.Mutator, Blockly.Icon); - -/** - * Width of workspace. - * @private - */ -Blockly.Mutator.prototype.workspaceWidth_ = 0; - -/** - * Height of workspace. - * @private - */ -Blockly.Mutator.prototype.workspaceHeight_ = 0; - -/** - * Draw the mutator icon. - * @param {!Element} group The icon group. - * @private - */ -Blockly.Mutator.prototype.drawIcon_ = function(group) { - // Square with rounded corners. - Blockly.utils.createSvgElement('rect', - { - 'class': 'blocklyIconShape', - 'rx': '4', - 'ry': '4', - 'height': '16', - 'width': '16' - }, - group); - // Gear teeth. - Blockly.utils.createSvgElement('path', - { - 'class': 'blocklyIconSymbol', - 'd': 'm4.203,7.296 0,1.368 -0.92,0.677 -0.11,0.41 0.9,1.559 0.41,' + - '0.11 1.043,-0.457 1.187,0.683 0.127,1.134 0.3,0.3 1.8,0 0.3,' + - '-0.299 0.127,-1.138 1.185,-0.682 1.046,0.458 0.409,-0.11 0.9,' + - '-1.559 -0.11,-0.41 -0.92,-0.677 0,-1.366 0.92,-0.677 0.11,' + - '-0.41 -0.9,-1.559 -0.409,-0.109 -1.046,0.458 -1.185,-0.682 ' + - '-0.127,-1.138 -0.3,-0.299 -1.8,0 -0.3,0.3 -0.126,1.135 -1.187,' + - '0.682 -1.043,-0.457 -0.41,0.11 -0.899,1.559 0.108,0.409z' - }, - group); - // Axle hole. - Blockly.utils.createSvgElement( - 'circle', - { - 'class': 'blocklyIconShape', - 'r': '2.7', - 'cx': '8', - 'cy': '8' - }, - group); -}; - -/** - * Clicking on the icon toggles if the mutator bubble is visible. - * Disable if block is uneditable. - * @param {!Event} e Mouse click event. - * @private - * @override - */ -Blockly.Mutator.prototype.iconClick_ = function(e) { - if (this.block_.isEditable()) { - Blockly.Icon.prototype.iconClick_.call(this, e); - } -}; - -/** - * Create the editor for the mutator's bubble. - * @return {!Element} The top-level node of the editor. - * @private - */ -Blockly.Mutator.prototype.createEditor_ = function() { - /* Create the editor. Here's the markup that will be generated: - - [Workspace] - - */ - this.svgDialog_ = Blockly.utils.createSvgElement('svg', - {'x': Blockly.Bubble.BORDER_WIDTH, 'y': Blockly.Bubble.BORDER_WIDTH}, - null); - // Convert the list of names into a list of XML objects for the flyout. - if (this.quarkNames_.length) { - var quarkXml = goog.dom.createDom('xml'); - for (var i = 0, quarkName; quarkName = this.quarkNames_[i]; i++) { - quarkXml.appendChild(goog.dom.createDom('block', {'type': quarkName})); - } - } else { - var quarkXml = null; - } - var workspaceOptions = { - languageTree: quarkXml, - parentWorkspace: this.block_.workspace, - pathToMedia: this.block_.workspace.options.pathToMedia, - RTL: this.block_.RTL, - toolboxPosition: this.block_.RTL ? Blockly.TOOLBOX_AT_RIGHT : - Blockly.TOOLBOX_AT_LEFT, - horizontalLayout: false, - getMetrics: this.getFlyoutMetrics_.bind(this), - setMetrics: null - }; - this.workspace_ = new Blockly.WorkspaceSvg(workspaceOptions, this.block_.workspace.dragSurface); - this.workspace_.isMutator = true; - - // Mutator flyouts go inside the mutator workspace's rather than in - // a top level svg. Instead of handling scale themselves, mutators - // inherit scale from the parent workspace. - // To fix this, scale needs to be applied at a different level in the dom. - var flyoutSvg = this.workspace_.addFlyout_('g'); - var background = this.workspace_.createDom('blocklyMutatorBackground'); - - // Insert the flyout after the but before the block canvas so that - // the flyout is underneath in z-order. This makes blocks layering during - // dragging work properly. - background.insertBefore(flyoutSvg, this.workspace_.svgBlockCanvas_); - this.svgDialog_.appendChild(background); - - return this.svgDialog_; -}; - -/** - * Add or remove the UI indicating if this icon may be clicked or not. - */ -Blockly.Mutator.prototype.updateEditable = function() { - if (!this.block_.isInFlyout) { - if (this.block_.isEditable()) { - if (this.iconGroup_) { - Blockly.utils.removeClass( - /** @type {!Element} */ (this.iconGroup_), - 'blocklyIconGroupReadonly'); - } - } else { - // Close any mutator bubble. Icon is not clickable. - this.setVisible(false); - if (this.iconGroup_) { - Blockly.utils.addClass( - /** @type {!Element} */ (this.iconGroup_), - 'blocklyIconGroupReadonly'); - } - } - } - // Default behaviour for an icon. - Blockly.Icon.prototype.updateEditable.call(this); -}; - -/** - * Callback function triggered when the bubble has resized. - * Resize the workspace accordingly. - * @private - */ -Blockly.Mutator.prototype.resizeBubble_ = function() { - var doubleBorderWidth = 2 * Blockly.Bubble.BORDER_WIDTH; - var workspaceSize = this.workspace_.getCanvas().getBBox(); - var width; - if (this.block_.RTL) { - width = -workspaceSize.x; - } else { - width = workspaceSize.width + workspaceSize.x; - } - var height = workspaceSize.height + doubleBorderWidth * 3; - if (this.workspace_.flyout_) { - var flyoutMetrics = this.workspace_.flyout_.getMetrics_(); - height = Math.max(height, flyoutMetrics.contentHeight + 20); - } - width += doubleBorderWidth * 3; - // Only resize if the size difference is significant. Eliminates shuddering. - if (Math.abs(this.workspaceWidth_ - width) > doubleBorderWidth || - Math.abs(this.workspaceHeight_ - height) > doubleBorderWidth) { - // Record some layout information for getFlyoutMetrics_. - this.workspaceWidth_ = width; - this.workspaceHeight_ = height; - // Resize the bubble. - this.bubble_.setBubbleSize( - width + doubleBorderWidth, height + doubleBorderWidth); - this.svgDialog_.setAttribute('width', this.workspaceWidth_); - this.svgDialog_.setAttribute('height', this.workspaceHeight_); - } - - if (this.block_.RTL) { - // Scroll the workspace to always left-align. - var translation = 'translate(' + this.workspaceWidth_ + ',0)'; - this.workspace_.getCanvas().setAttribute('transform', translation); - } - this.workspace_.resize(); -}; - -/** - * Show or hide the mutator bubble. - * @param {boolean} visible True if the bubble should be visible. - */ -Blockly.Mutator.prototype.setVisible = function(visible) { - if (visible == this.isVisible()) { - // No change. - return; - } - Blockly.Events.fire( - new Blockly.Events.Ui(this.block_, 'mutatorOpen', !visible, visible)); - if (visible) { - // Create the bubble. - this.bubble_ = new Blockly.Bubble( - /** @type {!Blockly.WorkspaceSvg} */ (this.block_.workspace), - this.createEditor_(), this.block_.svgPath_, this.iconXY_, null, null); - var tree = this.workspace_.options.languageTree; - if (tree) { - this.workspace_.flyout_.init(this.workspace_); - this.workspace_.flyout_.show(tree.childNodes); - } - - this.rootBlock_ = this.block_.decompose(this.workspace_); - var blocks = this.rootBlock_.getDescendants(false); - for (var i = 0, child; child = blocks[i]; i++) { - child.render(); - } - // The root block should not be dragable or deletable. - this.rootBlock_.setMovable(false); - this.rootBlock_.setDeletable(false); - if (this.workspace_.flyout_) { - var margin = this.workspace_.flyout_.CORNER_RADIUS * 2; - var x = this.workspace_.flyout_.width_ + margin; - } else { - var margin = 16; - var x = margin; - } - if (this.block_.RTL) { - x = -x; - } - this.rootBlock_.moveBy(x, margin); - // Save the initial connections, then listen for further changes. - if (this.block_.saveConnections) { - var thisMutator = this; - this.block_.saveConnections(this.rootBlock_); - this.sourceListener_ = function() { - thisMutator.block_.saveConnections(thisMutator.rootBlock_); - }; - this.block_.workspace.addChangeListener(this.sourceListener_); - } - this.resizeBubble_(); - // When the mutator's workspace changes, update the source block. - this.workspace_.addChangeListener(this.workspaceChanged_.bind(this)); - this.updateColour(); - } else { - // Dispose of the bubble. - this.svgDialog_ = null; - this.workspace_.dispose(); - this.workspace_ = null; - this.rootBlock_ = null; - this.bubble_.dispose(); - this.bubble_ = null; - this.workspaceWidth_ = 0; - this.workspaceHeight_ = 0; - if (this.sourceListener_) { - this.block_.workspace.removeChangeListener(this.sourceListener_); - this.sourceListener_ = null; - } - } -}; - -/** - * Update the source block when the mutator's blocks are changed. - * Bump down any block that's too high. - * Fired whenever a change is made to the mutator's workspace. - * @private - */ -Blockly.Mutator.prototype.workspaceChanged_ = function() { - if (!this.workspace_.isDragging()) { - var blocks = this.workspace_.getTopBlocks(false); - var MARGIN = 20; - for (var b = 0, block; block = blocks[b]; b++) { - var blockXY = block.getRelativeToSurfaceXY(); - var blockHW = block.getHeightWidth(); - if (blockXY.y + blockHW.height < MARGIN) { - // Bump any block that's above the top back inside. - block.moveBy(0, MARGIN - blockHW.height - blockXY.y); - } - } - } - - // When the mutator's workspace changes, update the source block. - if (this.rootBlock_.workspace == this.workspace_) { - Blockly.Events.setGroup(true); - var block = this.block_; - var oldMutationDom = block.mutationToDom(); - var oldMutation = oldMutationDom && Blockly.Xml.domToText(oldMutationDom); - // Switch off rendering while the source block is rebuilt. - var savedRendered = block.rendered; - block.rendered = false; - // Allow the source block to rebuild itself. - block.compose(this.rootBlock_); - // Restore rendering and show the changes. - block.rendered = savedRendered; - // Mutation may have added some elements that need initializing. - block.initSvg(); - var newMutationDom = block.mutationToDom(); - var newMutation = newMutationDom && Blockly.Xml.domToText(newMutationDom); - if (oldMutation != newMutation) { - Blockly.Events.fire(new Blockly.Events.BlockChange( - block, 'mutation', null, oldMutation, newMutation)); - // Ensure that any bump is part of this mutation's event group. - var group = Blockly.Events.getGroup(); - setTimeout(function() { - Blockly.Events.setGroup(group); - block.bumpNeighbours_(); - Blockly.Events.setGroup(false); - }, Blockly.BUMP_DELAY); - } - if (block.rendered) { - block.render(); - } - // Don't update the bubble until the drag has ended, to avoid moving blocks - // under the cursor. - if (!this.workspace_.isDragging()) { - this.resizeBubble_(); - } - Blockly.Events.setGroup(false); - } -}; - -/** - * Return an object with all the metrics required to size scrollbars for the - * mutator flyout. The following properties are computed: - * .viewHeight: Height of the visible rectangle, - * .viewWidth: Width of the visible rectangle, - * .absoluteTop: Top-edge of view. - * .absoluteLeft: Left-edge of view. - * @return {!Object} Contains size and position metrics of mutator dialog's - * workspace. - * @private - */ -Blockly.Mutator.prototype.getFlyoutMetrics_ = function() { - return { - viewHeight: this.workspaceHeight_, - viewWidth: this.workspaceWidth_, - absoluteTop: 0, - absoluteLeft: 0 - }; -}; - -/** - * Dispose of this mutator. - */ -Blockly.Mutator.prototype.dispose = function() { - this.block_.mutator = null; - Blockly.Icon.prototype.dispose.call(this); -}; - -/** - * Reconnect an block to a mutated input. - * @param {Blockly.Connection} connectionChild Connection on child block. - * @param {!Blockly.Block} block Parent block. - * @param {string} inputName Name of input on parent block. - * @return {boolean} True iff a reconnection was made, false otherwise. - */ -Blockly.Mutator.reconnect = function(connectionChild, block, inputName) { - if (!connectionChild || !connectionChild.getSourceBlock().workspace) { - return false; // No connection or block has been deleted. - } - var connectionParent = block.getInput(inputName).connection; - var currentParent = connectionChild.targetBlock(); - if ((!currentParent || currentParent == block) && - connectionParent.targetConnection != connectionChild) { - if (connectionParent.isConnected()) { - // There's already something connected here. Get rid of it. - connectionParent.disconnect(); - } - connectionParent.connect(connectionChild); - return true; - } - return false; -}; - -// Export symbols that would otherwise be renamed by Closure compiler. -if (!goog.global['Blockly']) { - goog.global['Blockly'] = {}; -} -if (!goog.global['Blockly']['Mutator']) { - goog.global['Blockly']['Mutator'] = {}; -} -goog.global['Blockly']['Mutator']['reconnect'] = Blockly.Mutator.reconnect; diff --git a/core/names.js b/core/names.js deleted file mode 100644 index b76978b62c..0000000000 --- a/core/names.js +++ /dev/null @@ -1,198 +0,0 @@ -/** - * @license - * Visual Blocks Editor - * - * Copyright 2012 Google Inc. - * https://developers.google.com/blockly/ - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @fileoverview Utility functions for handling variables and procedure names. - * @author fraser@google.com (Neil Fraser) - */ -'use strict'; - -goog.provide('Blockly.Names'); - - -/** - * Class for a database of entity names (variables, functions, etc). - * @param {string} reservedWords A comma-separated string of words that are - * illegal for use as names in a language (e.g. 'new,if,this,...'). - * @param {string=} opt_variablePrefix Some languages need a '$' or a namespace - * before all variable names. - * @constructor - */ -Blockly.Names = function(reservedWords, opt_variablePrefix) { - this.variablePrefix_ = opt_variablePrefix || ''; - this.reservedDict_ = Object.create(null); - if (reservedWords) { - var splitWords = reservedWords.split(','); - for (var i = 0; i < splitWords.length; i++) { - this.reservedDict_[splitWords[i]] = true; - } - } - this.reset(); -}; - -/** - * Constant to separate developer variable names from user-defined variable - * names when running generators. - * A developer variable will be declared as a global in the generated code, but - * will never be shown to the user in the workspace or stored in the variable - * map. - */ -Blockly.Names.DEVELOPER_VARIABLE_TYPE = 'DEVELOPER_VARIABLE'; - -/** - * When JavaScript (or most other languages) is generated, variable 'foo' and - * procedure 'foo' would collide. However, Blockly has no such problems since - * variable get 'foo' and procedure call 'foo' are unambiguous. - * Therefore, Blockly keeps a separate type name to disambiguate. - * getName('foo', 'variable') -> 'foo' - * getName('foo', 'procedure') -> 'foo2' - */ - -/** - * Empty the database and start from scratch. The reserved words are kept. - */ -Blockly.Names.prototype.reset = function() { - this.db_ = Object.create(null); - this.dbReverse_ = Object.create(null); - this.variableMap_ = null; -}; - -/** - * Set the variable map that maps from variable name to variable object. - * @param {!Blockly.VariableMap} map The map to track. - * @package - */ -Blockly.Names.prototype.setVariableMap = function(map) { - this.variableMap_ = map; -}; - -/** - * Get the name for a user-defined variable, based on its ID. - * This should only be used for variables of type Blockly.Variables.NAME_TYPE. - * @param {string} id The ID to look up in the variable map. - * @return {?string} The name of the referenced variable, or null if there was - * no variable map or the variable was not found in the map. - * @private - */ -Blockly.Names.prototype.getNameForUserVariable_ = function(id) { - if (!this.variableMap_) { - console.log('Deprecated call to Blockly.Names.prototype.getName without ' + - 'defining a variable map. To fix, add the folowing code in your ' + - 'generator\'s init() function:\n' + - 'Blockly.YourGeneratorName.variableDB_.setVariableMap(' + - 'workspace.getVariableMap());'); - return null; - } - var variable = this.variableMap_.getVariableById(id); - if (variable) { - return variable.name; - } else { - return null; - } -}; - -/** - * Convert a Blockly entity name to a legal exportable entity name. - * @param {string} name The Blockly entity name (no constraints). - * @param {string} type The type of entity in Blockly - * ('VARIABLE', 'PROCEDURE', 'BUILTIN', etc...). - * @return {string} An entity name that is legal in the exported language. - */ -Blockly.Names.prototype.getName = function(name, type) { - if (type == Blockly.Variables.NAME_TYPE) { - var varName = this.getNameForUserVariable_(name); - if (varName) { - name = varName; - } - } - var normalized = name.toLowerCase() + '_' + type; - - var isVarType = type == Blockly.Variables.NAME_TYPE || - type == Blockly.Names.DEVELOPER_VARIABLE_TYPE; - - var prefix = isVarType ? this.variablePrefix_ : ''; - if (normalized in this.db_) { - return prefix + this.db_[normalized]; - } - var safeName = this.getDistinctName(name, type); - this.db_[normalized] = safeName.substr(prefix.length); - return safeName; -}; - -/** - * Convert a Blockly entity name to a legal exportable entity name. - * Ensure that this is a new name not overlapping any previously defined name. - * Also check against list of reserved words for the current language and - * ensure name doesn't collide. - * @param {string} name The Blockly entity name (no constraints). - * @param {string} type The type of entity in Blockly - * ('VARIABLE', 'PROCEDURE', 'BUILTIN', etc...). - * @return {string} An entity name that is legal in the exported language. - */ -Blockly.Names.prototype.getDistinctName = function(name, type) { - var safeName = this.safeName_(name); - var i = ''; - while (this.dbReverse_[safeName + i] || - (safeName + i) in this.reservedDict_) { - // Collision with existing name. Create a unique name. - i = i ? i + 1 : 2; - } - safeName += i; - this.dbReverse_[safeName] = true; - var isVarType = type == Blockly.Variables.NAME_TYPE || - type == Blockly.Names.DEVELOPER_VARIABLE_TYPE; - var prefix = isVarType ? this.variablePrefix_ : ''; - return prefix + safeName; -}; - -/** - * Given a proposed entity name, generate a name that conforms to the - * [_A-Za-z][_A-Za-z0-9]* format that most languages consider legal for - * variables. - * @param {string} name Potentially illegal entity name. - * @return {string} Safe entity name. - * @private - */ -Blockly.Names.prototype.safeName_ = function(name) { - if (!name) { - name = 'unnamed'; - } else { - // Unfortunately names in non-latin characters will look like - // _E9_9F_B3_E4_B9_90 which is pretty meaningless. - // https://github.com/google/blockly/issues/1654 - name = encodeURI(name.replace(/ /g, '_')).replace(/[^\w]/g, '_'); - // Most languages don't allow names with leading numbers. - if ('0123456789'.indexOf(name[0]) != -1) { - name = 'my_' + name; - } - } - return name; -}; - -/** - * Do the given two entity names refer to the same entity? - * Blockly names are case-insensitive. - * @param {string} name1 First name. - * @param {string} name2 Second name. - * @return {boolean} True if names are the same. - */ -Blockly.Names.equals = function(name1, name2) { - return name1.toLowerCase() == name2.toLowerCase(); -}; diff --git a/core/options.js b/core/options.js deleted file mode 100644 index 6e3b79e47a..0000000000 --- a/core/options.js +++ /dev/null @@ -1,244 +0,0 @@ -/** - * @license - * Visual Blocks Editor - * - * Copyright 2016 Google Inc. - * https://developers.google.com/blockly/ - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @fileoverview Object that controls settings for the workspace. - * @author fenichel@google.com (Rachel Fenichel) - */ -'use strict'; - -goog.provide('Blockly.Options'); -goog.require('Blockly.Colours'); - - -/** - * Parse the user-specified options, using reasonable defaults where behaviour - * is unspecified. - * @param {!Object} options Dictionary of options. Specification: - * https://developers.google.com/blockly/guides/get-started/web#configuration - * @constructor - */ -Blockly.Options = function(options) { - var readOnly = !!options['readOnly']; - if (readOnly) { - var languageTree = null; - var hasCategories = false; - var hasTrashcan = false; - var hasCollapse = false; - var hasComments = false; - var hasDisable = false; - var hasSounds = false; - } else { - if (!options['toolbox'] && Blockly.Blocks.defaultToolbox) { - var oParser = new DOMParser(); - var dom = oParser.parseFromString(Blockly.Blocks.defaultToolbox, 'text/xml'); - options['toolbox'] = dom.documentElement; - } - var languageTree = Blockly.Options.parseToolboxTree(options['toolbox']); - var hasCategories = Boolean(languageTree && - languageTree.getElementsByTagName('category').length); - var hasTrashcan = options['trashcan']; - if (hasTrashcan === undefined) { - hasTrashcan = false; - } - var hasCollapse = options['collapse']; - if (hasCollapse === undefined) { - hasCollapse = hasCategories; - } - var hasComments = options['comments']; - if (hasComments === undefined) { - hasComments = hasCategories; - } - var hasDisable = options['disable']; - if (hasDisable === undefined) { - hasDisable = hasCategories; - } - var hasSounds = options['sounds']; - if (hasSounds === undefined) { - hasSounds = true; - } - } - var rtl = !!options['rtl']; - var horizontalLayout = options['horizontalLayout']; - if (horizontalLayout === undefined) { - horizontalLayout = false; - } - var toolboxAtStart = options['toolboxPosition']; - if (toolboxAtStart === 'end') { - toolboxAtStart = false; - } else { - toolboxAtStart = true; - } - - if (horizontalLayout) { - var toolboxPosition = toolboxAtStart ? - Blockly.TOOLBOX_AT_TOP : Blockly.TOOLBOX_AT_BOTTOM; - } else { - var toolboxPosition = (toolboxAtStart == rtl) ? - Blockly.TOOLBOX_AT_RIGHT : Blockly.TOOLBOX_AT_LEFT; - } - - var hasScrollbars = options['scrollbars']; - if (hasScrollbars === undefined) { - hasScrollbars = hasCategories; - } - var hasCss = options['css']; - if (hasCss === undefined) { - hasCss = true; - } - var pathToMedia = 'https://blockly-demo.appspot.com/static/media/'; - if (options['media']) { - pathToMedia = options['media']; - } else if (options['path']) { - // 'path' is a deprecated option which has been replaced by 'media'. - pathToMedia = options['path'] + 'media/'; - } - if (options['oneBasedIndex'] === undefined) { - var oneBasedIndex = true; - } else { - var oneBasedIndex = !!options['oneBasedIndex']; - } - - Blockly.Colours.overrideColours(options['colours']); - - this.RTL = rtl; - this.oneBasedIndex = oneBasedIndex; - this.collapse = hasCollapse; - this.comments = hasComments; - this.disable = hasDisable; - this.readOnly = readOnly; - this.pathToMedia = pathToMedia; - this.hasCategories = hasCategories; - this.hasScrollbars = hasScrollbars; - this.hasTrashcan = hasTrashcan; - this.hasSounds = hasSounds; - this.hasCss = hasCss; - this.horizontalLayout = horizontalLayout; - this.languageTree = languageTree; - this.gridOptions = Blockly.Options.parseGridOptions_(options); - this.zoomOptions = Blockly.Options.parseZoomOptions_(options); - this.toolboxPosition = toolboxPosition; -}; - -/** - * The parent of the current workspace, or null if there is no parent workspace. - * @type {Blockly.Workspace} - **/ -Blockly.Options.prototype.parentWorkspace = null; - -/** - * If set, sets the translation of the workspace to match the scrollbars. - */ -Blockly.Options.prototype.setMetrics = null; - -/** - * Return an object with the metrics required to size the workspace. - * @return {Object} Contains size and position metrics, or null. - */ -Blockly.Options.prototype.getMetrics = null; - -/** - * Parse the user-specified zoom options, using reasonable defaults where - * behaviour is unspecified. See zoom documentation: - * https://developers.google.com/blockly/guides/configure/web/zoom - * @param {!Object} options Dictionary of options. - * @return {!Object} A dictionary of normalized options. - * @private - */ -Blockly.Options.parseZoomOptions_ = function(options) { - var zoom = options['zoom'] || {}; - var zoomOptions = {}; - if (zoom['controls'] === undefined) { - zoomOptions.controls = false; - } else { - zoomOptions.controls = !!zoom['controls']; - } - if (zoom['wheel'] === undefined) { - zoomOptions.wheel = false; - } else { - zoomOptions.wheel = !!zoom['wheel']; - } - if (zoom['startScale'] === undefined) { - zoomOptions.startScale = 1; - } else { - zoomOptions.startScale = parseFloat(zoom['startScale']); - } - if (zoom['maxScale'] === undefined) { - zoomOptions.maxScale = 3; - } else { - zoomOptions.maxScale = parseFloat(zoom['maxScale']); - } - if (zoom['minScale'] === undefined) { - zoomOptions.minScale = 0.3; - } else { - zoomOptions.minScale = parseFloat(zoom['minScale']); - } - if (zoom['scaleSpeed'] === undefined) { - zoomOptions.scaleSpeed = 1.2; - } else { - zoomOptions.scaleSpeed = parseFloat(zoom['scaleSpeed']); - } - return zoomOptions; -}; - -/** - * Parse the user-specified grid options, using reasonable defaults where - * behaviour is unspecified. See grid documentation: - * https://developers.google.com/blockly/guides/configure/web/grid - * @param {!Object} options Dictionary of options. - * @return {!Object} A dictionary of normalized options. - * @private - */ -Blockly.Options.parseGridOptions_ = function(options) { - var grid = options['grid'] || {}; - var gridOptions = {}; - gridOptions.spacing = parseFloat(grid['spacing']) || 0; - gridOptions.colour = grid['colour'] || '#888'; - gridOptions.length = parseFloat(grid['length']) || 1; - gridOptions.snap = gridOptions.spacing > 0 && !!grid['snap']; - return gridOptions; -}; - -/** - * Parse the provided toolbox tree into a consistent DOM format. - * @param {Node|string} tree DOM tree of blocks, or text representation of same. - * @return {Node} DOM tree of blocks, or null. - */ -Blockly.Options.parseToolboxTree = function(tree) { - if (tree) { - if (typeof tree != 'string') { - if (typeof XSLTProcessor == 'undefined' && tree.outerHTML) { - // In this case the tree will not have been properly built by the - // browser. The HTML will be contained in the element, but it will - // not have the proper DOM structure since the browser doesn't support - // XSLTProcessor (XML -> HTML). This is the case in IE 9+. - tree = tree.outerHTML; - } else if (!(tree instanceof Element)) { - tree = null; - } - } - if (typeof tree == 'string') { - tree = Blockly.Xml.textToDom(tree); - } - } else { - tree = null; - } - return tree; -}; diff --git a/core/rendered_connection.js b/core/rendered_connection.js deleted file mode 100644 index 2d56842a51..0000000000 --- a/core/rendered_connection.js +++ /dev/null @@ -1,417 +0,0 @@ -/** - * @license - * Visual Blocks Editor - * - * Copyright 2016 Google Inc. - * https://developers.google.com/blockly/ - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @fileoverview Components for creating connections between blocks. - * @author fenichel@google.com (Rachel Fenichel) - */ -'use strict'; - -goog.provide('Blockly.RenderedConnection'); - -goog.require('Blockly.Connection'); - - -/** - * Class for a connection between blocks that may be rendered on screen. - * @param {!Blockly.Block} source The block establishing this connection. - * @param {number} type The type of the connection. - * @extends {Blockly.Connection} - * @constructor - */ -Blockly.RenderedConnection = function(source, type) { - Blockly.RenderedConnection.superClass_.constructor.call(this, source, type); - - /** - * Workspace units, (0, 0) is top left of block. - * @type {!goog.math.Coordinate} - * @private - */ - this.offsetInBlock_ = new goog.math.Coordinate(0, 0); -}; -goog.inherits(Blockly.RenderedConnection, Blockly.Connection); - -/** - * Returns the distance between this connection and another connection in - * workspace units. - * @param {!Blockly.Connection} otherConnection The other connection to measure - * the distance to. - * @return {number} The distance between connections, in workspace units. - */ -Blockly.RenderedConnection.prototype.distanceFrom = function(otherConnection) { - var xDiff = this.x_ - otherConnection.x_; - var yDiff = this.y_ - otherConnection.y_; - return Math.sqrt(xDiff * xDiff + yDiff * yDiff); -}; - -/** - * Move the block(s) belonging to the connection to a point where they don't - * visually interfere with the specified connection. - * @param {!Blockly.Connection} staticConnection The connection to move away - * from. - * @private - */ -Blockly.RenderedConnection.prototype.bumpAwayFrom_ = function(staticConnection) { - if (this.sourceBlock_.workspace.isDragging()) { - // Don't move blocks around while the user is doing the same. - return; - } - // Move the root block. - var rootBlock = this.sourceBlock_.getRootBlock(); - if (rootBlock.isInFlyout) { - // Don't move blocks around in a flyout. - return; - } - var reverse = false; - if (!rootBlock.isMovable()) { - // Can't bump an uneditable block away. - // Check to see if the other block is movable. - rootBlock = staticConnection.getSourceBlock().getRootBlock(); - if (!rootBlock.isMovable()) { - return; - } - // Swap the connections and move the 'static' connection instead. - staticConnection = this; - reverse = true; - } - // Raise it to the top for extra visibility. - var selected = Blockly.selected == rootBlock; - selected || rootBlock.addSelect(); - var dx = (staticConnection.x_ + Blockly.SNAP_RADIUS) - this.x_; - var dy = (staticConnection.y_ + Blockly.SNAP_RADIUS) - this.y_; - if (reverse) { - // When reversing a bump due to an uneditable block, bump up. - dy = -dy; - } - if (rootBlock.RTL) { - dx = -dx; - } - rootBlock.moveBy(dx, dy); - selected || rootBlock.removeSelect(); -}; - -/** - * Change the connection's coordinates. - * @param {number} x New absolute x coordinate, in workspace coordinates. - * @param {number} y New absolute y coordinate, in workspace coordinates. - */ -Blockly.RenderedConnection.prototype.moveTo = function(x, y) { - // Remove it from its old location in the database (if already present) - if (this.inDB_) { - this.db_.removeConnection_(this); - } - this.x_ = x; - this.y_ = y; - // Insert it into its new location in the database. - if (!this.hidden_) { - this.db_.addConnection(this); - } -}; - -/** - * Change the connection's coordinates. - * @param {number} dx Change to x coordinate, in workspace units. - * @param {number} dy Change to y coordinate, in workspace units. - */ -Blockly.RenderedConnection.prototype.moveBy = function(dx, dy) { - this.moveTo(this.x_ + dx, this.y_ + dy); -}; - -/** - * Move this connection to the location given by its offset within the block and - * the location of the block's top left corner. - * @param {!goog.math.Coordinate} blockTL The location of the top left corner - * of the block, in workspace coordinates. - */ -Blockly.RenderedConnection.prototype.moveToOffset = function(blockTL) { - this.moveTo(blockTL.x + this.offsetInBlock_.x, - blockTL.y + this.offsetInBlock_.y); -}; - -/** - * Set the offset of this connection relative to the top left of its block. - * @param {number} x The new relative x, in workspace units. - * @param {number} y The new relative y, in workspace units. - */ -Blockly.RenderedConnection.prototype.setOffsetInBlock = function(x, y) { - this.offsetInBlock_.x = x; - this.offsetInBlock_.y = y; -}; - -/** - * Move the blocks on either side of this connection right next to each other. - * @private - */ -Blockly.RenderedConnection.prototype.tighten_ = function() { - var dx = this.targetConnection.x_ - this.x_; - var dy = this.targetConnection.y_ - this.y_; - if (dx != 0 || dy != 0) { - var block = this.targetBlock(); - var svgRoot = block.getSvgRoot(); - if (!svgRoot) { - throw 'block is not rendered.'; - } - // Workspace coordinates. - var xy = Blockly.utils.getRelativeXY(svgRoot); - block.getSvgRoot().setAttribute('transform', - 'translate(' + (xy.x - dx) + ',' + (xy.y - dy) + ')'); - block.moveConnections_(-dx, -dy); - } -}; - -/** - * Find the closest compatible connection to this connection. - * All parameters are in workspace units. - * @param {number} maxLimit The maximum radius to another connection. - * @param {!goog.math.Coordinate} dxy Offset between this connection's location - * in the database and the current location (as a result of dragging). - * @return {!{connection: ?Blockly.Connection, radius: number}} Contains two - * properties: 'connection' which is either another connection or null, - * and 'radius' which is the distance. - */ -Blockly.RenderedConnection.prototype.closest = function(maxLimit, dxy) { - return this.dbOpposite_.searchForClosest(this, maxLimit, dxy); -}; - -/** - * Add highlighting around this connection. - */ -Blockly.RenderedConnection.prototype.highlight = function() { - var steps; - steps = 'm -20,0 h 5 ' + Blockly.BlockSvg.NOTCH_PATH_LEFT + ' h 5'; - var xy = this.sourceBlock_.getRelativeToSurfaceXY(); - var x = this.x_ - xy.x; - var y = this.y_ - xy.y; - Blockly.Connection.highlightedPath_ = Blockly.utils.createSvgElement( - 'path', - { - 'class': 'blocklyHighlightedConnectionPath', - 'd': steps, - transform: 'translate(' + x + ',' + y + ')' + - (this.sourceBlock_.RTL ? ' scale(-1 1)' : '') - }, - this.sourceBlock_.getSvgRoot()); -}; - -/** - * Unhide this connection, as well as all down-stream connections on any block - * attached to this connection. This happens when a block is expanded. - * Also unhides down-stream comments. - * @return {!Array.} List of blocks to render. - */ -Blockly.RenderedConnection.prototype.unhideAll = function() { - this.setHidden(false); - // All blocks that need unhiding must be unhidden before any rendering takes - // place, since rendering requires knowing the dimensions of lower blocks. - // Also, since rendering a block renders all its parents, we only need to - // render the leaf nodes. - var renderList = []; - if (this.type != Blockly.INPUT_VALUE && this.type != Blockly.NEXT_STATEMENT) { - // Only spider down. - return renderList; - } - var block = this.targetBlock(); - if (block) { - var connections; - if (block.isCollapsed()) { - // This block should only be partially revealed since it is collapsed. - connections = []; - block.outputConnection && connections.push(block.outputConnection); - block.nextConnection && connections.push(block.nextConnection); - block.previousConnection && connections.push(block.previousConnection); - } else { - // Show all connections of this block. - connections = block.getConnections_(true); - } - for (var i = 0; i < connections.length; i++) { - renderList.push.apply(renderList, connections[i].unhideAll()); - } - if (!renderList.length) { - // Leaf block. - renderList[0] = block; - } - } - return renderList; -}; - -/** - * Remove the highlighting around this connection. - */ -Blockly.RenderedConnection.prototype.unhighlight = function() { - goog.dom.removeNode(Blockly.Connection.highlightedPath_); - delete Blockly.Connection.highlightedPath_; -}; - -/** - * Set whether this connections is hidden (not tracked in a database) or not. - * @param {boolean} hidden True if connection is hidden. - */ -Blockly.RenderedConnection.prototype.setHidden = function(hidden) { - this.hidden_ = hidden; - if (hidden && this.inDB_) { - this.db_.removeConnection_(this); - } else if (!hidden && !this.inDB_) { - this.db_.addConnection(this); - } -}; - -/** - * Hide this connection, as well as all down-stream connections on any block - * attached to this connection. This happens when a block is collapsed. - * Also hides down-stream comments. - */ -Blockly.RenderedConnection.prototype.hideAll = function() { - this.setHidden(true); - if (this.targetConnection) { - var blocks = this.targetBlock().getDescendants(false); - for (var i = 0; i < blocks.length; i++) { - var block = blocks[i]; - // Hide all connections of all children. - var connections = block.getConnections_(true); - for (var j = 0; j < connections.length; j++) { - connections[j].setHidden(true); - } - // Close all bubbles of all children. - var icons = block.getIcons(); - for (var j = 0; j < icons.length; j++) { - icons[j].setVisible(false); - } - } - } -}; - -/** - * Check if the two connections can be dragged to connect to each other. - * @param {!Blockly.Connection} candidate A nearby connection to check. - * @param {number} maxRadius The maximum radius allowed for connections, in - * workspace units. - * @return {boolean} True if the connection is allowed, false otherwise. - */ -Blockly.RenderedConnection.prototype.isConnectionAllowed = function(candidate, - maxRadius) { - if (this.distanceFrom(candidate) > maxRadius) { - return false; - } - - return Blockly.RenderedConnection.superClass_.isConnectionAllowed.call(this, - candidate); -}; - -/** - * Disconnect two blocks that are connected by this connection. - * @param {!Blockly.Block} parentBlock The superior block. - * @param {!Blockly.Block} childBlock The inferior block. - * @private - */ -Blockly.RenderedConnection.prototype.disconnectInternal_ = function(parentBlock, - childBlock) { - Blockly.RenderedConnection.superClass_.disconnectInternal_.call(this, - parentBlock, childBlock); - // Rerender the parent so that it may reflow. - if (parentBlock.rendered) { - parentBlock.render(); - } - if (childBlock.rendered) { - childBlock.updateDisabled(); - childBlock.render(); - } -}; - -/** - * Respawn the shadow block if there was one connected to the this connection. - * Render/rerender blocks as needed. - * @private - */ -Blockly.RenderedConnection.prototype.respawnShadow_ = function() { - var parentBlock = this.getSourceBlock(); - // Respawn the shadow block if there is one. - var shadow = this.getShadowDom(); - if (parentBlock.workspace && shadow && Blockly.Events.recordUndo) { - Blockly.RenderedConnection.superClass_.respawnShadow_.call(this); - var blockShadow = this.targetBlock(); - if (!blockShadow) { - throw 'Couldn\'t respawn the shadow block that should exist here.'; - } - blockShadow.initSvg(); - blockShadow.render(false); - if (parentBlock.rendered) { - parentBlock.render(); - } - } -}; - -/** - * Find all nearby compatible connections to this connection. - * Type checking does not apply, since this function is used for bumping. - * @param {number} maxLimit The maximum radius to another connection, in - * workspace units. - * @return {!Array.} List of connections. - * @private - */ -Blockly.RenderedConnection.prototype.neighbours_ = function(maxLimit) { - return this.dbOpposite_.getNeighbours(this, maxLimit); -}; - -/** - * Connect two connections together. This is the connection on the superior - * block. Rerender blocks as needed. - * @param {!Blockly.Connection} childConnection Connection on inferior block. - * @private - */ -Blockly.RenderedConnection.prototype.connect_ = function(childConnection) { - Blockly.RenderedConnection.superClass_.connect_.call(this, childConnection); - - var parentConnection = this; - var parentBlock = parentConnection.getSourceBlock(); - var childBlock = childConnection.getSourceBlock(); - - if (parentBlock.rendered) { - parentBlock.updateDisabled(); - } - if (childBlock.rendered) { - childBlock.updateDisabled(); - } - if (parentBlock.rendered && childBlock.rendered) { - if (parentConnection.type == Blockly.NEXT_STATEMENT || - parentConnection.type == Blockly.PREVIOUS_STATEMENT) { - // Child block may need to square off its corners if it is in a stack. - // Rendering a child will render its parent. - childBlock.render(); - } else { - // Child block does not change shape. Rendering the parent node will - // move its connected children into position. - parentBlock.render(); - } - } -}; - -/** - * Function to be called when this connection's compatible types have changed. - * @private - */ -Blockly.RenderedConnection.prototype.onCheckChanged_ = function() { - // The new value type may not be compatible with the existing connection. - if (this.isConnected() && !this.checkType_(this.targetConnection)) { - var child = this.isSuperior() ? this.targetBlock() : this.sourceBlock_; - child.unplug(); - // Bump away. - this.sourceBlock_.bumpNeighbours_(); - } -}; diff --git a/core/scratch_block_comment.js b/core/scratch_block_comment.js deleted file mode 100644 index bb60524e6d..0000000000 --- a/core/scratch_block_comment.js +++ /dev/null @@ -1,653 +0,0 @@ -/** - * @license - * Visual Blocks Editor - * - * Copyright 2018 Google Inc. - * https://developers.google.com/blockly/ - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @fileoverview Object representing a code comment. - * @author kchadha@scratch.mit.edu (Karishma Chadha) - */ -'use strict'; - -goog.provide('Blockly.ScratchBlockComment'); - -goog.require('Blockly.Comment'); -goog.require('Blockly.Events.BlockChange'); -goog.require('Blockly.Events.Ui'); -goog.require('Blockly.Icon'); -goog.require('Blockly.ScratchBubble'); - -goog.require('goog.math.Coordinate'); -goog.require('goog.userAgent'); - - -/** - * Class for a comment. - * @param {!Blockly.Block} block The block associated with this comment. - * @param {string} text The text content of this comment. - * @param {string=} id Optional uid for comment; a new one will be generated if - * not provided. - * @param {number=} x Initial x position for comment, in workspace coordinates. - * @param {number=} y Initial y position for comment, in workspace coordinates. - * @param {boolean=} minimized Whether or not this comment is minimized - * (only the top bar displays), defaults to false. - * @extends {Blockly.Comment} - * @constructor - */ -Blockly.ScratchBlockComment = function(block, text, id, x, y, minimized) { - Blockly.ScratchBlockComment.superClass_.constructor.call(this, block); - /** - * The text content of this comment. - * @type {string} - * @private - */ - this.text_ = text; - - var xIsValidNumber = typeof x == 'number' && !isNaN(x); - var yIsValidNumber = typeof y == 'number' && !isNaN(y); - - /** - * Whether this comment needs to be auto-positioned (based on provided values - * for x and y position). - * @type {boolean} - * @private - */ - this.needsAutoPositioning_ = !xIsValidNumber && !yIsValidNumber; - // If both of the given x and y params are invalid, this comment needs to be auto positioned. - - /** - * The x position of this comment in workspace coordinates. Default to 0 if - * x position is not provided or is not a valid number. - * @type {number} - * @private - */ - this.x_ = xIsValidNumber ? x : 0; - /** - * The y position of this comment in workspace coordinates. Default to 0 if - * y position is not provided or is not a valid number. - * @type {number} - * @private - */ - this.y_ = yIsValidNumber ? y : 0; - /** - * Whether this comment is minimized. - * @type {boolean} - * @private - */ - this.isMinimized_ = minimized || false; - - /** - * The workspace this comment belongs to. - * @type {Blockly.Workspace} - * @package - */ - this.workspace = block.workspace; - /** - * The unique identifier for this comment. - * @type {string} - * @package - */ - this.id = goog.isString(id) && !this.workspace.getCommentById(id) ? - id : Blockly.utils.genUid(); - this.workspace.addTopComment(this); - - /** - * The id of the block this comment belongs to. - * @type {string} - * @package - */ - this.blockId = block.id; - - if (!block.rendered) { - Blockly.ScratchBlockComment.fireCreateEvent(this); - } - // If the block is rendered, fire event the create event when the comment is made - // visible -}; -goog.inherits(Blockly.ScratchBlockComment, Blockly.Comment); - -/** - * Width of bubble. - * @private - */ -Blockly.ScratchBlockComment.prototype.width_ = 200; - -/** - * Height of bubble. - * @private - */ -Blockly.ScratchBlockComment.prototype.height_ = 200; - -/** - * Comment Icon Size. - * @package - */ -Blockly.ScratchBlockComment.prototype.SIZE = 0; - -/** - * Offset for text area in comment bubble. - * @private - */ -Blockly.ScratchBlockComment.TEXTAREA_OFFSET = 12; - -/** - * Maximum lable length (actual label length will include - * one additional character, the ellipsis). - * @private - */ -Blockly.ScratchBlockComment.MAX_LABEL_LENGTH = 12; - -/** - * Maximum character length for comment text. - * @private - */ -Blockly.ScratchBlockComment.COMMENT_TEXT_LIMIT = 8000; - -/** - * Width that a minimized comment should have. - * @private - */ -Blockly.ScratchBlockComment.MINIMIZE_WIDTH = 200; - -/** - * Draw the comment icon. - * @param {!Element} _group The icon group. - * @private - */ -Blockly.ScratchBlockComment.prototype.drawIcon_ = function(_group) { - // NO-OP -- Don't render a comment icon for Scratch block comments -}; - -// Override renderIcon from Blocky.Icon so that the comment bubble is -// anchored correctly on the block. This function takes in the top margin -// as an input instead of setting an arbitrary one. -/** - * Render the icon. - * @param {number} cursorX Horizontal offset at which to position the icon. - * @param {number} topMargin Vertical offset from the top of the block to position the icon. - * @return {number} Horizontal offset for next item to draw. - * @package - */ -Blockly.ScratchBlockComment.prototype.renderIcon = function(cursorX, topMargin) { - if (this.collapseHidden && this.block_.isCollapsed()) { - this.iconGroup_.setAttribute('display', 'none'); - return cursorX; - } - this.iconGroup_.setAttribute('display', 'block'); - - var width = this.SIZE; - if (this.block_.RTL) { - cursorX -= width; - } - this.iconGroup_.setAttribute('transform', - 'translate(' + cursorX + ',' + topMargin + ')'); - this.computeIconLocation(); - if (this.block_.RTL) { - cursorX -= Blockly.BlockSvg.SEP_SPACE_X; - } else { - cursorX += width + Blockly.BlockSvg.SEP_SPACE_X; - } - return cursorX; -}; - -/** - * Create the editor for the comment's bubble. - * @return {{commentEditor: !Element, labelText: !string}} The components used - * to render the comment editing/writing area and the truncated label text - * to display in the minimized comment top bar. - * @private - */ -Blockly.ScratchBlockComment.prototype.createEditor_ = function() { - this.foreignObject_ = Blockly.utils.createSvgElement('foreignObject', - { - 'x': Blockly.ScratchBubble.BORDER_WIDTH, - 'y': Blockly.ScratchBubble.BORDER_WIDTH + Blockly.ScratchBubble.TOP_BAR_HEIGHT, - 'class': 'scratchCommentForeignObject' - }, - null); - var body = document.createElementNS(Blockly.HTML_NS, 'body'); - body.setAttribute('xmlns', Blockly.HTML_NS); - body.className = 'blocklyMinimalBody scratchCommentBody'; - var textarea = document.createElementNS(Blockly.HTML_NS, 'textarea'); - textarea.className = 'scratchCommentTextarea scratchCommentText'; - textarea.setAttribute('dir', this.block_.RTL ? 'RTL' : 'LTR'); - textarea.setAttribute('maxlength', Blockly.ScratchBlockComment.COMMENT_TEXT_LIMIT); - textarea.setAttribute('placeholder', Blockly.Msg.WORKSPACE_COMMENT_DEFAULT_TEXT); - body.appendChild(textarea); - this.textarea_ = textarea; - this.textarea_.style.margin = (Blockly.ScratchBlockComment.TEXTAREA_OFFSET) + 'px'; - this.foreignObject_.appendChild(body); - Blockly.bindEventWithChecks_(textarea, 'mousedown', this, - this.textareaFocus_, true, true); // noCapture and do not prevent default - // Don't zoom with mousewheel. - Blockly.bindEventWithChecks_(textarea, 'wheel', this, function(e) { - e.stopPropagation(); - }); - Blockly.bindEventWithChecks_(textarea, 'change', this, function(_e) { - if (this.text_ != textarea.value) { - Blockly.Events.fire(new Blockly.Events.CommentChange( - this, {text: this.text_}, {text: textarea.value})); - this.text_ = textarea.value; - } - }); - - // Label for comment top bar when comment is minimized - this.label_ = this.getLabelText(); - - return { - commentEditor: this.foreignObject_, - labelText: this.label_ - }; -}; - -/** - * Handle text area click, make sure to stop propagation to allow default selection behavior. - * @param {!Event} e Mouse up event. - * @private - */ -Blockly.ScratchBlockComment.prototype.textareaFocus_ = function(e) { - Blockly.ScratchBlockComment.superClass_.textareaFocus_.call(this, e); - // Stop event from propagating to the workspace to make sure preventDefault _is not called_. - e.stopPropagation(); -}; - - -/** - * Callback function triggered when the bubble has resized. - * Resize the text area accordingly. - * @private - */ -Blockly.ScratchBlockComment.prototype.resizeBubble_ = function() { - if (this.isVisible() && !this.isMinimized_) { - var size = this.bubble_.getBubbleSize(); - var doubleBorderWidth = 2 * Blockly.ScratchBubble.BORDER_WIDTH; - var textOffset = Blockly.ScratchBlockComment.TEXTAREA_OFFSET * 2; - this.foreignObject_.setAttribute('width', size.width - doubleBorderWidth); - this.foreignObject_.setAttribute('height', size.height - doubleBorderWidth - Blockly.ScratchBubble.TOP_BAR_HEIGHT); - this.textarea_.style.width = (size.width - textOffset) + 'px'; - this.textarea_.style.height = (size.height - doubleBorderWidth - - Blockly.ScratchBubble.TOP_BAR_HEIGHT - textOffset) + 'px'; - - // Actually set the size! - this.width_ = size.width; - this.height_ = size.height; - } -}; - -/** - * Change the colour of the associated bubble to match its block. - * @package - */ -Blockly.ScratchBlockComment.prototype.updateColour = function() { - if (this.isVisible()) { - this.bubble_.setColour(this.block_.getColourTertiary()); - } -}; - -/** - * Auto position this comment given information about the block that owns this - * comment and the comment state, if this block needs auto positioning. - * @private - */ -Blockly.ScratchBlockComment.prototype.autoPosition_ = function() { - if (!this.needsAutoPositioning_) return; - if (this.isMinimized_) { - var minimizedOffset = 4 * Blockly.BlockSvg.GRID_UNIT; - this.x_ = this.block_.RTL ? - this.iconXY_.x - this.getBubbleSize().width - minimizedOffset : - this.iconXY_.x + minimizedOffset; - this.y_ = this.iconXY_.y - (Blockly.ScratchBubble.TOP_BAR_HEIGHT / 2); - } else { - // Position comment so that the expanded bubble does not overlap - // blocks below it in the stack that are wider than this block - // Overhang is the difference between this blocks trailing edge and - // the largest block below (zero if this block is the widest) - var thisBlockWidth = Math.floor(this.block_.svgPath_.getBBox().width); - var fullStackWidth = Math.floor(this.block_.getHeightWidth().width); - var overhang = fullStackWidth - thisBlockWidth; - var offset = 8 * Blockly.BlockSvg.GRID_UNIT; - this.x_ = this.block_.RTL ? - this.iconXY_.x - this.width_ - overhang - offset : - this.iconXY_.x + overhang + offset; - this.y_ = this.iconXY_.y - (Blockly.ScratchBubble.TOP_BAR_HEIGHT / 2); - } -}; - -/** - * Show or hide the comment bubble. - * @param {boolean} visible True if the bubble should be visible. - * @package - */ -Blockly.ScratchBlockComment.prototype.setVisible = function(visible) { - if (visible == this.isVisible()) { - // No change. - return; - } - if ((!this.block_.isEditable() && !this.textarea_) || goog.userAgent.IE) { - // Steal the code from warnings to make an uneditable text bubble. - // MSIE does not support foreignobject; textareas are impossible. - // http://msdn.microsoft.com/en-us/library/hh834675%28v=vs.85%29.aspx - // Always treat comments in IE as uneditable. - Blockly.Warning.prototype.setVisible.call(this, visible); - return; - } - // Save the bubble stats before the visibility switch. - var text = this.getText(); - var size = this.getBubbleSize(); - if (visible) { - // Auto position this comment, if necessary. - if (this.needsAutoPositioning_) { - this.autoPosition_(); - // This comment has been auto-positioned so reset the flag - this.needsAutoPositioning_ = false; - } - - // Create the bubble. - this.bubble_ = new Blockly.ScratchBubble( - this, /** @type {!Blockly.WorkspaceSvg} */ (this.block_.workspace), - this.createEditor_(), this.iconXY_, this.width_, this.height_, - this.x_, this.y_, this.isMinimized_); - this.bubble_.setAutoLayout(false); - this.bubble_.registerResizeEvent(this.resizeBubble_.bind(this)); - this.bubble_.registerMinimizeToggleEvent(this.toggleMinimize_.bind(this)); - this.bubble_.registerDeleteEvent(this.dispose.bind(this)); - this.bubble_.registerContextMenuCallback(this.showContextMenu_.bind(this)); - this.updateColour(); - } else { - // Dispose of the bubble. - this.bubble_.dispose(); - this.bubble_ = null; - this.textarea_ = null; - this.foreignObject_ = null; - this.label_ = null; - } - // Restore the bubble stats after the visibility switch. - this.setText(text); - this.setBubbleSize(size.width, size.height); - if (visible) { - Blockly.ScratchBlockComment.fireCreateEvent(this); - } -}; - -/** - * Toggle the minimization state of this comment. - * @private - */ -Blockly.ScratchBlockComment.prototype.toggleMinimize_ = function() { - this.setMinimized(!this.isMinimized_); -}; - -/** - * Set the minimized state for this comment. - * @param {boolean} minimize Whether the comment should be minimized - * @package - */ -Blockly.ScratchBlockComment.prototype.setMinimized = function(minimize) { - if (this.isMinimized_ == minimize) { - return; - } - Blockly.Events.fire(new Blockly.Events.CommentChange(this, - {minimized: this.isMinimized_}, {minimized: minimize})); - this.isMinimized_ = minimize; - if (minimize) { - this.bubble_.setMinimized(true, this.getLabelText()); - this.setBubbleSize(Blockly.ScratchBlockComment.MINIMIZE_WIDTH, - Blockly.ScratchBubble.TOP_BAR_HEIGHT); - // Note we are not updating this.width_ or this.height_ here - // because we want to keep track of the width/height of the - // maximized comment - } else { - this.bubble_.setMinimized(false); - this.setText(this.text_); - this.setBubbleSize(this.width_, this.height_); - } -}; - -/** - * Size this comment's bubble. - * @param {number} width Width of the bubble. - * @param {number} height Height of the bubble. - * @package - */ -Blockly.ScratchBlockComment.prototype.setBubbleSize = function(width, height) { - if (this.bubble_) { - if (this.isMinimized_) { - this.bubble_.setBubbleSize(Blockly.ScratchBlockComment.MINIMIZE_WIDTH, - Blockly.ScratchBubble.TOP_BAR_HEIGHT); - } else { - this.bubble_.setBubbleSize(width, height); - } - } -}; - -/** - * Set the un-minimized size of this comment. If the comment has an un-minimized - * bubble, also set the bubble's size. - * @param {number} width Width of the unminimized comment. - * @param {number} height Height of the unminimized comment. - * @package - */ -Blockly.ScratchBlockComment.prototype.setSize = function(width, height) { - var oldWidth = this.width_; - var oldHeight = this.height_; - - if (!this.isMinimized_) { - this.setBubbleSize(width, height); - } - - this.height_ = height; - this.width_ = width; - - if (oldWidth != this.width_ || oldHeight != this.height_) { - Blockly.Events.fire(new Blockly.Events.CommentChange( - this, - {width: oldWidth, height: oldHeight}, - {width: this.width_, height: this.height_})); - } -}; - -/** - * Get the truncated text for this comment to display in the minimized - * top bar. - * @return {string} The truncated comment text - * @package - */ -Blockly.ScratchBlockComment.prototype.getLabelText = function() { - if (this.text_.length > Blockly.ScratchBlockComment.MAX_LABEL_LENGTH) { - if (this.block_.RTL) { - return '\u2026' + this.text_.slice(0, Blockly.ScratchBlockComment.MAX_LABEL_LENGTH); - } - return this.text_.slice(0, Blockly.ScratchBlockComment.MAX_LABEL_LENGTH) + '\u2026'; - } else { - return this.text_; - } -}; - -/** - * Set this comment's text. - * @param {string} text Comment text. - * @package - */ -Blockly.ScratchBlockComment.prototype.setText = function(text) { - if (this.text_ != text) { - Blockly.Events.fire(new Blockly.Events.CommentChange( - this, {text: this.text_}, {text: text})); - this.text_ = text; - } - if (this.textarea_) { - this.textarea_.value = text; - } -}; - -/** - * Move this comment to a position given x and y coordinates. - * @param {number} x The x-coordinate on the workspace. - * @param {number} y The y-coordinate on the workspace. - * @package - */ -Blockly.ScratchBlockComment.prototype.moveTo = function(x, y) { - var event = new Blockly.Events.CommentMove(this); - if (this.bubble_) { - this.bubble_.moveTo(x, y); - } - this.x_ = x; - this.y_ = y; - event.recordNew(); - Blockly.Events.fire(event); -}; - -/** - * Get the x and y position of this comment. - * @return {goog.math.Coordinate} The XY position - * @package - */ -Blockly.ScratchBlockComment.prototype.getXY = function() { - if (this.bubble_) { - return this.bubble_.getRelativeToSurfaceXY(); - } - // Auto position this comment if iconXY_ is provided - // (auto positioning will only occur if it is necessary). - if (this.needsAutoPositioning_ && this.iconXY_) { - this.autoPosition_(); - // Do not reset the needsAutoPositioning flag here. This will be reset - // after the comment has been made visible and the re-auto positioned, - // because the block may have moved by that point. - } - return new goog.math.Coordinate(this.x_, this.y_); -}; - -/** - * Get the height and width of this comment. - * Note: this does not use the current bubble size because - * the bubble may be minimized. - * @return {{height: number, width: number}} The height and width of - * this comment when it is full size. These numbers do not change - * as the workspace zoom changes. - * @package - */ -Blockly.ScratchBlockComment.prototype.getHeightWidth = function() { - return {height: this.height_, width: this.width_}; -}; - -/** - * Returns the coordinates of a bounding box describing the dimensions of this - * comment. - * Coordinate system: workspace coordinates. - * @return {!{topLeft: goog.math.Coordinate, bottomRight: goog.math.Coordinate}} - * Object with top left and bottom right coordinates of the bounding box. - * @package - */ -Blockly.ScratchBlockComment.prototype.getBoundingRectangle = function() { - var commentXY = this.getXY(); - var commentBounds = this.getBubbleSize(); - var topLeft; - var bottomRight; - if (this.workspace.RTL) { - // TODO (#1562) for some reason this doesn't work with workspace scroll in RTL - topLeft = new goog.math.Coordinate(commentXY.x - commentBounds.width, - commentXY.y); - bottomRight = new goog.math.Coordinate(commentXY.x, - commentXY.y + commentBounds.height); - } else { - topLeft = new goog.math.Coordinate(commentXY.x, commentXY.y); - bottomRight = new goog.math.Coordinate(commentXY.x + commentBounds.width, - commentXY.y + commentBounds.height); - } - return {topLeft: topLeft, bottomRight: bottomRight}; -}; - -/** - * Check whether this comment is currently minimized. - * @return {boolean} True if minimized - * @package - */ -Blockly.ScratchBlockComment.prototype.isMinimized = function() { - return this.isMinimized_; -}; - -/** - * Show the context menu for this comment's bubble. - * @param {!Event} e The mouse event - * @private - */ -Blockly.ScratchBlockComment.prototype.showContextMenu_ = function(e) { - var menuOptions = []; - menuOptions.push(Blockly.ContextMenu.commentDeleteOption(this, Blockly.Msg.DELETE)); - Blockly.ContextMenu.show(e, menuOptions, this.block_.RTL); -}; - -/** - * Encode a comment subtree as XML with XY coordinates. - * @param {boolean=} opt_noId True if the encoder should skip the comment id. - * @return {!Element} Tree of XML elements. - * @package - */ -Blockly.ScratchBlockComment.prototype.toXmlWithXY = function() { - var element = goog.dom.createDom('comment'); - element.setAttribute('id', this.id); - element.textContent = this.text_; - element.setAttribute('x', Math.round( - this.workspace.RTL ? this.workspace.getWidth() - this.x_ : this.x_)); - element.setAttribute('y', Math.round(this.y_)); - element.setAttribute('h', this.height_); - element.setAttribute('w', this.width_); - return element; -}; - -/** - * Fire a create event for the given workspace comment, if comments are enabled. - * @param {!Blockly.WorkspaceComment} comment The comment that was just created. - * @package - */ -Blockly.ScratchBlockComment.fireCreateEvent = function(comment) { - if (Blockly.Events.isEnabled()) { - var existingGroup = Blockly.Events.getGroup(); - if (!existingGroup) { - Blockly.Events.setGroup(true); - } - try { - Blockly.Events.fire(new Blockly.Events.CommentCreate(comment)); - } finally { - if (!existingGroup) { - Blockly.Events.setGroup(false); - } - } - } -}; - -/** - * Dispose of this comment. - */ -Blockly.ScratchBlockComment.prototype.dispose = function() { - if (Blockly.Events.isEnabled()) { - // Emit delete event before disposal begins so that the - // event's reference to this comment contains all the relevant - // information (for undoing this event) - Blockly.Events.fire(new Blockly.Events.CommentDelete(this)); - } - this.block_.comment = null; - this.workspace.removeTopComment(this); - Blockly.Icon.prototype.dispose.call(this); -}; - -/** - * Focus this comments textarea. - */ -Blockly.ScratchBlockComment.prototype.focus = function() { - this.textarea_.focus(); -}; diff --git a/core/scratch_bubble.js b/core/scratch_bubble.js deleted file mode 100644 index 8c80345d78..0000000000 --- a/core/scratch_bubble.js +++ /dev/null @@ -1,696 +0,0 @@ -/** - * @license - * Visual Blocks Editor - * - * Copyright 2018 Google Inc. - * https://developers.google.com/blockly/ - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @fileoverview Object representing a UI bubble. - * @author kchadha@scratch.mit.edu (Karishma Chadha) - */ -'use strict'; - -goog.provide('Blockly.ScratchBubble'); - -goog.require('Blockly.Touch'); -goog.require('Blockly.Workspace'); -goog.require('goog.dom'); -goog.require('goog.math'); -goog.require('goog.math.Coordinate'); -goog.require('goog.userAgent'); - - -/** - * Class for Scratch comment UI bubble. - * @param {!Blockly.ScratchBlockComment} comment The comment this bubble belongs - * to. - * @param {!Blockly.WorkspaceSvg} workspace The workspace on which to draw the - * bubble. - * @param {!Element} content SVG content for the bubble. - * @param {!goog.math.Coordinate} anchorXY Absolute position of bubble's anchor - * point. - * @param {?number} bubbleWidth Width of bubble, or null if not resizable. - * @param {?number} bubbleHeight Height of bubble, or null if not resizable. - * @param {?number} bubbleX X position of bubble - * @param {?number} bubbleY Y position of bubble - * @param {?boolean} minimized Whether or not this comment bubble is minimized - * (only the top bar displays), defaults to false if not provided. - * @extends {Blockly.Bubble} - * @constructor - */ -Blockly.ScratchBubble = function(comment, workspace, content, anchorXY, - bubbleWidth, bubbleHeight, bubbleX, bubbleY, minimized) { - - // Needed for Events - /** - * The comment this bubble belongs to. - * @type {Blockly.ScratchBlockComment} - * @package - */ - this.comment = comment; - - this.workspace_ = workspace; - this.content_ = content; - this.x = bubbleX; - this.y = bubbleY; - this.isMinimized_ = minimized || false; - var canvas = workspace.getBubbleCanvas(); - canvas.appendChild(this.createDom_(content, !!(bubbleWidth && bubbleHeight), - this.isMinimized_)); - - this.setAnchorLocation(anchorXY); - if (!bubbleWidth || !bubbleHeight) { - var bBox = /** @type {SVGLocatable} */ (this.content_).getBBox(); - bubbleWidth = bBox.width + 2 * Blockly.ScratchBubble.BORDER_WIDTH; - bubbleHeight = bBox.height + 2 * Blockly.ScratchBubble.BORDER_WIDTH; - } - this.setBubbleSize(bubbleWidth, bubbleHeight); - - // Render the bubble. - this.positionBubble_(); - this.renderArrow_(); - this.rendered_ = true; - - if (!workspace.options.readOnly) { - Blockly.bindEventWithChecks_( - this.minimizeArrow_, 'mousedown', this, this.minimizeArrowMouseDown_, true); - Blockly.bindEventWithChecks_( - this.minimizeArrow_, 'mouseout', this, this.minimizeArrowMouseOut_, true); - Blockly.bindEventWithChecks_( - this.minimizeArrow_, 'mouseup', this, this.minimizeArrowMouseUp_, true); - Blockly.bindEventWithChecks_( - this.deleteIcon_, 'mousedown', this, this.deleteMouseDown_, true); - Blockly.bindEventWithChecks_( - this.deleteIcon_, 'mouseout', this, this.deleteMouseOut_, true); - Blockly.bindEventWithChecks_( - this.deleteIcon_, 'mouseup', this, this.deleteMouseUp_, true); - Blockly.bindEventWithChecks_( - this.commentTopBar_, 'mousedown', this, this.bubbleMouseDown_); - Blockly.bindEventWithChecks_( - this.bubbleBack_, 'mousedown', this, this.bubbleMouseDown_); - if (this.resizeGroup_) { - Blockly.bindEventWithChecks_( - this.resizeGroup_, 'mousedown', this, this.resizeMouseDown_); - Blockly.bindEventWithChecks_( - this.resizeGroup_, 'mouseup', this, this.resizeMouseUp_); - } - } - - this.setAutoLayout(false); - this.moveTo(this.x, this.y); -}; -goog.inherits(Blockly.ScratchBubble, Blockly.Bubble); - -/** - * Width of the border around the bubble. - * @package - */ -Blockly.ScratchBubble.BORDER_WIDTH = 1; - -/** - * Thickness of the line connecting the bubble - * to the block. - * @private - */ -Blockly.ScratchBubble.LINE_THICKNESS = 1; - -/** - * The height of the comment top bar. - * @package - */ -Blockly.ScratchBubble.TOP_BAR_HEIGHT = 32; - -/** - * The size of the minimize arrow icon in the comment top bar. - * @private - */ -Blockly.ScratchBubble.MINIMIZE_ICON_SIZE = 32; - -/** - * The size of the delete icon in the comment top bar. - * @private - */ -Blockly.ScratchBubble.DELETE_ICON_SIZE = 32; - -/** - * The inset for the top bar icons. - * @private - */ -Blockly.ScratchBubble.TOP_BAR_ICON_INSET = 0; - - -/** - * The inset for the top bar icons. - * @private - */ -Blockly.ScratchBubble.RESIZE_SIZE = 16; - -/** - * The bottom corner padding of the resize handle touch target. - * Extends slightly outside the comment box. - * @private - */ -Blockly.ScratchBubble.RESIZE_CORNER_PAD = 4; - -/** - * The top/side padding around resize handle touch target. - * Extends about one extra "diagonal" above resize handle. - * @private - */ -Blockly.ScratchBubble.RESIZE_OUTER_PAD = 8; - -/** - * Create the bubble's DOM. - * @param {!Element} content SVG content for the bubble. - * @param {boolean} hasResize Add diagonal resize gripper if true. - * @param {boolean} minimized Whether the bubble is minimized - * @return {!Element} The bubble's SVG group. - * @private - */ -Blockly.ScratchBubble.prototype.createDom_ = function(content, hasResize, minimized) { - this.bubbleGroup_ = Blockly.utils.createSvgElement('g', {}, null); - this.bubbleArrow_ = Blockly.utils.createSvgElement('line', - {'stroke-linecap': 'round'}, - this.bubbleGroup_); - this.bubbleBack_ = Blockly.utils.createSvgElement('rect', - { - 'class': 'blocklyDraggable scratchCommentRect', - 'x': 0, - 'y': 0, - 'rx': 4 * Blockly.ScratchBubble.BORDER_WIDTH, - 'ry': 4 * Blockly.ScratchBubble.BORDER_WIDTH - }, - this.bubbleGroup_); - - this.labelText_ = content.labelText; - this.createCommentTopBar_(); - - // Comment Text Editor - this.commentEditor_ = content.commentEditor; - this.bubbleGroup_.appendChild(this.commentEditor_); - - // Comment Resize Handle - if (hasResize) { - this.createResizeHandle_(); - } else { - this.resizeGroup_ = null; - } - - // Show / hide relevant things based on minimized state - if (minimized) { - this.minimizeArrow_.setAttributeNS('http://www.w3.org/1999/xlink', - 'xlink:href', Blockly.mainWorkspace.options.pathToMedia + 'comment-arrow-up.svg'); - this.commentEditor_.setAttribute('display', 'none'); - this.resizeGroup_.setAttribute('display', 'none'); - } else { - this.minimizeArrow_.setAttributeNS('http://www.w3.org/1999/xlink', - 'xlink:href', Blockly.mainWorkspace.options.pathToMedia + 'comment-arrow-down.svg'); - this.topBarLabel_.setAttribute('display', 'none'); - } - - return this.bubbleGroup_; -}; - -/** - * Create the comment top bar and its contents. - * @private - */ -Blockly.ScratchBubble.prototype.createCommentTopBar_ = function() { - this.commentTopBar_ = Blockly.utils.createSvgElement('rect', - { - 'class': 'blocklyDraggable scratchCommentTopBar', - 'rx': Blockly.ScratchBubble.BORDER_WIDTH, - 'ry': Blockly.ScratchBubble.BORDER_WIDTH, - 'height': Blockly.ScratchBubble.TOP_BAR_HEIGHT - }, this.bubbleGroup_); - - this.createTopBarIcons_(); - this.createTopBarLabel_(); -}; - -/** - * Create the minimize toggle and delete icons that in the comment top bar. - * @private - */ -Blockly.ScratchBubble.prototype.createTopBarIcons_ = function() { - var topBarMiddleY = (Blockly.ScratchBubble.TOP_BAR_HEIGHT / 2) + - Blockly.ScratchBubble.BORDER_WIDTH; - - // Minimize Toggle Icon in Comment Top Bar - var xInset = Blockly.ScratchBubble.TOP_BAR_ICON_INSET; - this.minimizeArrow_ = Blockly.utils.createSvgElement('image', - { - 'x': xInset, - 'y': topBarMiddleY - Blockly.ScratchBubble.MINIMIZE_ICON_SIZE / 2, - 'width': Blockly.ScratchBubble.MINIMIZE_ICON_SIZE, - 'height': Blockly.ScratchBubble.MINIMIZE_ICON_SIZE - }, this.bubbleGroup_); - - // Delete Icon in Comment Top Bar - this.deleteIcon_ = Blockly.utils.createSvgElement('image', - { - 'x': xInset, - 'y': topBarMiddleY - Blockly.ScratchBubble.DELETE_ICON_SIZE / 2, - 'width': Blockly.ScratchBubble.DELETE_ICON_SIZE, - 'height': Blockly.ScratchBubble.DELETE_ICON_SIZE - }, this.bubbleGroup_); - this.deleteIcon_.setAttributeNS('http://www.w3.org/1999/xlink', - 'xlink:href', Blockly.mainWorkspace.options.pathToMedia + 'delete-x.svg'); -}; - -/** - * Create the comment top bar label. This is the truncated comment text - * that shows when comment is minimized. - * @private - */ -Blockly.ScratchBubble.prototype.createTopBarLabel_ = function() { - this.topBarLabel_ = Blockly.utils.createSvgElement('text', - { - 'class': 'scratchCommentText', - 'x': this.width_ / 2, - 'y': (Blockly.ScratchBubble.TOP_BAR_HEIGHT / 2) + Blockly.ScratchBubble.BORDER_WIDTH, - 'text-anchor': 'middle', - 'dominant-baseline': 'middle' - }, this.bubbleGroup_); - - var labelTextNode = document.createTextNode(this.labelText_); - this.topBarLabel_.appendChild(labelTextNode); -}; - -/** - * Create the comment resize handle. - * @private - */ -Blockly.ScratchBubble.prototype.createResizeHandle_ = function() { - this.resizeGroup_ = Blockly.utils.createSvgElement('g', - {'class': this.workspace_.RTL ? - 'scratchCommentResizeSW' : 'scratchCommentResizeSE'}, - this.bubbleGroup_); - var resizeSize = Blockly.ScratchBubble.RESIZE_SIZE; - var outerPad = Blockly.ScratchBubble.RESIZE_OUTER_PAD; - var cornerPad = Blockly.ScratchBubble.RESIZE_CORNER_PAD; - // Build an (invisible) triangle that will catch resizes. It is padded on the - // top/left by outerPad, and padded down/right by cornerPad. - Blockly.utils.createSvgElement('polygon', - { - 'points': [ - -outerPad, resizeSize + cornerPad, - resizeSize + cornerPad, resizeSize + cornerPad, - resizeSize + cornerPad, -outerPad - ].join(' ') - }, - this.resizeGroup_); - Blockly.utils.createSvgElement('line', - { - 'class': 'blocklyResizeLine', - 'x1': resizeSize / 3, 'y1': resizeSize - 1, - 'x2': resizeSize - 1, 'y2': resizeSize / 3 - }, this.resizeGroup_); - Blockly.utils.createSvgElement('line', - { - 'class': 'blocklyResizeLine', - 'x1': resizeSize * 2 / 3, - 'y1': resizeSize - 1, - 'x2': resizeSize - 1, - 'y2': resizeSize * 2 / 3 - }, this.resizeGroup_); -}; - -/** - * Show the context menu for this bubble. - * @param {!Event} e Mouse event. - * @private - */ -Blockly.ScratchBubble.prototype.showContextMenu_ = function(e) { - if (this.workspace_.options.readOnly) { - return; - } - - if (this.contextMenuCallback_) { - this.contextMenuCallback_(e); - } -}; - -/** - * Handle a mouse-down on bubble's minimize icon. - * @param {!Event} e Mouse up event. - * @private - */ -Blockly.ScratchBubble.prototype.minimizeArrowMouseDown_ = function(e) { - // Set a property indicating that this comment's minimize arrow got a mouse - // down event. This property will get reset if the mouse leaves the icon or - // when a mouse up occurs on this icon after this mouse down. - this.shouldToggleMinimize_ = true; - e.stopPropagation(); -}; - -/** - * Handle a mouse-out on bubble's minimize icon. - * @param {!Event} _e Mouse up event. - * @private - */ -Blockly.ScratchBubble.prototype.minimizeArrowMouseOut_ = function(_e) { - // If the mouse has left the minimize arrow icon, the - // shouldToggleMinimize property should get reset to false. - this.shouldToggleMinimize_ = false; -}; - -/** - * Handle a mouse-up on bubble's minimize icon. - * @param {!Event} e Mouse up event. - * @private - */ -Blockly.ScratchBubble.prototype.minimizeArrowMouseUp_ = function(e) { - // First check if this icon had a mouse down event - // on it and that the mouse never left the icon - if (this.shouldToggleMinimize_) { - this.shouldToggleMinimize_ = false; - - if (this.minimizeToggleCallback_) { - this.minimizeToggleCallback_.call(this); - } - } - e.stopPropagation(); -}; - -/** - * Handle a mouse-down on bubble's delete icon. - * @param {!Event} e Mouse up event. - * @private - */ -Blockly.ScratchBubble.prototype.deleteMouseDown_ = function(e) { - this.shouldDelete_ = true; - e.stopPropagation(); -}; - -/** - * Handle a mouse-out on bubble's delete icon. - * @param {!Event} _e Mouse out event. - * @private - */ -Blockly.ScratchBubble.prototype.deleteMouseOut_ = function(_e) { - // If the mouse has left the delete icon, the shouldDelete_ property - // should get reset to false. - this.shouldDelete_ = false; -}; - -/** - * Handle a mouse-up on bubble's delete icon. - * @param {!Event} e Mouse up event. - * @private - */ -Blockly.ScratchBubble.prototype.deleteMouseUp_ = function(e) { - // First check that this is actually the same icon that had a mouse down event - // on it and that the mouse never left the icon - if (this.shouldDelete_) { - this.shouldDelete_ = false; - - if (this.deleteCallback_) { - this.deleteCallback_.call(this); - } - } - e.stopPropagation(); -}; - -/** - * Handle a mouse-down on bubble's resize corner. - * @param {!Event} e Mouse down event. - * @private - */ -Blockly.ScratchBubble.prototype.resizeMouseDown_ = function(e) { - this.resizeStartSize_ = {width: this.width_, height: this.height_}; - this.workspace_.setResizesEnabled(false); - Blockly.ScratchBubble.superClass_.resizeMouseDown_.call(this, e); -}; - -/** - * Handle a mouse-up on bubble's resize corner. - * @param {!Event} _e Mouse up event. - * @private - */ -Blockly.ScratchBubble.prototype.resizeMouseUp_ = function(_e) { - var oldHW = this.resizeStartSize_; - this.resizeStartSize_ = null; - if (this.width_ == oldHW.width && this.height_ == oldHW.height) { - return; - } - // Fire a change event for the new width/height after - // resize mouse up - Blockly.Events.fire(new Blockly.Events.CommentChange( - this.comment, {width: oldHW.width , height: oldHW.height}, - {width: this.width_, height: this.height_})); - - this.workspace_.setResizesEnabled(true); -}; - -/** - * Set the minimized state of the bubble. - * @param {boolean} minimize Whether the bubble should be minimized - * @param {?string} labelText Optional label text for the comment top bar - * when it is minimized. - * @package - */ -Blockly.ScratchBubble.prototype.setMinimized = function(minimize, labelText) { - if (minimize == this.isMinimized_) { - return; - } - if (minimize) { - this.isMinimized_ = true; - // Change minimize icon - this.minimizeArrow_.setAttributeNS('http://www.w3.org/1999/xlink', - 'xlink:href', Blockly.mainWorkspace.options.pathToMedia + 'comment-arrow-up.svg'); - // Hide text area - this.commentEditor_.setAttribute('display', 'none'); - // Hide resize handle if it exists - if (this.resizeGroup_) { - this.resizeGroup_.setAttribute('display', 'none'); - } - if (labelText && this.labelText_ != labelText) { - // Update label and display - this.topBarLabel_.textContent = labelText; - } - Blockly.utils.removeAttribute(this.topBarLabel_, 'display'); - } else { - this.isMinimized_ = false; - // Change minimize icon - this.minimizeArrow_.setAttributeNS('http://www.w3.org/1999/xlink', - 'xlink:href', Blockly.mainWorkspace.options.pathToMedia + 'comment-arrow-down.svg'); - // Hide label - this.topBarLabel_.setAttribute('display', 'none'); - // Show text area - Blockly.utils.removeAttribute(this.commentEditor_, 'display'); - // Display resize handle if it exists - if (this.resizeGroup_) { - Blockly.utils.removeAttribute(this.resizeGroup_, 'display'); - } - } -}; - -/** - * Register a function as a callback event for when the bubble is minimized. - * @param {!Function} callback The function to call on resize. - * @package - */ -Blockly.ScratchBubble.prototype.registerMinimizeToggleEvent = function(callback) { - this.minimizeToggleCallback_ = callback; -}; - -/** - * Register a function as a callback event for when the bubble is resized. - * @param {!Function} callback The function to call on resize. - * @package - */ -Blockly.ScratchBubble.prototype.registerDeleteEvent = function(callback) { - this.deleteCallback_ = callback; -}; - -/** - * Register a function as a callback to show the context menu for this comment. - * @param {!Function} callback The function to call on resize. - * @package - */ -Blockly.ScratchBubble.prototype.registerContextMenuCallback = function(callback) { - this.contextMenuCallback_ = callback; -}; - -/** - * Notification that the anchor has moved. - * Update the arrow and bubble accordingly. - * @param {!goog.math.Coordinate} xy Absolute location. - * @package - */ -Blockly.ScratchBubble.prototype.setAnchorLocation = function(xy) { - this.anchorXY_ = xy; - if (this.rendered_) { - this.positionBubble_(); - } -}; - -/** - * Move the bubble group to the specified location in workspace coordinates. - * @param {number} x The x position to move to. - * @param {number} y The y position to move to. - * @package - */ -Blockly.ScratchBubble.prototype.moveTo = function(x, y) { - Blockly.ScratchBubble.superClass_.moveTo.call(this, x, y); - this.updatePosition_(x, y); -}; - -/** - * Size this bubble. - * @param {number} width Width of the bubble. - * @param {number} height Height of the bubble. - * @package - */ -Blockly.ScratchBubble.prototype.setBubbleSize = function(width, height) { - var doubleBorderWidth = 2 * Blockly.ScratchBubble.BORDER_WIDTH; - // Minimum size of a bubble. - width = Math.max(width, doubleBorderWidth + 50); - height = Math.max(height, Blockly.ScratchBubble.TOP_BAR_HEIGHT); - this.width_ = width; - this.height_ = height; - this.bubbleBack_.setAttribute('width', width); - this.bubbleBack_.setAttribute('height', height); - this.commentTopBar_.setAttribute('width', width); - this.commentTopBar_.setAttribute('height', Blockly.ScratchBubble.TOP_BAR_HEIGHT); - if (this.workspace_.RTL) { - this.minimizeArrow_.setAttribute('x', width - - (Blockly.ScratchBubble.MINIMIZE_ICON_SIZE) - - Blockly.ScratchBubble.TOP_BAR_ICON_INSET); - } else { - this.deleteIcon_.setAttribute('x', width - - Blockly.ScratchBubble.DELETE_ICON_SIZE - - Blockly.ScratchBubble.TOP_BAR_ICON_INSET); - } - if (this.resizeGroup_) { - var resizeSize = Blockly.ScratchBubble.RESIZE_SIZE; - if (this.workspace_.RTL) { - // Mirror the resize group. - this.resizeGroup_.setAttribute('transform', 'translate(' + - (resizeSize + doubleBorderWidth) + ',' + - (this.height_ - doubleBorderWidth - resizeSize) + ') scale(-1, 1)'); - } else { - this.resizeGroup_.setAttribute('transform', 'translate(' + - (this.width_ - doubleBorderWidth - resizeSize) + ',' + - (this.height_ - doubleBorderWidth - resizeSize) + ')'); - } - } - if (this.isMinimized_) { - this.topBarLabel_.setAttribute('x', this.width_ / 2); - this.topBarLabel_.setAttribute('y', this.height_ / 2); - } - if (this.rendered_) { - this.positionBubble_(); - this.renderArrow_(); - } - // Allow the contents to resize. - if (this.resizeCallback_) { - this.resizeCallback_(); - } -}; - -/** - * Draw the line between the bubble and the origin. - * @private - */ -Blockly.ScratchBubble.prototype.renderArrow_ = function() { - // Find the relative coordinates of the top bar center of the bubble. - var relBubbleX = this.width_ / 2; - var relBubbleY = Blockly.ScratchBubble.TOP_BAR_HEIGHT / 2; - // Find the relative coordinates of the center of the anchor. - var relAnchorX = -this.relativeLeft_; - var relAnchorY = -this.relativeTop_; - if (relBubbleX != relAnchorX || relBubbleY != relAnchorY) { - // Compute the angle of the arrow's line. - var rise = relAnchorY - relBubbleY; - var run = relAnchorX - relBubbleX; - if (this.workspace_.RTL) { - run *= -1; - run -= this.width_; - } - - var baseX1 = relBubbleX; - var baseY1 = relBubbleY; - - this.bubbleArrow_.setAttribute('x1', baseX1); - this.bubbleArrow_.setAttribute('y1', baseY1); - this.bubbleArrow_.setAttribute('x2', baseX1 + run); - this.bubbleArrow_.setAttribute('y2', baseY1 + rise); - this.bubbleArrow_.setAttribute('stroke-width', Blockly.ScratchBubble.LINE_THICKNESS); - } -}; - -/** - * Change the colour of a bubble. - * @param {string} hexColour Hex code of colour. - * @package - */ -Blockly.ScratchBubble.prototype.setColour = function(hexColour) { - this.bubbleBack_.setAttribute('stroke', hexColour); - this.bubbleArrow_.setAttribute('stroke', hexColour); -}; - -/** - * Move this bubble during a drag, taking into account whether or not there is - * a drag surface. - * @param {?Blockly.BlockDragSurfaceSvg} dragSurface The surface that carries - * rendered items during a drag, or null if no drag surface is in use. - * @param {!goog.math.Coordinate} newLoc The location to translate to, in - * workspace coordinates. - * @package - */ -Blockly.ScratchBubble.prototype.moveDuringDrag = function(dragSurface, newLoc) { - if (dragSurface) { - dragSurface.translateSurface(newLoc.x, newLoc.y); - this.updatePosition_(newLoc.x, newLoc.y); - } else { - this.moveTo(newLoc.x, newLoc.y); - } -}; - -/** - * Update the relative left and top of the bubble after a move. - * @param {number} x The x position of the bubble - * @param {number} y The y position of the bubble - * @private - */ -Blockly.ScratchBubble.prototype.updatePosition_ = function(x, y) { - // Relative left is the distance *and* direction to get from the comment - // anchor position on the block to the starting edge of the comment (e.g. - // the left edge of the comment in LTR and the right edge of the comment in RTL) - if (this.workspace_.RTL) { - // we want relativeLeft_ to actually be the distance from the anchor point to the *right* edge of the comment in RTL - this.relativeLeft_ = this.anchorXY_.x - x; - } else { - this.relativeLeft_ = x - this.anchorXY_.x; - } - this.relativeTop_ = y - this.anchorXY_.y; - this.renderArrow_(); -}; - -/** - * Dispose of this bubble. - * @package - */ -Blockly.ScratchBubble.prototype.dispose = function() { - Blockly.ScratchBubble.superClass_.dispose.call(this); - this.topBarLabel_ = null; - this.commentTopBar_ = null; - this.minimizeArrow_ = null; - this.deleteIcon_ = null; -}; diff --git a/core/scratch_events.js b/core/scratch_events.js deleted file mode 100644 index 56f340bdc9..0000000000 --- a/core/scratch_events.js +++ /dev/null @@ -1,131 +0,0 @@ -/** - * @license - * Visual Blocks Editor - * - * Copyright 2018 Google Inc. - * https://developers.google.com/blockly/ - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @fileoverview Events fired as a result of UI actions in a Scratch-Blocks - * editor that are not fired in Blockly. - * @author fenichel@google.com (Rachel Fenichel) - */ -'use strict'; - -goog.provide('Blockly.Events.DragBlockOutside'); -goog.provide('Blockly.Events.EndBlockDrag'); - -goog.require('Blockly.Events'); -goog.require('Blockly.Events.BlockBase'); - -goog.require('goog.array'); -goog.require('goog.math.Coordinate'); - -/** - * Class for a block drag event. Fired when block dragged into or out of - * the blocks UI. - * @param {Blockly.Block} block The moved block. Null for a blank event. - * @extends {Blockly.Events.BlockBase} - * @constructor - */ -Blockly.Events.DragBlockOutside = function(block) { - if (!block) { - return; // Blank event to be populated by fromJson. - } - Blockly.Events.DragBlockOutside.superClass_.constructor.call(this, block); - this.recordUndo = false; -}; -goog.inherits(Blockly.Events.DragBlockOutside, Blockly.Events.BlockBase); - -/** - * Type of this event. - * @type {string} - */ -Blockly.Events.DragBlockOutside.prototype.type = Blockly.Events.DRAG_OUTSIDE; - -/** - * Encode the event as JSON. - * @return {!Object} JSON representation. - */ -Blockly.Events.DragBlockOutside.prototype.toJson = function() { - var json = Blockly.Events.DragBlockOutside.superClass_.toJson.call(this); - if (this.isOutside) { - json['isOutside'] = this.isOutside; - } - return json; -}; - -/** - * Decode the JSON event. - * @param {!Object} json JSON representation. - */ -Blockly.Events.DragBlockOutside.prototype.fromJson = function(json) { - Blockly.Events.DragBlockOutside.superClass_.fromJson.call(this, json); - this.isOutside = json['isOutside']; -}; - -/** - * Class for a block end drag event. - * @param {Blockly.Block} block The moved block. Null for a blank event. - * @param {boolean} isOutside True if the moved block is outside of the - * blocks workspace. - * @extends {Blockly.Events.BlockBase} - * @constructor - */ -Blockly.Events.EndBlockDrag = function(block, isOutside) { - if (!block) { - return; // Blank event to be populated by fromJson. - } - Blockly.Events.EndBlockDrag.superClass_.constructor.call(this, block); - this.isOutside = isOutside; - // If drag ends outside the blocks workspace, send the block XML - if (isOutside) { - this.xml = Blockly.Xml.blockToDom(block, true /* opt_noId */); - } - this.recordUndo = false; -}; -goog.inherits(Blockly.Events.EndBlockDrag, Blockly.Events.BlockBase); - -/** - * Type of this event. - * @type {string} - */ -Blockly.Events.EndBlockDrag.prototype.type = Blockly.Events.END_DRAG; - -/** - * Encode the event as JSON. - * @return {!Object} JSON representation. - */ -Blockly.Events.EndBlockDrag.prototype.toJson = function() { - var json = Blockly.Events.EndBlockDrag.superClass_.toJson.call(this); - if (this.isOutside) { - json['isOutside'] = this.isOutside; - } - if (this.xml) { - json['xml'] = this.xml; - } - return json; -}; - -/** - * Decode the JSON event. - * @param {!Object} json JSON representation. - */ -Blockly.Events.EndBlockDrag.prototype.fromJson = function(json) { - Blockly.Events.EndBlockDrag.superClass_.fromJson.call(this, json); - this.isOutside = json['isOutside']; - this.xml = json['xml']; -}; diff --git a/core/scratch_msgs.js b/core/scratch_msgs.js deleted file mode 100644 index f59588f841..0000000000 --- a/core/scratch_msgs.js +++ /dev/null @@ -1,85 +0,0 @@ -/** - * @license - * Visual Blocks Editor - * - * Copyright 2018 Google Inc. - * https://developers.google.com/blockly/ - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @fileoverview Scratch Messages singleton, with function to override Blockly.Msg values. - * @author chrisg@media.mit.edu (Chris Garrity) - */ -'use strict'; - -/** - * Name space for the ScratchMsgs singleton. - * Msg gets populated in the message files. - */ -goog.provide('Blockly.ScratchMsgs'); - -goog.require('Blockly.Msg'); - - -/** - * The object containing messages for all locales - loaded from msg/scratch_msgs. - * @type {Object} - */ -Blockly.ScratchMsgs.locales = {}; - -/** - * The current locale. - * @type {String} - * @private - */ -Blockly.ScratchMsgs.currentLocale_ = 'en'; - -/** - * Change the Blockly.Msg strings to a new Locale - * Does not exist in Blockly, but needed in scratch-blocks - * @param {string} locale E.g., 'de', or 'zh-tw' - * @package - */ -Blockly.ScratchMsgs.setLocale = function(locale) { - if (Object.keys(Blockly.ScratchMsgs.locales).includes(locale)) { - Blockly.ScratchMsgs.currentLocale_ = locale; - Blockly.Msg = Object.assign({}, Blockly.Msg, Blockly.ScratchMsgs.locales[locale]); - } else { - // keep current locale - console.warn('Ignoring unrecognized locale: ' + locale); - } -}; - -/** - * Gets a localized message, for use in the Scratch VM with json init. - * Does not interpolate placeholders. Provided to allow default values in - * dynamic menus, for example, 'next backdrop', or 'random position' - * @param {string} msgId id for the message, key in Msg table. - * @param {string} defaultMsg string to use if the id isn't found. - * @param {string} useLocale optional locale to use in place of currentLocale_. - * @return {string} message with placeholders filled. - * @package - */ -Blockly.ScratchMsgs.translate = function(msgId, defaultMsg, useLocale) { - var locale = useLocale || Blockly.ScratchMsgs.currentLocale_; - - if (Object.keys(Blockly.ScratchMsgs.locales).includes(locale)) { - var messages = Blockly.ScratchMsgs.locales[locale]; - if (Object.keys(messages).includes(msgId)) { - return messages[msgId]; - } - } - return defaultMsg; -}; diff --git a/core/scrollbar.js b/core/scrollbar.js deleted file mode 100644 index c5431291a2..0000000000 --- a/core/scrollbar.js +++ /dev/null @@ -1,875 +0,0 @@ -/** - * @license - * Visual Blocks Editor - * - * Copyright 2011 Google Inc. - * https://developers.google.com/blockly/ - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @fileoverview Library for creating scrollbars. - * @author fraser@google.com (Neil Fraser) - */ -'use strict'; - -goog.provide('Blockly.Scrollbar'); -goog.provide('Blockly.ScrollbarPair'); - -goog.require('goog.dom'); -goog.require('goog.events'); - - -/** - * A note on units: most of the numbers that are in CSS pixels are scaled if the - * scrollbar is in a mutator. - */ - -/** - * Class for a pair of scrollbars. Horizontal and vertical. - * @param {!Blockly.Workspace} workspace Workspace to bind the scrollbars to. - * @constructor - */ -Blockly.ScrollbarPair = function(workspace) { - this.workspace_ = workspace; - this.hScroll = new Blockly.Scrollbar( - workspace, true, true, 'blocklyMainWorkspaceScrollbar'); - this.vScroll = new Blockly.Scrollbar( - workspace, false, true, 'blocklyMainWorkspaceScrollbar'); - this.corner_ = Blockly.utils.createSvgElement( - 'rect', - { - 'height': Blockly.Scrollbar.scrollbarThickness, - 'width': Blockly.Scrollbar.scrollbarThickness, - 'class': 'blocklyScrollbarBackground' - }, - null); - Blockly.utils.insertAfter(this.corner_, workspace.getBubbleCanvas()); -}; - -/** - * Previously recorded metrics from the workspace. - * @type {Object} - * @private - */ -Blockly.ScrollbarPair.prototype.oldHostMetrics_ = null; - -/** - * Dispose of this pair of scrollbars. - * Unlink from all DOM elements to prevent memory leaks. - */ -Blockly.ScrollbarPair.prototype.dispose = function() { - goog.dom.removeNode(this.corner_); - this.corner_ = null; - this.workspace_ = null; - this.oldHostMetrics_ = null; - this.hScroll.dispose(); - this.hScroll = null; - this.vScroll.dispose(); - this.vScroll = null; -}; - -/** - * Recalculate both of the scrollbars' locations and lengths. - * Also reposition the corner rectangle. - */ -Blockly.ScrollbarPair.prototype.resize = function() { - // Look up the host metrics once, and use for both scrollbars. - var hostMetrics = this.workspace_.getMetrics(); - if (!hostMetrics) { - // Host element is likely not visible. - return; - } - - // Only change the scrollbars if there has been a change in metrics. - var resizeH = false; - var resizeV = false; - if (!this.oldHostMetrics_ || - this.oldHostMetrics_.viewWidth != hostMetrics.viewWidth || - this.oldHostMetrics_.viewHeight != hostMetrics.viewHeight || - this.oldHostMetrics_.absoluteTop != hostMetrics.absoluteTop || - this.oldHostMetrics_.absoluteLeft != hostMetrics.absoluteLeft) { - // The window has been resized or repositioned. - resizeH = true; - resizeV = true; - } else { - // Has the content been resized or moved? - if (!this.oldHostMetrics_ || - this.oldHostMetrics_.contentWidth != hostMetrics.contentWidth || - this.oldHostMetrics_.viewLeft != hostMetrics.viewLeft || - this.oldHostMetrics_.contentLeft != hostMetrics.contentLeft) { - resizeH = true; - } - if (!this.oldHostMetrics_ || - this.oldHostMetrics_.contentHeight != hostMetrics.contentHeight || - this.oldHostMetrics_.viewTop != hostMetrics.viewTop || - this.oldHostMetrics_.contentTop != hostMetrics.contentTop) { - resizeV = true; - } - } - if (resizeH) { - this.hScroll.resize(hostMetrics); - } - if (resizeV) { - this.vScroll.resize(hostMetrics); - } - - // Reposition the corner square. - if (!this.oldHostMetrics_ || - this.oldHostMetrics_.viewWidth != hostMetrics.viewWidth || - this.oldHostMetrics_.absoluteLeft != hostMetrics.absoluteLeft) { - this.corner_.setAttribute('x', this.vScroll.position_.x); - } - if (!this.oldHostMetrics_ || - this.oldHostMetrics_.viewHeight != hostMetrics.viewHeight || - this.oldHostMetrics_.absoluteTop != hostMetrics.absoluteTop) { - this.corner_.setAttribute('y', this.hScroll.position_.y); - } - - // Cache the current metrics to potentially short-cut the next resize event. - this.oldHostMetrics_ = hostMetrics; -}; - -/** - * Set the handles of both scrollbars to be at a certain position in CSS pixels - * relative to their parents. - * @param {number} x Horizontal scroll value. - * @param {number} y Vertical scroll value. - */ -Blockly.ScrollbarPair.prototype.set = function(x, y) { - // This function is equivalent to: - // this.hScroll.set(x); - // this.vScroll.set(y); - // However, that calls setMetrics twice which causes a chain of - // getAttribute->setAttribute->getAttribute resulting in an extra layout pass. - // Combining them speeds up rendering. - var xyRatio = {}; - - var hHandlePosition = x * this.hScroll.ratio_; - var vHandlePosition = y * this.vScroll.ratio_; - - var hBarLength = this.hScroll.scrollViewSize_; - var vBarLength = this.vScroll.scrollViewSize_; - - xyRatio.x = this.getRatio_(hHandlePosition, hBarLength); - xyRatio.y = this.getRatio_(vHandlePosition, vBarLength); - this.workspace_.setMetrics(xyRatio); - - this.hScroll.setHandlePosition(hHandlePosition); - this.vScroll.setHandlePosition(vHandlePosition); -}; - -/** - * Helper to calculate the ratio of handle position to scrollbar view size. - * @param {number} handlePosition The value of the handle. - * @param {number} viewSize The total size of the scrollbar's view. - * @return {number} Ratio. - * @private - */ -Blockly.ScrollbarPair.prototype.getRatio_ = function(handlePosition, viewSize) { - var ratio = handlePosition / viewSize; - if (isNaN(ratio)) { - return 0; - } - return ratio; -}; - -// -------------------------------------------------------------------- - -/** - * Class for a pure SVG scrollbar. - * This technique offers a scrollbar that is guaranteed to work, but may not - * look or behave like the system's scrollbars. - * @param {!Blockly.Workspace} workspace Workspace to bind the scrollbar to. - * @param {boolean} horizontal True if horizontal, false if vertical. - * @param {boolean=} opt_pair True if scrollbar is part of a horiz/vert pair. - * @param {string=} opt_class A class to be applied to this scrollbar. - * @constructor - */ -Blockly.Scrollbar = function(workspace, horizontal, opt_pair, opt_class) { - this.workspace_ = workspace; - this.pair_ = opt_pair || false; - this.horizontal_ = horizontal; - this.oldHostMetrics_ = null; - - this.createDom_(opt_class); - - /** - * The upper left corner of the scrollbar's SVG group in CSS pixels relative - * to the scrollbar's origin. This is usually relative to the injection div - * origin. - * @type {goog.math.Coordinate} - * @private - */ - this.position_ = new goog.math.Coordinate(0, 0); - - // Store the thickness in a temp variable for readability. - var scrollbarThickness = Blockly.Scrollbar.scrollbarThickness; - if (horizontal) { - this.svgBackground_.setAttribute('height', scrollbarThickness); - this.outerSvg_.setAttribute('height', scrollbarThickness); - this.svgHandle_.setAttribute('height', scrollbarThickness - 5); - this.svgHandle_.setAttribute('y', 2.5); - - this.lengthAttribute_ = 'width'; - this.positionAttribute_ = 'x'; - } else { - this.svgBackground_.setAttribute('width', scrollbarThickness); - this.outerSvg_.setAttribute('width', scrollbarThickness); - this.svgHandle_.setAttribute('width', scrollbarThickness - 5); - this.svgHandle_.setAttribute('x', 2.5); - - this.lengthAttribute_ = 'height'; - this.positionAttribute_ = 'y'; - } - var scrollbar = this; - this.onMouseDownBarWrapper_ = Blockly.bindEventWithChecks_( - this.svgBackground_, 'mousedown', scrollbar, scrollbar.onMouseDownBar_); - this.onMouseDownHandleWrapper_ = Blockly.bindEventWithChecks_(this.svgHandle_, - 'mousedown', scrollbar, scrollbar.onMouseDownHandle_); -}; - -/** - * The location of the origin of the workspace that the scrollbar is in, - * measured in CSS pixels relative to the injection div origin. This is usually - * (0, 0). When the scrollbar is in a flyout it may have a different origin. - * @type {goog.math.Coordinate} - * @private - */ -Blockly.Scrollbar.prototype.origin_ = new goog.math.Coordinate(0, 0); - -/** - * Whether or not the origin of the scrollbar has changed. Used - * to help decide whether or not the reflow/resize calls need to happen. - * @type {boolean} - * @private - */ -Blockly.Scrollbar.prototype.originHasChanged_ = true; - -/** - * The size of the area within which the scrollbar handle can move, in CSS - * pixels. - * @type {number} - * @private - */ -Blockly.Scrollbar.prototype.scrollViewSize_ = 0; - -/** - * The length of the scrollbar handle in CSS pixels. - * @type {number} - * @private - */ -Blockly.Scrollbar.prototype.handleLength_ = 0; - -/** - * The offset of the start of the handle from the scrollbar position, in CSS - * pixels. - * @type {number} - * @private - */ -Blockly.Scrollbar.prototype.handlePosition_ = 0; - -/** - * Whether the scrollbar handle is visible. - * @type {boolean} - * @private - */ -Blockly.Scrollbar.prototype.isVisible_ = true; - -/** - * Whether the workspace containing this scrollbar is visible. - * @type {boolean} - * @private - */ -Blockly.Scrollbar.prototype.containerVisible_ = true; - -/** - * Width of vertical scrollbar or height of horizontal scrollbar in CSS pixels. - * Scrollbars should be larger on touch devices. - */ -Blockly.Scrollbar.scrollbarThickness = 11; -if (goog.events.BrowserFeature.TOUCH_ENABLED) { - Blockly.Scrollbar.scrollbarThickness = 14; -} - -/** - * @param {!Object} first An object containing computed measurements of a - * workspace. - * @param {!Object} second Another object containing computed measurements of a - * workspace. - * @return {boolean} Whether the two sets of metrics are equivalent. - * @private - */ -Blockly.Scrollbar.metricsAreEquivalent_ = function(first, second) { - if (!(first && second)) { - return false; - } - - if (first.viewWidth != second.viewWidth || - first.viewHeight != second.viewHeight || - first.viewLeft != second.viewLeft || - first.viewTop != second.viewTop || - first.absoluteTop != second.absoluteTop || - first.absoluteLeft != second.absoluteLeft || - first.contentWidth != second.contentWidth || - first.contentHeight != second.contentHeight || - first.contentLeft != second.contentLeft || - first.contentTop != second.contentTop) { - return false; - } - - return true; -}; - -/** - * Dispose of this scrollbar. - * Unlink from all DOM elements to prevent memory leaks. - */ -Blockly.Scrollbar.prototype.dispose = function() { - this.cleanUp_(); - Blockly.unbindEvent_(this.onMouseDownBarWrapper_); - this.onMouseDownBarWrapper_ = null; - Blockly.unbindEvent_(this.onMouseDownHandleWrapper_); - this.onMouseDownHandleWrapper_ = null; - - goog.dom.removeNode(this.outerSvg_); - this.outerSvg_ = null; - this.svgGroup_ = null; - this.svgBackground_ = null; - this.svgHandle_ = null; - this.workspace_ = null; -}; - -/** - * Set the length of the scrollbar's handle and change the SVG attribute - * accordingly. - * @param {number} newLength The new scrollbar handle length in CSS pixels. - */ -Blockly.Scrollbar.prototype.setHandleLength_ = function(newLength) { - this.handleLength_ = newLength; - this.svgHandle_.setAttribute(this.lengthAttribute_, this.handleLength_); -}; - -/** - * Set the offset of the scrollbar's handle from the scrollbar's position, and - * change the SVG attribute accordingly. - * @param {number} newPosition The new scrollbar handle offset in CSS pixels. - */ -Blockly.Scrollbar.prototype.setHandlePosition = function(newPosition) { - this.handlePosition_ = newPosition; - this.svgHandle_.setAttribute(this.positionAttribute_, this.handlePosition_); -}; - -/** - * Set the size of the scrollbar's background and change the SVG attribute - * accordingly. - * @param {number} newSize The new scrollbar background length in CSS pixels. - * @private - */ -Blockly.Scrollbar.prototype.setScrollViewSize_ = function(newSize) { - this.scrollViewSize_ = newSize; - this.outerSvg_.setAttribute(this.lengthAttribute_, this.scrollViewSize_); - this.svgBackground_.setAttribute(this.lengthAttribute_, this.scrollViewSize_); -}; - -/** - * Set whether this scrollbar's container is visible. - * @param {boolean} visible Whether the container is visible. - */ -Blockly.ScrollbarPair.prototype.setContainerVisible = function(visible) { - this.hScroll.setContainerVisible(visible); - this.vScroll.setContainerVisible(visible); -}; - -/** - * Set the position of the scrollbar's SVG group in CSS pixels relative to the - * scrollbar's origin. This sets the scrollbar's location within the workspace. - * @param {number} x The new x coordinate. - * @param {number} y The new y coordinate. - * @private - */ -Blockly.Scrollbar.prototype.setPosition_ = function(x, y) { - this.position_.x = x; - this.position_.y = y; - - var tempX = this.position_.x + this.origin_.x; - var tempY = this.position_.y + this.origin_.y; - var transform = 'translate(' + tempX + 'px,' + tempY + 'px)'; - Blockly.utils.setCssTransform(this.outerSvg_, transform); -}; - -/** - * Recalculate the scrollbar's location and its length. - * @param {Object=} opt_metrics A data structure of from the describing all the - * required dimensions. If not provided, it will be fetched from the host - * object. - */ -Blockly.Scrollbar.prototype.resize = function(opt_metrics) { - // Determine the location, height and width of the host element. - var hostMetrics = opt_metrics; - if (!hostMetrics) { - hostMetrics = this.workspace_.getMetrics(); - if (!hostMetrics) { - // Host element is likely not visible. - return; - } - } - - // If the origin has changed (e.g. the toolbox is moving from start to end) - // we want to continue with the resize even if workspace metrics haven't. - if (this.originHasChanged_) { - this.originHasChanged_ = false; - } else if (Blockly.Scrollbar.metricsAreEquivalent_(hostMetrics, - this.oldHostMetrics_)) { - return; - } - this.oldHostMetrics_ = hostMetrics; - - /* hostMetrics is an object with the following properties. - * .viewHeight: Height of the visible rectangle, - * .viewWidth: Width of the visible rectangle, - * .contentHeight: Height of the contents, - * .contentWidth: Width of the content, - * .viewTop: Offset of top edge of visible rectangle from parent, - * .viewLeft: Offset of left edge of visible rectangle from parent, - * .contentTop: Offset of the top-most content from the y=0 coordinate, - * .contentLeft: Offset of the left-most content from the x=0 coordinate, - * .absoluteTop: Top-edge of view. - * .absoluteLeft: Left-edge of view. - */ - if (this.horizontal_) { - this.resizeHorizontal_(hostMetrics); - } else { - this.resizeVertical_(hostMetrics); - } - // Resizing may have caused some scrolling. - this.onScroll_(); -}; - -/** - * Recalculate a horizontal scrollbar's location and length. - * @param {!Object} hostMetrics A data structure describing all the - * required dimensions, possibly fetched from the host object. - * @private - */ -Blockly.Scrollbar.prototype.resizeHorizontal_ = function(hostMetrics) { - // TODO: Inspect metrics to determine if we can get away with just a content - // resize. - this.resizeViewHorizontal(hostMetrics); -}; - -/** - * Recalculate a horizontal scrollbar's location on the screen and path length. - * This should be called when the layout or size of the window has changed. - * @param {!Object} hostMetrics A data structure describing all the - * required dimensions, possibly fetched from the host object. - */ -Blockly.Scrollbar.prototype.resizeViewHorizontal = function(hostMetrics) { - var viewSize = hostMetrics.viewWidth - 1; - if (this.pair_) { - // Shorten the scrollbar to make room for the corner square. - viewSize -= Blockly.Scrollbar.scrollbarThickness; - } - this.setScrollViewSize_(Math.max(0, viewSize)); - - var xCoordinate = hostMetrics.absoluteLeft + 0.5; - if (this.pair_ && this.workspace_.RTL) { - xCoordinate += Blockly.Scrollbar.scrollbarThickness; - } - - // Horizontal toolbar should always be just above the bottom of the workspace. - var yCoordinate = hostMetrics.absoluteTop + hostMetrics.viewHeight - - Blockly.Scrollbar.scrollbarThickness - 0.5; - this.setPosition_(xCoordinate, yCoordinate); - - // If the view has been resized, a content resize will also be necessary. The - // reverse is not true. - this.resizeContentHorizontal(hostMetrics); -}; - -/** - * Recalculate a horizontal scrollbar's location within its path and length. - * This should be called when the contents of the workspace have changed. - * @param {!Object} hostMetrics A data structure describing all the - * required dimensions, possibly fetched from the host object. - */ -Blockly.Scrollbar.prototype.resizeContentHorizontal = function(hostMetrics) { - if (!this.pair_) { - // Only show the scrollbar if needed. - // Ideally this would also apply to scrollbar pairs, but that's a bigger - // headache (due to interactions with the corner square). - this.setVisible(this.scrollViewSize_ < hostMetrics.contentWidth); - } - - this.ratio_ = this.scrollViewSize_ / hostMetrics.contentWidth; - if (this.ratio_ == -Infinity || this.ratio_ == Infinity || - isNaN(this.ratio_)) { - this.ratio_ = 0; - } - - var handleLength = hostMetrics.viewWidth * this.ratio_; - this.setHandleLength_(Math.max(0, handleLength)); - - var handlePosition = (hostMetrics.viewLeft - hostMetrics.contentLeft) * - this.ratio_; - this.setHandlePosition(this.constrainHandle_(handlePosition)); -}; - -/** - * Recalculate a vertical scrollbar's location and length. - * @param {!Object} hostMetrics A data structure describing all the - * required dimensions, possibly fetched from the host object. - * @private - */ -Blockly.Scrollbar.prototype.resizeVertical_ = function(hostMetrics) { - // TODO: Inspect metrics to determine if we can get away with just a content - // resize. - this.resizeViewVertical(hostMetrics); -}; - -/** - * Recalculate a vertical scrollbar's location on the screen and path length. - * This should be called when the layout or size of the window has changed. - * @param {!Object} hostMetrics A data structure describing all the - * required dimensions, possibly fetched from the host object. - */ -Blockly.Scrollbar.prototype.resizeViewVertical = function(hostMetrics) { - var viewSize = hostMetrics.viewHeight - 1; - if (this.pair_) { - // Shorten the scrollbar to make room for the corner square. - viewSize -= Blockly.Scrollbar.scrollbarThickness; - } - this.setScrollViewSize_(Math.max(0, viewSize)); - - var xCoordinate = hostMetrics.absoluteLeft + 0.5; - if (!this.workspace_.RTL) { - xCoordinate += hostMetrics.viewWidth - - Blockly.Scrollbar.scrollbarThickness - 1; - } - var yCoordinate = hostMetrics.absoluteTop + 0.5; - this.setPosition_(xCoordinate, yCoordinate); - - // If the view has been resized, a content resize will also be necessary. The - // reverse is not true. - this.resizeContentVertical(hostMetrics); -}; - -/** - * Recalculate a vertical scrollbar's location within its path and length. - * This should be called when the contents of the workspace have changed. - * @param {!Object} hostMetrics A data structure describing all the - * required dimensions, possibly fetched from the host object. - */ -Blockly.Scrollbar.prototype.resizeContentVertical = function(hostMetrics) { - if (!this.pair_) { - // Only show the scrollbar if needed. - this.setVisible(this.scrollViewSize_ < hostMetrics.contentHeight); - } - - this.ratio_ = this.scrollViewSize_ / hostMetrics.contentHeight; - if (this.ratio_ == -Infinity || this.ratio_ == Infinity || - isNaN(this.ratio_)) { - this.ratio_ = 0; - } - - var handleLength = hostMetrics.viewHeight * this.ratio_; - this.setHandleLength_(Math.max(0, handleLength)); - - var handlePosition = (hostMetrics.viewTop - hostMetrics.contentTop) * - this.ratio_; - this.setHandlePosition(this.constrainHandle_(handlePosition)); -}; - -/** - * Create all the DOM elements required for a scrollbar. - * The resulting widget is not sized. - * @param {string=} opt_class A class to be applied to this scrollbar. - * @private - */ -Blockly.Scrollbar.prototype.createDom_ = function(opt_class) { - /* Create the following DOM: - - - - - - - */ - var className = 'blocklyScrollbar' + - (this.horizontal_ ? 'Horizontal' : 'Vertical'); - if (opt_class) { - className += ' ' + opt_class; - } - this.outerSvg_ = Blockly.utils.createSvgElement( - 'svg', {'class': className}, null); - this.svgGroup_ = Blockly.utils.createSvgElement('g', {}, this.outerSvg_); - this.svgBackground_ = Blockly.utils.createSvgElement( - 'rect', {'class': 'blocklyScrollbarBackground'}, this.svgGroup_); - var radius = Math.floor((Blockly.Scrollbar.scrollbarThickness - 5) / 2); - this.svgHandle_ = Blockly.utils.createSvgElement( - 'rect', - { - 'class': 'blocklyScrollbarHandle', - 'rx': radius, - 'ry': radius - }, - this.svgGroup_); - Blockly.utils.insertAfter(this.outerSvg_, this.workspace_.getParentSvg()); -}; - -/** - * Is the scrollbar visible. Non-paired scrollbars disappear when they aren't - * needed. - * @return {boolean} True if visible. - */ -Blockly.Scrollbar.prototype.isVisible = function() { - return this.isVisible_; -}; - -/** - * Set whether the scrollbar's container is visible and update - * display accordingly if visibility has changed. - * @param {boolean} visible Whether the container is visible - */ -Blockly.Scrollbar.prototype.setContainerVisible = function(visible) { - var visibilityChanged = (visible != this.containerVisible_); - - this.containerVisible_ = visible; - if (visibilityChanged) { - this.updateDisplay_(); - } -}; - -/** - * Set whether the scrollbar is visible. - * Only applies to non-paired scrollbars. - * @param {boolean} visible True if visible. - */ -Blockly.Scrollbar.prototype.setVisible = function(visible) { - var visibilityChanged = (visible != this.isVisible()); - - // Ideally this would also apply to scrollbar pairs, but that's a bigger - // headache (due to interactions with the corner square). - if (this.pair_) { - throw 'Unable to toggle visibility of paired scrollbars.'; - } - this.isVisible_ = visible; - if (visibilityChanged) { - this.updateDisplay_(); - } -}; - -/** - * Update visibility of scrollbar based on whether it thinks it should - * be visible and whether its containing workspace is visible. - * We cannot rely on the containing workspace being hidden to hide us - * because it is not necessarily our parent in the DOM. - */ -Blockly.Scrollbar.prototype.updateDisplay_ = function() { - var show = true; - // Check whether our parent/container is visible. - if (!this.containerVisible_) { - show = false; - } else { - show = this.isVisible(); - } - if (show) { - this.outerSvg_.setAttribute('display', 'block'); - } else { - this.outerSvg_.setAttribute('display', 'none'); - } -}; - -/** - * Scroll by one pageful. - * Called when scrollbar background is clicked. - * @param {!Event} e Mouse down event. - * @private - */ -Blockly.Scrollbar.prototype.onMouseDownBar_ = function(e) { - this.workspace_.markFocused(); - Blockly.Touch.clearTouchIdentifier(); // This is really a click. - this.cleanUp_(); - if (Blockly.utils.isRightButton(e)) { - // Right-click. - // Scrollbars have no context menu. - e.stopPropagation(); - return; - } - var mouseXY = Blockly.utils.mouseToSvg(e, this.workspace_.getParentSvg(), - this.workspace_.getInverseScreenCTM()); - var mouseLocation = this.horizontal_ ? mouseXY.x : mouseXY.y; - - var handleXY = Blockly.utils.getInjectionDivXY_(this.svgHandle_); - var handleStart = this.horizontal_ ? handleXY.x : handleXY.y; - var handlePosition = this.handlePosition_; - - var pageLength = this.handleLength_ * 0.95; - if (mouseLocation <= handleStart) { - // Decrease the scrollbar's value by a page. - handlePosition -= pageLength; - } else if (mouseLocation >= handleStart + this.handleLength_) { - // Increase the scrollbar's value by a page. - handlePosition += pageLength; - } - // When the scrollbars are clicked, hide the WidgetDiv/DropDownDiv without - // animation in anticipation of a workspace move. - Blockly.WidgetDiv.hide(true); - Blockly.DropDownDiv.hideWithoutAnimation(); - - this.setHandlePosition(this.constrainHandle_(handlePosition)); - this.onScroll_(); - e.stopPropagation(); - e.preventDefault(); -}; - -/** - * Start a dragging operation. - * Called when scrollbar handle is clicked. - * @param {!Event} e Mouse down event. - * @private - */ -Blockly.Scrollbar.prototype.onMouseDownHandle_ = function(e) { - this.workspace_.markFocused(); - this.cleanUp_(); - if (Blockly.utils.isRightButton(e)) { - // Right-click. - // Scrollbars have no context menu. - e.stopPropagation(); - return; - } - // Look up the current translation and record it. - this.startDragHandle = this.handlePosition_; - - // Tell the workspace to setup its drag surface since it is about to move. - // onMouseMoveHandle will call onScroll which actually tells the workspace - // to move. - this.workspace_.setupDragSurface(); - - // Record the current mouse position. - this.startDragMouse_ = this.horizontal_ ? e.clientX : e.clientY; - Blockly.Scrollbar.onMouseUpWrapper_ = Blockly.bindEventWithChecks_(document, - 'mouseup', this, this.onMouseUpHandle_); - Blockly.Scrollbar.onMouseMoveWrapper_ = Blockly.bindEventWithChecks_(document, - 'mousemove', this, this.onMouseMoveHandle_); - // When the scrollbars are clicked, hide the WidgetDiv/DropDownDiv without - // animation in anticipation of a workspace move. - Blockly.WidgetDiv.hide(true); - Blockly.DropDownDiv.hideWithoutAnimation(); - - e.stopPropagation(); - e.preventDefault(); -}; - -/** - * Drag the scrollbar's handle. - * @param {!Event} e Mouse up event. - * @private - */ -Blockly.Scrollbar.prototype.onMouseMoveHandle_ = function(e) { - var currentMouse = this.horizontal_ ? e.clientX : e.clientY; - var mouseDelta = currentMouse - this.startDragMouse_; - var handlePosition = this.startDragHandle + mouseDelta; - // Position the bar. - this.setHandlePosition(this.constrainHandle_(handlePosition)); - this.onScroll_(); -}; - -/** - * Release the scrollbar handle and reset state accordingly. - * @private - */ -Blockly.Scrollbar.prototype.onMouseUpHandle_ = function() { - // Tell the workspace to clean up now that the workspace is done moving. - this.workspace_.resetDragSurface(); - Blockly.Touch.clearTouchIdentifier(); - this.cleanUp_(); -}; - -/** - * Hide chaff and stop binding to mouseup and mousemove events. Call this to - * wrap up lose ends associated with the scrollbar. - * @private - */ -Blockly.Scrollbar.prototype.cleanUp_ = function() { - Blockly.hideChaff(true); - if (Blockly.Scrollbar.onMouseUpWrapper_) { - Blockly.unbindEvent_(Blockly.Scrollbar.onMouseUpWrapper_); - Blockly.Scrollbar.onMouseUpWrapper_ = null; - } - if (Blockly.Scrollbar.onMouseMoveWrapper_) { - Blockly.unbindEvent_(Blockly.Scrollbar.onMouseMoveWrapper_); - Blockly.Scrollbar.onMouseMoveWrapper_ = null; - } -}; - -/** - * Constrain the handle's position within the minimum (0) and maximum - * (length of scrollbar) values allowed for the scrollbar. - * @param {number} value Value that is potentially out of bounds, in CSS pixels. - * @return {number} Constrained value, in CSS pixels. - * @private - */ -Blockly.Scrollbar.prototype.constrainHandle_ = function(value) { - if (value <= 0 || isNaN(value) || this.scrollViewSize_ < this.handleLength_) { - value = 0; - } else { - value = Math.min(value, this.scrollViewSize_ - this.handleLength_); - } - return value; -}; - -/** - * Called when scrollbar is moved. - * @private - */ -Blockly.Scrollbar.prototype.onScroll_ = function() { - var ratio = this.handlePosition_ / this.scrollViewSize_; - if (isNaN(ratio)) { - ratio = 0; - } - var xyRatio = {}; - if (this.horizontal_) { - xyRatio.x = ratio; - } else { - xyRatio.y = ratio; - } - this.workspace_.setMetrics(xyRatio); -}; - -/** - * Set the scrollbar handle's position. - * @param {number} value The distance from the top/left end of the bar, in CSS - * pixels. It may be larger than the maximum allowable position of the - * scrollbar handle. - */ -Blockly.Scrollbar.prototype.set = function(value) { - this.setHandlePosition(this.constrainHandle_(value * this.ratio_)); - this.onScroll_(); -}; - -/** - * Record the origin of the workspace that the scrollbar is in, in pixels - * relative to the injection div origin. This is for times when the scrollbar is - * used in an object whose origin isn't the same as the main workspace - * (e.g. in a flyout.) - * @param {number} x The x coordinate of the scrollbar's origin, in CSS pixels. - * @param {number} y The y coordinate of the scrollbar's origin, in CSS pixels. - */ -Blockly.Scrollbar.prototype.setOrigin = function(x, y) { - if (x != this.origin_.x || y != this.origin_.y) { - this.origin_ = new goog.math.Coordinate(x, y); - this.originHasChanged_ = true; - } -}; diff --git a/core/toolbox.js b/core/toolbox.js deleted file mode 100644 index 67fcb0338d..0000000000 --- a/core/toolbox.js +++ /dev/null @@ -1,801 +0,0 @@ -/** - * @license - * Visual Blocks Editor - * - * Copyright 2011 Google Inc. - * https://developers.google.com/blockly/ - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @fileoverview Toolbox from whence to create blocks. - * @author fraser@google.com (Neil Fraser) - */ -'use strict'; - -goog.provide('Blockly.Toolbox'); - -goog.require('Blockly.Events.Ui'); -goog.require('Blockly.HorizontalFlyout'); -goog.require('Blockly.Touch'); -goog.require('Blockly.VerticalFlyout'); -goog.require('goog.dom'); -goog.require('goog.dom.TagName'); -goog.require('goog.events'); -goog.require('goog.events.BrowserFeature'); -goog.require('goog.html.SafeHtml'); -goog.require('goog.html.SafeStyle'); -goog.require('goog.math.Rect'); -goog.require('goog.style'); -goog.require('goog.ui.tree.TreeControl'); -goog.require('goog.ui.tree.TreeNode'); - - -/** - * Class for a Toolbox. - * Creates the toolbox's DOM. - * @param {!Blockly.Workspace} workspace The workspace in which to create new - * blocks. - * @constructor - */ -Blockly.Toolbox = function(workspace) { - /** - * @type {!Blockly.Workspace} - * @private - */ - this.workspace_ = workspace; - - /** - * Whether toolbox categories should be represented by icons instead of text. - * @type {boolean} - * @private - */ - this.iconic_ = false; - - /** - * Is RTL vs LTR. - * @type {boolean} - */ - this.RTL = workspace.options.RTL; - - /** - * Whether the toolbox should be laid out horizontally. - * @type {boolean} - * @private - */ - this.horizontalLayout_ = workspace.options.horizontalLayout; - - /** - * Position of the toolbox and flyout relative to the workspace. - * @type {number} - */ - this.toolboxPosition = workspace.options.toolboxPosition; - -}; - -/** - * Width of the toolbox, which changes only in vertical layout. - * This is the sum of the width of the flyout (250) and the category menu (60). - * @type {number} - */ -Blockly.Toolbox.prototype.width = 310; - -/** - * Height of the toolbox, which changes only in horizontal layout. - * @type {number} - */ -Blockly.Toolbox.prototype.height = 0; - -Blockly.Toolbox.prototype.selectedItem_ = null; - -/** - * Initializes the toolbox. - */ -Blockly.Toolbox.prototype.init = function() { - var workspace = this.workspace_; - var svg = this.workspace_.getParentSvg(); - - /** - * HTML container for the Toolbox menu. - * @type {Element} - */ - this.HtmlDiv = - goog.dom.createDom(goog.dom.TagName.DIV, 'blocklyToolboxDiv'); - this.HtmlDiv.setAttribute('dir', workspace.RTL ? 'RTL' : 'LTR'); - svg.parentNode.insertBefore(this.HtmlDiv, svg); - - // Clicking on toolbox closes popups. - Blockly.bindEventWithChecks_(this.HtmlDiv, 'mousedown', this, - function(e) { - // Cancel any gestures in progress. - this.workspace_.cancelCurrentGesture(); - if (Blockly.utils.isRightButton(e) || e.target == this.HtmlDiv) { - // Close flyout. - Blockly.hideChaff(false); - } else { - // Just close popups. - Blockly.hideChaff(true); - } - Blockly.Touch.clearTouchIdentifier(); // Don't block future drags. - }, /*opt_noCaptureIdentifier*/ false, /*opt_noPreventDefault*/ true); - - this.createFlyout_(); - this.categoryMenu_ = new Blockly.Toolbox.CategoryMenu(this, this.HtmlDiv); - this.populate_(workspace.options.languageTree); - this.position(); -}; - -/** - * Dispose of this toolbox. - */ -Blockly.Toolbox.prototype.dispose = function() { - this.flyout_.dispose(); - this.categoryMenu_.dispose(); - this.categoryMenu_ = null; - goog.dom.removeNode(this.HtmlDiv); - this.workspace_ = null; - this.lastCategory_ = null; -}; - -/** - * Create and configure a flyout based on the main workspace's options. - * @private - */ -Blockly.Toolbox.prototype.createFlyout_ = function() { - var workspace = this.workspace_; - - var options = { - disabledPatternId: workspace.options.disabledPatternId, - parentWorkspace: workspace, - RTL: workspace.RTL, - oneBasedIndex: workspace.options.oneBasedIndex, - horizontalLayout: workspace.horizontalLayout, - toolboxPosition: workspace.options.toolboxPosition, - stackGlowFilterId: workspace.options.stackGlowFilterId - }; - - if (workspace.horizontalLayout) { - this.flyout_ = new Blockly.HorizontalFlyout(options); - } else { - this.flyout_ = new Blockly.VerticalFlyout(options); - } - this.flyout_.setParentToolbox(this); - - goog.dom.insertSiblingAfter( - this.flyout_.createDom('svg'), this.workspace_.getParentSvg()); - this.flyout_.init(workspace); -}; - -/** - * Fill the toolbox with categories and blocks. - * @param {!Node} newTree DOM tree of blocks. - * @private - */ -Blockly.Toolbox.prototype.populate_ = function(newTree) { - this.categoryMenu_.populate(newTree); - this.showAll_(); - this.setSelectedItem(this.categoryMenu_.categories_[0], false); -}; - -/** - * Show all blocks for all categories in the flyout - * @private - */ -Blockly.Toolbox.prototype.showAll_ = function() { - var allContents = []; - for (var i = 0; i < this.categoryMenu_.categories_.length; i++) { - var category = this.categoryMenu_.categories_[i]; - - // create a label node to go at the top of the category - var labelString = ''; - var labelXML = Blockly.Xml.textToDom(labelString); - - allContents.push(labelXML.firstChild); - - allContents = allContents.concat(category.getContents()); - } - this.flyout_.show(allContents); -}; - -/** - * Get the width of the toolbox. - * @return {number} The width of the toolbox. - */ -Blockly.Toolbox.prototype.getWidth = function() { - return this.width; -}; - -/** - * Get the height of the toolbox, not including the block menu. - * @return {number} The height of the toolbox. - */ -Blockly.Toolbox.prototype.getHeight = function() { - return this.categoryMenu_ ? this.categoryMenu_.getHeight() : 0; -}; - -/** - * Move the toolbox to the edge. - */ -Blockly.Toolbox.prototype.position = function() { - var treeDiv = this.HtmlDiv; - if (!treeDiv) { - // Not initialized yet. - return; - } - var svg = this.workspace_.getParentSvg(); - var svgSize = Blockly.svgSize(svg); - if (this.horizontalLayout_) { - treeDiv.style.left = '0'; - treeDiv.style.height = 'auto'; - treeDiv.style.width = svgSize.width + 'px'; - this.height = treeDiv.offsetHeight; - if (this.toolboxPosition == Blockly.TOOLBOX_AT_TOP) { // Top - treeDiv.style.top = '0'; - } else { // Bottom - treeDiv.style.bottom = '0'; - } - } else { - if (this.toolboxPosition == Blockly.TOOLBOX_AT_RIGHT) { // Right - treeDiv.style.right = '0'; - } else { // Left - treeDiv.style.left = '0'; - } - treeDiv.style.height = '100%'; - } - this.flyout_.position(); -}; - -/** - * Unhighlight any previously specified option. - */ -Blockly.Toolbox.prototype.clearSelection = function() { - this.setSelectedItem(null); -}; - -/** - * Adds a style on the toolbox. Usually used to change the cursor. - * @param {string} style The name of the class to add. - * @package - */ -Blockly.Toolbox.prototype.addStyle = function(style) { - Blockly.utils.addClass(/** @type {!Element} */ (this.HtmlDiv), style); -}; - -/** - * Removes a style from the toolbox. Usually used to change the cursor. - * @param {string} style The name of the class to remove. - * @package - */ -Blockly.Toolbox.prototype.removeStyle = function(style) { - Blockly.utils.removeClass(/** @type {!Element} */ (this.HtmlDiv), style); -}; - -/** - * Return the deletion rectangle for this toolbox. - * @return {goog.math.Rect} Rectangle in which to delete. - */ -Blockly.Toolbox.prototype.getClientRect = function() { - if (!this.HtmlDiv) { - return null; - } - - // If not an auto closing flyout, always use the (larger) flyout client rect - if (!this.flyout_.autoClose) { - return this.flyout_.getClientRect(); - } - - // BIG_NUM is offscreen padding so that blocks dragged beyond the toolbox - // area are still deleted. Must be smaller than Infinity, but larger than - // the largest screen size. - var BIG_NUM = 10000000; - var toolboxRect = this.HtmlDiv.getBoundingClientRect(); - - var x = toolboxRect.left; - var y = toolboxRect.top; - var width = toolboxRect.width; - var height = toolboxRect.height; - - // Assumes that the toolbox is on the SVG edge. If this changes - // (e.g. toolboxes in mutators) then this code will need to be more complex. - if (this.toolboxPosition == Blockly.TOOLBOX_AT_LEFT) { - return new goog.math.Rect(-BIG_NUM, -BIG_NUM, BIG_NUM + x + width, - 2 * BIG_NUM); - } else if (this.toolboxPosition == Blockly.TOOLBOX_AT_RIGHT) { - return new goog.math.Rect(toolboxRect.right - width, -BIG_NUM, BIG_NUM + width, 2 * BIG_NUM); - } else if (this.toolboxPosition == Blockly.TOOLBOX_AT_TOP) { - return new goog.math.Rect(-BIG_NUM, -BIG_NUM, 2 * BIG_NUM, - BIG_NUM + y + height); - } else { // Bottom - return new goog.math.Rect(0, y, 2 * BIG_NUM, BIG_NUM); - } -}; - -/** - * Update the flyout's contents without closing it. Should be used in response - * to a change in one of the dynamic categories, such as variables or - * procedures. - */ -Blockly.Toolbox.prototype.refreshSelection = function() { - this.showAll_(); -}; - -/** - * @return {Blockly.Toolbox.Category} the currently selected category. - */ -Blockly.Toolbox.prototype.getSelectedItem = function() { - return this.selectedItem_; -}; - -/** - * @return {string} The name of the currently selected category. - */ -Blockly.Toolbox.prototype.getSelectedCategoryName = function() { - return this.selectedItem_.name_; -}; - -/** - * @return {string} The id of the currently selected category. - * @public - */ -Blockly.Toolbox.prototype.getSelectedCategoryId = function() { - return this.selectedItem_.id_; -}; - -/** - * @return {number} The distance flyout is scrolled below the top of the currently - * selected category. - */ -Blockly.Toolbox.prototype.getCategoryScrollOffset = function() { - var categoryPos = this.getCategoryPositionById(this.getSelectedCategoryId()); - return this.flyout_.getScrollPos() - categoryPos; -}; - -/** - * Get the position of a category by name. - * @param {string} name The name of the category. - * @return {number} The position of the category. - */ -Blockly.Toolbox.prototype.getCategoryPositionByName = function(name) { - var scrollPositions = this.flyout_.categoryScrollPositions; - for (var i = 0; i < scrollPositions.length; i++) { - if (name === scrollPositions[i].categoryName) { - return scrollPositions[i].position; - } - } -}; - -/** - * Get the position of a category by id. - * @param {string} id The id of the category. - * @return {number} The position of the category. - * @public - */ -Blockly.Toolbox.prototype.getCategoryPositionById = function(id) { - var scrollPositions = this.flyout_.categoryScrollPositions; - for (var i = 0; i < scrollPositions.length; i++) { - if (id === scrollPositions[i].categoryId) { - return scrollPositions[i].position; - } - } -}; - -/** - * Get the length of a category by name. - * @param {string} name The name of the category. - * @return {number} The length of the category. - */ -Blockly.Toolbox.prototype.getCategoryLengthByName = function(name) { - var scrollPositions = this.flyout_.categoryScrollPositions; - for (var i = 0; i < scrollPositions.length; i++) { - if (name === scrollPositions[i].categoryName) { - return scrollPositions[i].length; - } - } -}; - -/** - * Get the length of a category by id. - * @param {string} id The id of the category. - * @return {number} The length of the category. - * @public - */ -Blockly.Toolbox.prototype.getCategoryLengthById = function(id) { - var scrollPositions = this.flyout_.categoryScrollPositions; - for (var i = 0; i < scrollPositions.length; i++) { - if (id === scrollPositions[i].categoryId) { - return scrollPositions[i].length; - } - } -}; - -/** - * Set the scroll position of the flyout. - * @param {number} pos The position to set. - */ -Blockly.Toolbox.prototype.setFlyoutScrollPos = function(pos) { - this.flyout_.setScrollPos(pos); -}; - - -/** - * Set the currently selected category. - * @param {Blockly.Toolbox.Category} item The category to select. - * @param {boolean=} opt_shouldScroll Whether to scroll to the selected category. Defaults to true. - */ -Blockly.Toolbox.prototype.setSelectedItem = function(item, opt_shouldScroll) { - if (typeof opt_shouldScroll === 'undefined') { - opt_shouldScroll = true; - } - if (this.selectedItem_) { - // They selected a different category but one was already open. Close it. - this.selectedItem_.setSelected(false); - } - this.selectedItem_ = item; - if (this.selectedItem_ != null) { - this.selectedItem_.setSelected(true); - // Scroll flyout to the top of the selected category - var categoryId = item.id_; - if (opt_shouldScroll) { - this.scrollToCategoryById(categoryId); - } - } -}; - -/** - * Select and scroll to a category by name. - * @param {string} name The name of the category to select and scroll to. - */ -Blockly.Toolbox.prototype.setSelectedCategoryByName = function(name) { - this.selectCategoryByName(name); - this.scrollToCategoryByName(name); -}; - -/** - * Select and scroll to a category by id. - * @param {string} id The id of the category to select and scroll to. - * @public - */ -Blockly.Toolbox.prototype.setSelectedCategoryById = function(id) { - this.selectCategoryById(id); - this.scrollToCategoryById(id); -}; - -/** - * Scroll to a category by name. - * @param {string} name The name of the category to scroll to. - * @package - */ -Blockly.Toolbox.prototype.scrollToCategoryByName = function(name) { - var scrollPositions = this.flyout_.categoryScrollPositions; - for (var i = 0; i < scrollPositions.length; i++) { - if (name === scrollPositions[i].categoryName) { - this.flyout_.setVisible(true); - this.flyout_.scrollTo(scrollPositions[i].position); - return; - } - } -}; - -/** - * Scroll to a category by id. - * @param {string} id The id of the category to scroll to. - * @public - */ -Blockly.Toolbox.prototype.scrollToCategoryById = function(id) { - var scrollPositions = this.flyout_.categoryScrollPositions; - for (var i = 0; i < scrollPositions.length; i++) { - if (id === scrollPositions[i].categoryId) { - this.flyout_.setVisible(true); - this.flyout_.scrollTo(scrollPositions[i].position); - return; - } - } -}; - -/** - * Get a category by its index. - * @param {number} index The index of the category. - * @return {Blockly.Toolbox.Category} the category, or null if there are no categories. - * @package - */ -Blockly.Toolbox.prototype.getCategoryByIndex = function(index) { - if (!this.categoryMenu_.categories_) return null; - return this.categoryMenu_.categories_[index]; -}; - -/** - * Select a category by name. - * @param {string} name The name of the category to select. - * @package - */ -Blockly.Toolbox.prototype.selectCategoryByName = function(name) { - for (var i = 0; i < this.categoryMenu_.categories_.length; i++) { - var category = this.categoryMenu_.categories_[i]; - if (name === category.name_) { - this.selectedItem_.setSelected(false); - this.selectedItem_ = category; - this.selectedItem_.setSelected(true); - } - } -}; - -/** - * Select a category by id. - * @param {string} id The id of the category to select. - * @package - */ -Blockly.Toolbox.prototype.selectCategoryById = function(id) { - for (var i = 0; i < this.categoryMenu_.categories_.length; i++) { - var category = this.categoryMenu_.categories_[i]; - if (id === category.id_) { - this.selectedItem_.setSelected(false); - this.selectedItem_ = category; - this.selectedItem_.setSelected(true); - } - } -}; - -/** - * Wrapper function for calling setSelectedItem from a touch handler. - * @param {Blockly.Toolbox.Category} item The category to select. - * @return {function} A function that can be passed to bindEvent. - */ -Blockly.Toolbox.prototype.setSelectedItemFactory = function(item) { - var selectedItem = item; - return function() { - if (!this.workspace_.isDragging()) { - this.setSelectedItem(selectedItem); - Blockly.Touch.clearTouchIdentifier(); - } - }; -}; - -// Category menu -/** - * Class for a table of category titles that will control which category is - * displayed. - * @param {Blockly.Toolbox} parent The toolbox that owns the category menu. - * @param {Element} parentHtml The containing html div. - * @constructor - */ -Blockly.Toolbox.CategoryMenu = function(parent, parentHtml) { - this.parent_ = parent; - this.height_ = 0; - this.parentHtml_ = parentHtml; - this.createDom(); - this.categories_ = []; -}; - -/** - * @return {number} the height of the category menu. - */ -Blockly.Toolbox.CategoryMenu.prototype.getHeight = function() { - return this.height_; -}; - -/** - * Create the DOM for the category menu. - */ -Blockly.Toolbox.CategoryMenu.prototype.createDom = function() { - this.table = goog.dom.createDom('div', this.parent_.horizontalLayout_ ? - 'scratchCategoryMenuHorizontal' : 'scratchCategoryMenu'); - this.parentHtml_.appendChild(this.table); -}; - -/** - * Fill the toolbox with categories and blocks by creating a new - * {Blockly.Toolbox.Category} for every category tag in the toolbox xml. - * @param {Node} domTree DOM tree of blocks, or null. - */ -Blockly.Toolbox.CategoryMenu.prototype.populate = function(domTree) { - if (!domTree) { - return; - } - - // Remove old categories - this.dispose(); - this.createDom(); - var categories = []; - // Find actual categories from the DOM tree. - for (var i = 0, child; child = domTree.childNodes[i]; i++) { - if (!child.tagName || child.tagName.toUpperCase() != 'CATEGORY') { - continue; - } - categories.push(child); - } - - // Create a single column of categories - for (var i = 0; i < categories.length; i++) { - var child = categories[i]; - var row = goog.dom.createDom('div', 'scratchCategoryMenuRow'); - this.table.appendChild(row); - if (child) { - this.categories_.push(new Blockly.Toolbox.Category(this, row, - child)); - } - } - this.height_ = this.table.offsetHeight; -}; - -/** - * Dispose of this Category Menu and all of its children. - */ -Blockly.Toolbox.CategoryMenu.prototype.dispose = function() { - for (var i = 0, category; category = this.categories_[i]; i++) { - category.dispose(); - } - this.categories_ = []; - if (this.table) { - goog.dom.removeNode(this.table); - this.table = null; - } -}; - - -// Category -/** - * Class for the data model of a category in the toolbox. - * @param {Blockly.Toolbox.CategoryMenu} parent The category menu that owns this - * category. - * @param {Element} parentHtml The containing html div. - * @param {Node} domTree DOM tree of blocks. - * @constructor - */ -Blockly.Toolbox.Category = function(parent, parentHtml, domTree) { - this.parent_ = parent; - this.parentHtml_ = parentHtml; - this.name_ = domTree.getAttribute('name'); - this.id_ = domTree.getAttribute('id'); - this.setColour(domTree); - this.custom_ = domTree.getAttribute('custom'); - this.iconURI_ = domTree.getAttribute('iconURI'); - this.showStatusButton_ = domTree.getAttribute('showStatusButton'); - this.contents_ = []; - if (!this.custom_) { - this.parseContents_(domTree); - } - this.createDom(); -}; - -/** - * Dispose of this category and all of its contents. - */ -Blockly.Toolbox.Category.prototype.dispose = function() { - if (this.item_) { - goog.dom.removeNode(this.item_); - this.item = null; - } - this.parent_ = null; - this.parentHtml_ = null; - this.contents_ = null; -}; - -/** - * Used to determine the css classes for the menu item for this category - * based on its current state. - * @private - * @param {boolean=} selected Indication whether the category is currently selected. - * @return {string} The css class names to be applied, space-separated. - */ -Blockly.Toolbox.Category.prototype.getMenuItemClassName_ = function(selected) { - var classNames = [ - 'scratchCategoryMenuItem', - 'scratchCategoryId-' + this.id_, - ]; - if (selected) { - classNames.push('categorySelected'); - } - return classNames.join(' '); -}; - -/** - * Create the DOM for a category in the toolbox. - */ -Blockly.Toolbox.Category.prototype.createDom = function() { - var toolbox = this.parent_.parent_; - this.item_ = goog.dom.createDom('div', - {'class': this.getMenuItemClassName_()}); - this.label_ = goog.dom.createDom('div', - {'class': 'scratchCategoryMenuItemLabel'}, - Blockly.utils.replaceMessageReferences(this.name_)); - if (this.iconURI_) { - this.bubble_ = goog.dom.createDom('div', - {'class': 'scratchCategoryItemIcon'}); - this.bubble_.style.backgroundImage = 'url(' + this.iconURI_ + ')'; - } else { - this.bubble_ = goog.dom.createDom('div', - {'class': 'scratchCategoryItemBubble'}); - this.bubble_.style.backgroundColor = this.colour_; - this.bubble_.style.borderColor = this.secondaryColour_; - } - this.item_.appendChild(this.bubble_); - this.item_.appendChild(this.label_); - this.parentHtml_.appendChild(this.item_); - Blockly.bindEvent_( - this.item_, 'mouseup', toolbox, toolbox.setSelectedItemFactory(this)); -}; - -/** - * Set the selected state of this category. - * @param {boolean} selected Whether this category is selected. - */ -Blockly.Toolbox.Category.prototype.setSelected = function(selected) { - this.item_.className = this.getMenuItemClassName_(selected); -}; - -/** - * Set the contents of this category from DOM. - * @param {Node} domTree DOM tree of blocks. - * @constructor - */ -Blockly.Toolbox.Category.prototype.parseContents_ = function(domTree) { - for (var i = 0, child; child = domTree.childNodes[i]; i++) { - if (!child.tagName) { - // Skip - continue; - } - switch (child.tagName.toUpperCase()) { - case 'BLOCK': - case 'SHADOW': - case 'LABEL': - case 'BUTTON': - case 'SEP': - case 'TEXT': - this.contents_.push(child); - break; - default: - break; - } - } -}; - -/** - * Get the contents of this category. - * @return {!Array|string} xmlList List of blocks to show, or a string with the - * name of a custom category. - */ -Blockly.Toolbox.Category.prototype.getContents = function() { - return this.custom_ ? this.custom_ : this.contents_; -}; - -/** - * Set the colour of the category's background from a DOM node. - * @param {Node} node DOM node with "colour" and "secondaryColour" attribute. - * Colours are a hex string or hue on a colour wheel (0-360). - */ -Blockly.Toolbox.Category.prototype.setColour = function(node) { - var colour = node.getAttribute('colour'); - var secondaryColour = node.getAttribute('secondaryColour'); - if (goog.isString(colour)) { - if (colour.match(/^#[0-9a-fA-F]{6}$/)) { - this.colour_ = colour; - } else { - this.colour_ = Blockly.hueToRgb(colour); - } - if (secondaryColour.match(/^#[0-9a-fA-F]{6}$/)) { - this.secondaryColour_ = secondaryColour; - } else { - this.secondaryColour_ = Blockly.hueToRgb(secondaryColour); - } - this.hasColours_ = true; - } else { - this.colour_ = '#000000'; - this.secondaryColour_ = '#000000'; - } -}; diff --git a/core/tooltip.js b/core/tooltip.js deleted file mode 100644 index 2e3d3da49f..0000000000 --- a/core/tooltip.js +++ /dev/null @@ -1,337 +0,0 @@ -/** - * @license - * Visual Blocks Editor - * - * Copyright 2011 Google Inc. - * https://developers.google.com/blockly/ - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @fileoverview Library to create tooltips for Blockly. - * First, call Blockly.Tooltip.init() after onload. - * Second, set the 'tooltip' property on any SVG element that needs a tooltip. - * If the tooltip is a string, then that message will be displayed. - * If the tooltip is an SVG element, then that object's tooltip will be used. - * Third, call Blockly.Tooltip.bindMouseEvents(e) passing the SVG element. - * @author fraser@google.com (Neil Fraser) - */ -'use strict'; - -/** - * @name Blockly.Tooltip - * @namespace - **/ -goog.provide('Blockly.Tooltip'); - -goog.require('goog.dom'); -goog.require('goog.dom.TagName'); - - -/** - * Is a tooltip currently showing? - */ -Blockly.Tooltip.visible = false; - -/** - * Is someone else blocking the tooltip from being shown? - * @type {boolean} - * @private - */ -Blockly.Tooltip.blocked_ = false; - -/** - * Maximum width (in characters) of a tooltip. - */ -Blockly.Tooltip.LIMIT = 50; - -/** - * PID of suspended thread to clear tooltip on mouse out. - * @private - */ -Blockly.Tooltip.mouseOutPid_ = 0; - -/** - * PID of suspended thread to show the tooltip. - * @private - */ -Blockly.Tooltip.showPid_ = 0; - -/** - * Last observed X location of the mouse pointer (freezes when tooltip appears). - * @private - */ -Blockly.Tooltip.lastX_ = 0; - -/** - * Last observed Y location of the mouse pointer (freezes when tooltip appears). - * @private - */ -Blockly.Tooltip.lastY_ = 0; - -/** - * Current element being pointed at. - * @private - */ -Blockly.Tooltip.element_ = null; - -/** - * Once a tooltip has opened for an element, that element is 'poisoned' and - * cannot respawn a tooltip until the pointer moves over a different element. - * @private - */ -Blockly.Tooltip.poisonedElement_ = null; - -/** - * Horizontal offset between mouse cursor and tooltip. - */ -Blockly.Tooltip.OFFSET_X = 0; - -/** - * Vertical offset between mouse cursor and tooltip. - */ -Blockly.Tooltip.OFFSET_Y = 10; - -/** - * Radius mouse can move before killing tooltip. - */ -Blockly.Tooltip.RADIUS_OK = 10; - -/** - * Delay before tooltip appears. - */ -Blockly.Tooltip.HOVER_MS = 750; - -/** - * Horizontal padding between tooltip and screen edge. - */ -Blockly.Tooltip.MARGINS = 5; - -/** - * The HTML container. Set once by Blockly.Tooltip.createDom. - * @type {Element} - */ -Blockly.Tooltip.DIV = null; - -/** - * Create the tooltip div and inject it onto the page. - */ -Blockly.Tooltip.createDom = function() { - if (Blockly.Tooltip.DIV) { - return; // Already created. - } - // Create an HTML container for popup overlays (e.g. editor widgets). - Blockly.Tooltip.DIV = - goog.dom.createDom(goog.dom.TagName.DIV, 'blocklyTooltipDiv'); - document.body.appendChild(Blockly.Tooltip.DIV); -}; - -/** - * Binds the required mouse events onto an SVG element. - * @param {!Element} element SVG element onto which tooltip is to be bound. - */ -Blockly.Tooltip.bindMouseEvents = function(element) { - Blockly.bindEvent_(element, 'mouseover', null, - Blockly.Tooltip.onMouseOver_); - Blockly.bindEvent_(element, 'mouseout', null, - Blockly.Tooltip.onMouseOut_); - - // Don't use bindEvent_ for mousemove since that would create a - // corresponding touch handler, even though this only makes sense in the - // context of a mouseover/mouseout. - element.addEventListener('mousemove', Blockly.Tooltip.onMouseMove_, false); -}; - -/** - * Hide the tooltip if the mouse is over a different object. - * Initialize the tooltip to potentially appear for this object. - * @param {!Event} e Mouse event. - * @private - */ -Blockly.Tooltip.onMouseOver_ = function(e) { - if (Blockly.Tooltip.blocked_) { - // Someone doesn't want us to show tooltips. - return; - } - // If the tooltip is an object, treat it as a pointer to the next object in - // the chain to look at. Terminate when a string or function is found. - var element = e.target; - while (!goog.isString(element.tooltip) && !goog.isFunction(element.tooltip)) { - element = element.tooltip; - } - if (Blockly.Tooltip.element_ != element) { - Blockly.Tooltip.hide(); - Blockly.Tooltip.poisonedElement_ = null; - Blockly.Tooltip.element_ = element; - } - // Forget about any immediately preceding mouseOut event. - clearTimeout(Blockly.Tooltip.mouseOutPid_); -}; - -/** - * Hide the tooltip if the mouse leaves the object and enters the workspace. - * @param {!Event} _e Mouse event. - * @private - */ -Blockly.Tooltip.onMouseOut_ = function(_e) { - if (Blockly.Tooltip.blocked_) { - // Someone doesn't want us to show tooltips. - return; - } - // Moving from one element to another (overlapping or with no gap) generates - // a mouseOut followed instantly by a mouseOver. Fork off the mouseOut - // event and kill it if a mouseOver is received immediately. - // This way the task only fully executes if mousing into the void. - Blockly.Tooltip.mouseOutPid_ = setTimeout(function() { - Blockly.Tooltip.element_ = null; - Blockly.Tooltip.poisonedElement_ = null; - Blockly.Tooltip.hide(); - }, 1); - clearTimeout(Blockly.Tooltip.showPid_); -}; - -/** - * When hovering over an element, schedule a tooltip to be shown. If a tooltip - * is already visible, hide it if the mouse strays out of a certain radius. - * @param {!Event} e Mouse event. - * @private - */ -Blockly.Tooltip.onMouseMove_ = function(e) { - if (!Blockly.Tooltip.element_ || !Blockly.Tooltip.element_.tooltip) { - // No tooltip here to show. - return; - } else if (Blockly.WidgetDiv.isVisible()) { - // Don't display a tooltip if a widget is open (tooltip would be under it). - return; - } else if (Blockly.Tooltip.blocked_) { - // Someone doesn't want us to show tooltips. We are probably handling a - // user gesture, such as a click or drag. - return; - } - if (Blockly.Tooltip.visible) { - // Compute the distance between the mouse position when the tooltip was - // shown and the current mouse position. Pythagorean theorem. - var dx = Blockly.Tooltip.lastX_ - e.pageX; - var dy = Blockly.Tooltip.lastY_ - e.pageY; - if (Math.sqrt(dx * dx + dy * dy) > Blockly.Tooltip.RADIUS_OK) { - Blockly.Tooltip.hide(); - } - } else if (Blockly.Tooltip.poisonedElement_ != Blockly.Tooltip.element_) { - // The mouse moved, clear any previously scheduled tooltip. - clearTimeout(Blockly.Tooltip.showPid_); - // Maybe this time the mouse will stay put. Schedule showing of tooltip. - Blockly.Tooltip.lastX_ = e.pageX; - Blockly.Tooltip.lastY_ = e.pageY; - Blockly.Tooltip.showPid_ = - setTimeout(Blockly.Tooltip.show_, Blockly.Tooltip.HOVER_MS); - } -}; - -/** - * Hide the tooltip. - */ -Blockly.Tooltip.hide = function() { - if (Blockly.Tooltip.visible) { - Blockly.Tooltip.visible = false; - if (Blockly.Tooltip.DIV) { - Blockly.Tooltip.DIV.style.display = 'none'; - } - } - if (Blockly.Tooltip.showPid_) { - clearTimeout(Blockly.Tooltip.showPid_); - } -}; - -/** - * Hide any in-progress tooltips and block showing new tooltips until the next - * call to unblock(). - * @package - */ -Blockly.Tooltip.block = function() { - Blockly.Tooltip.hide(); - Blockly.Tooltip.blocked_ = true; -}; - -/** - * Unblock tooltips: allow them to be scheduled and shown according to their own - * logic. - * @package - */ -Blockly.Tooltip.unblock = function() { - Blockly.Tooltip.blocked_ = false; -}; - -/** - * Create the tooltip and show it. - * @private - */ -Blockly.Tooltip.show_ = function() { - if (Blockly.Tooltip.blocked_) { - // Someone doesn't want us to show tooltips. - return; - } - Blockly.Tooltip.poisonedElement_ = Blockly.Tooltip.element_; - if (!Blockly.Tooltip.DIV) { - return; - } - // Erase all existing text. - goog.dom.removeChildren(/** @type {!Element} */ (Blockly.Tooltip.DIV)); - // Get the new text. - var tip = Blockly.Tooltip.element_.tooltip; - while (goog.isFunction(tip)) { - tip = tip(); - } - tip = Blockly.utils.wrap(tip, Blockly.Tooltip.LIMIT); - // Create new text, line by line. - var lines = tip.split('\n'); - for (var i = 0; i < lines.length; i++) { - var div = document.createElement('div'); - div.appendChild(document.createTextNode(lines[i])); - Blockly.Tooltip.DIV.appendChild(div); - } - var rtl = Blockly.Tooltip.element_.RTL; - var windowSize = goog.dom.getViewportSize(); - // Display the tooltip. - Blockly.Tooltip.DIV.style.direction = rtl ? 'rtl' : 'ltr'; - Blockly.Tooltip.DIV.style.display = 'block'; - Blockly.Tooltip.visible = true; - // Move the tooltip to just below the cursor. - var anchorX = Blockly.Tooltip.lastX_; - if (rtl) { - anchorX -= Blockly.Tooltip.OFFSET_X + Blockly.Tooltip.DIV.offsetWidth; - } else { - anchorX += Blockly.Tooltip.OFFSET_X; - } - var anchorY = Blockly.Tooltip.lastY_ + Blockly.Tooltip.OFFSET_Y; - - if (anchorY + Blockly.Tooltip.DIV.offsetHeight > - windowSize.height + window.scrollY) { - // Falling off the bottom of the screen; shift the tooltip up. - anchorY -= Blockly.Tooltip.DIV.offsetHeight + 2 * Blockly.Tooltip.OFFSET_Y; - } - if (rtl) { - // Prevent falling off left edge in RTL mode. - anchorX = Math.max(Blockly.Tooltip.MARGINS - window.scrollX, anchorX); - } else { - if (anchorX + Blockly.Tooltip.DIV.offsetWidth > - windowSize.width + window.scrollX - 2 * Blockly.Tooltip.MARGINS) { - // Falling off the right edge of the screen; - // clamp the tooltip on the edge. - anchorX = windowSize.width - Blockly.Tooltip.DIV.offsetWidth - - 2 * Blockly.Tooltip.MARGINS; - } - } - Blockly.Tooltip.DIV.style.top = anchorY + 'px'; - Blockly.Tooltip.DIV.style.left = anchorX + 'px'; -}; diff --git a/core/touch.js b/core/touch.js deleted file mode 100644 index debad6b9c4..0000000000 --- a/core/touch.js +++ /dev/null @@ -1,226 +0,0 @@ -/** - * @license - * Visual Blocks Editor - * - * Copyright 2016 Google Inc. - * https://developers.google.com/blockly/ - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @fileoverview Touch handling for Blockly. - * @author fenichel@google.com (Rachel Fenichel) - */ -'use strict'; - -/** - * @name Blockly.Touch - * @namespace - **/ -goog.provide('Blockly.Touch'); - -goog.require('goog.events'); -goog.require('goog.events.BrowserFeature'); -goog.require('goog.string'); - - -/** - * Which touch events are we currently paying attention to? - * @type {DOMString} - * @private - */ -Blockly.Touch.touchIdentifier_ = null; - -/** - * The TOUCH_MAP lookup dictionary specifies additional touch events to fire, - * in conjunction with mouse events. - * @type {Object} - */ -Blockly.Touch.TOUCH_MAP = {}; -if (goog.events.BrowserFeature.TOUCH_ENABLED) { - Blockly.Touch.TOUCH_MAP = { - 'mousedown': ['touchstart'], - 'mousemove': ['touchmove'], - 'mouseup': ['touchend', 'touchcancel'] - }; -} - -/** - * PID of queued long-press task. - * @private - */ -Blockly.longPid_ = 0; - -/** - * Context menus on touch devices are activated using a long-press. - * Unfortunately the contextmenu touch event is currently (2015) only supported - * by Chrome. This function is fired on any touchstart event, queues a task, - * which after about a second opens the context menu. The tasks is killed - * if the touch event terminates early. - * @param {!Event} e Touch start event. - * @param {Blockly.Gesture} gesture The gesture that triggered this longStart. - * @private - */ -Blockly.longStart_ = function(e, gesture) { - Blockly.longStop_(); - // Punt on multitouch events. - if (e.changedTouches.length != 1) { - return; - } - Blockly.longPid_ = setTimeout(function() { - e.button = 2; // Simulate a right button click. - // e was a touch event. It needs to pretend to be a mouse event. - e.clientX = e.changedTouches[0].clientX; - e.clientY = e.changedTouches[0].clientY; - - // Let the gesture route the right-click correctly. - if (gesture) { - gesture.handleRightClick(e); - } - }, Blockly.LONGPRESS); -}; - -/** - * Nope, that's not a long-press. Either touchend or touchcancel was fired, - * or a drag hath begun. Kill the queued long-press task. - * @private - */ -Blockly.longStop_ = function() { - if (Blockly.longPid_) { - clearTimeout(Blockly.longPid_); - Blockly.longPid_ = 0; - } -}; - -/** - * Clear the touch identifier that tracks which touch stream to pay attention - * to. This ends the current drag/gesture and allows other pointers to be - * captured. - */ -Blockly.Touch.clearTouchIdentifier = function() { - Blockly.Touch.touchIdentifier_ = null; -}; - -/** - * Decide whether Blockly should handle or ignore this event. - * Mouse and touch events require special checks because we only want to deal - * with one touch stream at a time. All other events should always be handled. - * @param {!Event} e The event to check. - * @return {boolean} True if this event should be passed through to the - * registered handler; false if it should be blocked. - */ -Blockly.Touch.shouldHandleEvent = function(e) { - return !Blockly.Touch.isMouseOrTouchEvent(e) || - Blockly.Touch.checkTouchIdentifier(e); -}; - -/** - * Get the touch identifier from the given event. If it was a mouse event, the - * identifier is the string 'mouse'. - * @param {!Event} e Mouse event or touch event. - * @return {string} The touch identifier from the first changed touch, if - * defined. Otherwise 'mouse'. - */ -Blockly.Touch.getTouchIdentifierFromEvent = function(e) { - return (e.changedTouches && e.changedTouches[0] && - e.changedTouches[0].identifier != undefined && - e.changedTouches[0].identifier != null) ? - e.changedTouches[0].identifier : 'mouse'; -}; - -/** - * Check whether the touch identifier on the event matches the current saved - * identifier. If there is no identifier, that means it's a mouse event and - * we'll use the identifier "mouse". This means we won't deal well with - * multiple mice being used at the same time. That seems okay. - * If the current identifier was unset, save the identifier from the - * event. This starts a drag/gesture, during which touch events with other - * identifiers will be silently ignored. - * @param {!Event} e Mouse event or touch event. - * @return {boolean} Whether the identifier on the event matches the current - * saved identifier. - */ -Blockly.Touch.checkTouchIdentifier = function(e) { - var identifier = Blockly.Touch.getTouchIdentifierFromEvent(e); - - // if (Blockly.touchIdentifier_ )is insufficient because Android touch - // identifiers may be zero. - if (Blockly.Touch.touchIdentifier_ != undefined && - Blockly.Touch.touchIdentifier_ != null) { - // We're already tracking some touch/mouse event. Is this from the same - // source? - return Blockly.Touch.touchIdentifier_ == identifier; - } - if (e.type == 'mousedown' || e.type == 'touchstart') { - // No identifier set yet, and this is the start of a drag. Set it and - // return. - Blockly.Touch.touchIdentifier_ = identifier; - return true; - } - // There was no identifier yet, but this wasn't a start event so we're going - // to ignore it. This probably means that another drag finished while this - // pointer was down. - return false; -}; - -/** - * Set an event's clientX and clientY from its first changed touch. Use this to - * make a touch event work in a mouse event handler. - * @param {!Event} e A touch event. - */ -Blockly.Touch.setClientFromTouch = function(e) { - if (Blockly.utils.startsWith(e.type, 'touch')) { - // Map the touch event's properties to the event. - var touchPoint = e.changedTouches[0]; - e.clientX = touchPoint.clientX; - e.clientY = touchPoint.clientY; - } -}; - -/** - * Check whether a given event is a mouse or touch event. - * @param {!Event} e An event. - * @return {boolean} true if it is a mouse or touch event; false otherwise. - */ -Blockly.Touch.isMouseOrTouchEvent = function(e) { - return Blockly.utils.startsWith(e.type, 'touch') || - Blockly.utils.startsWith(e.type, 'mouse'); -}; - -/** - * Split an event into an array of events, one per changed touch or mouse - * point. - * @param {!Event} e A mouse event or a touch event with one or more changed - * touches. - * @return {!Array.} An array of mouse or touch events. Each touch - * event will have exactly one changed touch. - */ -Blockly.Touch.splitEventByTouches = function(e) { - var events = []; - if (e.changedTouches) { - for (var i = 0; i < e.changedTouches.length; i++) { - var newEvent = { - type: e.type, - changedTouches: [e.changedTouches[i]], - target: e.target, - stopPropagation: function(){ e.stopPropagation(); }, - preventDefault: function(){ e.preventDefault(); } - }; - events[i] = newEvent; - } - } else { - events.push(e); - } - return events; -}; diff --git a/core/trashcan.js b/core/trashcan.js deleted file mode 100644 index 4a39ce1ffc..0000000000 --- a/core/trashcan.js +++ /dev/null @@ -1,343 +0,0 @@ -/** - * @license - * Visual Blocks Editor - * - * Copyright 2011 Google Inc. - * https://developers.google.com/blockly/ - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @fileoverview Object representing a trash can icon. - * @author fraser@google.com (Neil Fraser) - */ -'use strict'; - -goog.provide('Blockly.Trashcan'); - -goog.require('goog.dom'); -goog.require('goog.math.Rect'); - - -/** - * Class for a trash can. - * @param {!Blockly.Workspace} workspace The workspace to sit in. - * @constructor - */ -Blockly.Trashcan = function(workspace) { - this.workspace_ = workspace; -}; - -/** - * Width of both the trash can and lid images. - * @type {number} - * @private - */ -Blockly.Trashcan.prototype.WIDTH_ = 47; - -/** - * Height of the trashcan image (minus lid). - * @type {number} - * @private - */ -Blockly.Trashcan.prototype.BODY_HEIGHT_ = 44; - -/** - * Height of the lid image. - * @type {number} - * @private - */ -Blockly.Trashcan.prototype.LID_HEIGHT_ = 16; - -/** - * Distance between trashcan and bottom edge of workspace. - * @type {number} - * @private - */ -Blockly.Trashcan.prototype.MARGIN_BOTTOM_ = 20; - -/** - * Distance between trashcan and right edge of workspace. - * @type {number} - * @private - */ -Blockly.Trashcan.prototype.MARGIN_SIDE_ = 20; - -/** - * Extent of hotspot on all sides beyond the size of the image. - * @type {number} - * @private - */ -Blockly.Trashcan.prototype.MARGIN_HOTSPOT_ = 10; - -/** - * Location of trashcan in sprite image. - * @type {number} - * @private - */ -Blockly.Trashcan.prototype.SPRITE_LEFT_ = 0; - -/** - * Location of trashcan in sprite image. - * @type {number} - * @private - */ -Blockly.Trashcan.prototype.SPRITE_TOP_ = 32; - -/** - * Current open/close state of the lid. - * @type {boolean} - */ -Blockly.Trashcan.prototype.isOpen = false; - -/** - * The SVG group containing the trash can. - * @type {Element} - * @private - */ -Blockly.Trashcan.prototype.svgGroup_ = null; - -/** - * The SVG image element of the trash can lid. - * @type {Element} - * @private - */ -Blockly.Trashcan.prototype.svgLid_ = null; - -/** - * Task ID of opening/closing animation. - * @type {number} - * @private - */ -Blockly.Trashcan.prototype.lidTask_ = 0; - -/** - * Current state of lid opening (0.0 = closed, 1.0 = open). - * @type {number} - * @private - */ -Blockly.Trashcan.prototype.lidOpen_ = 0; - -/** - * Left coordinate of the trash can. - * @type {number} - * @private - */ -Blockly.Trashcan.prototype.left_ = 0; - -/** - * Top coordinate of the trash can. - * @type {number} - * @private - */ -Blockly.Trashcan.prototype.top_ = 0; - -/** - * Create the trash can elements. - * @return {!Element} The trash can's SVG group. - */ -Blockly.Trashcan.prototype.createDom = function() { - /* Here's the markup that will be generated: - - - - - - - - - - - */ - this.svgGroup_ = Blockly.utils.createSvgElement('g', - {'class': 'blocklyTrash'}, null); - var clip; - var rnd = String(Math.random()).substring(2); - clip = Blockly.utils.createSvgElement('clipPath', - {'id': 'blocklyTrashBodyClipPath' + rnd}, - this.svgGroup_); - Blockly.utils.createSvgElement('rect', - { - 'width': this.WIDTH_, - 'height': this.BODY_HEIGHT_, - 'y': this.LID_HEIGHT_ - }, - clip); - var body = Blockly.utils.createSvgElement('image', - { - 'width': Blockly.SPRITE.width, - 'x': -this.SPRITE_LEFT_, - 'height': Blockly.SPRITE.height, - 'y': -this.SPRITE_TOP_, - 'clip-path': 'url(#blocklyTrashBodyClipPath' + rnd + ')' - }, - this.svgGroup_); - body.setAttributeNS('http://www.w3.org/1999/xlink', 'xlink:href', - this.workspace_.options.pathToMedia + Blockly.SPRITE.url); - - clip = Blockly.utils.createSvgElement('clipPath', - {'id': 'blocklyTrashLidClipPath' + rnd}, - this.svgGroup_); - Blockly.utils.createSvgElement('rect', - {'width': this.WIDTH_, 'height': this.LID_HEIGHT_}, clip); - this.svgLid_ = Blockly.utils.createSvgElement('image', - { - 'width': Blockly.SPRITE.width, - 'x': -this.SPRITE_LEFT_, - 'height': Blockly.SPRITE.height, - 'y': -this.SPRITE_TOP_, - 'clip-path': 'url(#blocklyTrashLidClipPath' + rnd + ')' - }, - this.svgGroup_); - this.svgLid_.setAttributeNS('http://www.w3.org/1999/xlink', 'xlink:href', - this.workspace_.options.pathToMedia + Blockly.SPRITE.url); - - Blockly.bindEventWithChecks_(this.svgGroup_, 'mouseup', this, this.click); - this.animateLid_(); - return this.svgGroup_; -}; - -/** - * Initialize the trash can. - * @param {number} bottom Distance from workspace bottom to bottom of trashcan. - * @return {number} Distance from workspace bottom to the top of trashcan. - */ -Blockly.Trashcan.prototype.init = function(bottom) { - this.bottom_ = this.MARGIN_BOTTOM_ + bottom; - this.setOpen_(false); - return this.bottom_ + this.BODY_HEIGHT_ + this.LID_HEIGHT_; -}; - -/** - * Dispose of this trash can. - * Unlink from all DOM elements to prevent memory leaks. - */ -Blockly.Trashcan.prototype.dispose = function() { - if (this.svgGroup_) { - goog.dom.removeNode(this.svgGroup_); - this.svgGroup_ = null; - } - this.svgLid_ = null; - this.workspace_ = null; - clearTimeout(this.lidTask_); -}; - -/** - * Move the trash can to the bottom-right corner. - */ -Blockly.Trashcan.prototype.position = function() { - var metrics = this.workspace_.getMetrics(); - if (!metrics) { - // There are no metrics available (workspace is probably not visible). - return; - } - if (this.workspace_.RTL) { - this.left_ = this.MARGIN_SIDE_ + Blockly.Scrollbar.scrollbarThickness; - if (metrics.toolboxPosition == Blockly.TOOLBOX_AT_LEFT) { - this.left_ += metrics.flyoutWidth; - if (this.workspace_.toolbox_) { - this.left_ += metrics.absoluteLeft; - } - } - } else { - this.left_ = metrics.viewWidth + metrics.absoluteLeft - - this.WIDTH_ - this.MARGIN_SIDE_ - Blockly.Scrollbar.scrollbarThickness; - - if (metrics.toolboxPosition == Blockly.TOOLBOX_AT_RIGHT) { - this.left_ -= metrics.flyoutWidth; - } - } - this.top_ = metrics.viewHeight + metrics.absoluteTop - - (this.BODY_HEIGHT_ + this.LID_HEIGHT_) - this.bottom_; - - if (metrics.toolboxPosition == Blockly.TOOLBOX_AT_BOTTOM) { - this.top_ -= metrics.flyoutHeight; - } - this.svgGroup_.setAttribute('transform', - 'translate(' + this.left_ + ',' + this.top_ + ')'); -}; - -/** - * Return the deletion rectangle for this trash can. - * @return {goog.math.Rect} Rectangle in which to delete. - */ -Blockly.Trashcan.prototype.getClientRect = function() { - if (!this.svgGroup_) { - return null; - } - - var trashRect = this.svgGroup_.getBoundingClientRect(); - var left = trashRect.left + this.SPRITE_LEFT_ - this.MARGIN_HOTSPOT_; - var top = trashRect.top + this.SPRITE_TOP_ - this.MARGIN_HOTSPOT_; - var width = this.WIDTH_ + 2 * this.MARGIN_HOTSPOT_; - var height = this.LID_HEIGHT_ + this.BODY_HEIGHT_ + 2 * this.MARGIN_HOTSPOT_; - return new goog.math.Rect(left, top, width, height); - -}; - -/** - * Flip the lid open or shut. - * @param {boolean} state True if open. - * @private - */ -Blockly.Trashcan.prototype.setOpen_ = function(state) { - if (this.isOpen == state) { - return; - } - clearTimeout(this.lidTask_); - this.isOpen = state; - this.animateLid_(); -}; - -/** - * Rotate the lid open or closed by one step. Then wait and recurse. - * @private - */ -Blockly.Trashcan.prototype.animateLid_ = function() { - this.lidOpen_ += this.isOpen ? 0.2 : -0.2; - this.lidOpen_ = Math.min(Math.max(this.lidOpen_, 0), 1); - var lidAngle = this.lidOpen_ * 45; - this.svgLid_.setAttribute('transform', 'rotate(' + - (this.workspace_.RTL ? -lidAngle : lidAngle) + ',' + - (this.workspace_.RTL ? 4 : this.WIDTH_ - 4) + ',' + - (this.LID_HEIGHT_ - 2) + ')'); - // Linear interpolation between 0.4 and 0.8. - var opacity = 0.4 + this.lidOpen_ * (0.8 - 0.4); - this.svgGroup_.style.opacity = opacity; - if (this.lidOpen_ > 0 && this.lidOpen_ < 1) { - this.lidTask_ = setTimeout(this.animateLid_.bind(this), 20); - } -}; - -/** - * Flip the lid shut. - * Called externally after a drag. - */ -Blockly.Trashcan.prototype.close = function() { - this.setOpen_(false); -}; - -/** - * Inspect the contents of the trash. - */ -Blockly.Trashcan.prototype.click = function() { - var dx = this.workspace_.startScrollX - this.workspace_.scrollX; - var dy = this.workspace_.startScrollY - this.workspace_.scrollY; - if (Math.sqrt(dx * dx + dy * dy) > Blockly.DRAG_RADIUS) { - return; - } - console.log('TODO: Inspect trash.'); -}; diff --git a/core/ui_events.js b/core/ui_events.js deleted file mode 100644 index 2430ac928b..0000000000 --- a/core/ui_events.js +++ /dev/null @@ -1,91 +0,0 @@ -/** - * @license - * Visual Blocks Editor - * - * Copyright 2018 Google Inc. - * https://developers.google.com/blockly/ - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @fileoverview Events fired as a result of UI actions in Blockly's editor. - * @author fraser@google.com (Neil Fraser) - */ -'use strict'; - -goog.provide('Blockly.Events.Ui'); - -goog.require('Blockly.Events'); -goog.require('Blockly.Events.Abstract'); - -goog.require('goog.array'); -goog.require('goog.math.Coordinate'); - -/** - * Class for a UI event. - * UI events are events that don't need to be sent over the wire for multi-user - * editing to work (e.g. scrolling the workspace, zooming, opening toolbox - * categories). - * UI events do not undo or redo. - * @param {Blockly.Block} block The affected block. - * @param {string} element One of 'selected', 'comment', 'mutator', etc. - * @param {*} oldValue Previous value of element. - * @param {*} newValue New value of element. - * @extends {Blockly.Events.Abstract} - * @constructor - */ -Blockly.Events.Ui = function(block, element, oldValue, newValue) { - Blockly.Events.Ui.superClass_.constructor.call(this); - this.blockId = block ? block.id : null; - this.workspaceId = block ? block.workspace.id : null; - this.element = element; - this.oldValue = oldValue; - this.newValue = newValue; - // UI events do not undo or redo. - this.recordUndo = false; -}; -goog.inherits(Blockly.Events.Ui, Blockly.Events.Abstract); - -/** - * Type of this event. - * @type {string} - */ -Blockly.Events.Ui.prototype.type = Blockly.Events.UI; - -/** - * Encode the event as JSON. - * @return {!Object} JSON representation. - */ -Blockly.Events.Ui.prototype.toJson = function() { - var json = Blockly.Events.Ui.superClass_.toJson.call(this); - json['element'] = this.element; - if (this.newValue !== undefined) { - json['newValue'] = this.newValue; - } - if (this.blockId) { - json['blockId'] = this.blockId; - } - return json; -}; - -/** - * Decode the JSON event. - * @param {!Object} json JSON representation. - */ -Blockly.Events.Ui.prototype.fromJson = function(json) { - Blockly.Events.Ui.superClass_.fromJson.call(this, json); - this.element = json['element']; - this.newValue = json['newValue']; - this.blockId = json['blockId']; -}; diff --git a/core/ui_menu_utils.js b/core/ui_menu_utils.js deleted file mode 100644 index 8fda6021ac..0000000000 --- a/core/ui_menu_utils.js +++ /dev/null @@ -1,68 +0,0 @@ -/** - * @license - * Visual Blocks Editor - * - * Copyright 2017 Google Inc. - * https://developers.google.com/blockly/ - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @fileoverview Utility methods for working with the closure menu (goog.ui.menu). - * @author fenichel@google.com (Rachel Fenichel) - */ -'use strict'; - -/** - * @name Blockly.utils.uiMenu - * @namespace - **/ -goog.provide('Blockly.utils.uiMenu'); - - -/** - * Get the size of a rendered goog.ui.Menu. - * @param {!goog.ui.Menu} menu The menu to measure. - * @return {!goog.math.Size} Object with width and height properties. - * @package - */ -Blockly.utils.uiMenu.getSize = function(menu) { - var menuDom = menu.getElement(); - var menuSize = goog.style.getSize(menuDom); - // Recalculate height for the total content, not only box height. - menuSize.height = menuDom.scrollHeight; - return menuSize; -}; - -/** - * Adjust the bounding boxes used to position the widget div to deal with RTL - * goog.ui.Menu positioning. In RTL mode the menu renders down and to the left - * of its start point, instead of down and to the right. Adjusting all of the - * bounding boxes accordingly allows us to use the same code for all widgets. - * This function in-place modifies the provided bounding boxes. - * @param {!Object} viewportBBox The bounding rectangle of the current viewport, - * in window coordinates. - * @param {!Object} anchorBBox The bounding rectangle of the anchor, in window - * coordinates. - * @param {!goog.math.Size} menuSize The size of the menu that is inside the - * widget div, in window coordinates. - * @package - */ -Blockly.utils.uiMenu.adjustBBoxesForRTL = function(viewportBBox, anchorBBox, - menuSize) { - anchorBBox.left += menuSize.width; - anchorBBox.right += menuSize.width; - viewportBBox.left += menuSize.width; - viewportBBox.right += menuSize.width; -}; diff --git a/core/utils.js b/core/utils.js deleted file mode 100644 index a29c705ebf..0000000000 --- a/core/utils.js +++ /dev/null @@ -1,948 +0,0 @@ -/** - * @license - * Visual Blocks Editor - * - * Copyright 2012 Google Inc. - * https://developers.google.com/blockly/ - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @fileoverview Utility methods. - * These methods are not specific to Blockly, and could be factored out into - * a JavaScript framework such as Closure. - * @author fraser@google.com (Neil Fraser) - */ -'use strict'; - -/** - * @name Blockly.utils - * @namespace - **/ -goog.provide('Blockly.utils'); - -goog.require('Blockly.Touch'); -goog.require('goog.dom'); -goog.require('goog.events.BrowserFeature'); -goog.require('goog.math.Coordinate'); -goog.require('goog.userAgent'); - - -/** - * To allow ADVANCED_OPTIMIZATIONS, combining variable.name and variable['name'] - * is not possible. To access the exported Blockly.Msg.Something it needs to be - * accessed through the exact name that was exported. Note, that all the exports - * are happening as the last thing in the generated js files, so they won't be - * accessible before JavaScript loads! - * @return {!Object.} The message array. - * @private - */ -Blockly.utils.getMessageArray_ = function() { - return goog.global['Blockly']['Msg']; -}; - -/** - * Remove an attribute from a element even if it's in IE 10. - * Similar to Element.removeAttribute() but it works on SVG elements in IE 10. - * Sets the attribute to null in IE 10, which treats removeAttribute as a no-op - * if it's called on an SVG element. - * @param {!Element} element DOM element to remove attribute from. - * @param {string} attributeName Name of attribute to remove. - */ -Blockly.utils.removeAttribute = function(element, attributeName) { - // goog.userAgent.isVersion is deprecated, but the replacement is - // goog.userAgent.isVersionOrHigher. - if (goog.userAgent.IE && goog.userAgent.isVersion('10.0')) { - element.setAttribute(attributeName, null); - } else { - element.removeAttribute(attributeName); - } -}; - -/** - * Add a CSS class to a element. - * Similar to Closure's goog.dom.classes.add, except it handles SVG elements. - * @param {!Element} element DOM element to add class to. - * @param {string} className Name of class to add. - * @return {boolean} True if class was added, false if already present. - */ -Blockly.utils.addClass = function(element, className) { - var classes = element.getAttribute('class') || ''; - if ((' ' + classes + ' ').indexOf(' ' + className + ' ') != -1) { - return false; - } - if (classes) { - classes += ' '; - } - element.setAttribute('class', classes + className); - return true; -}; - -/** - * Remove a CSS class from a element. - * Similar to Closure's goog.dom.classes.remove, except it handles SVG elements. - * @param {!Element} element DOM element to remove class from. - * @param {string} className Name of class to remove. - * @return {boolean} True if class was removed, false if never present. - */ -Blockly.utils.removeClass = function(element, className) { - var classes = element.getAttribute('class'); - if ((' ' + classes + ' ').indexOf(' ' + className + ' ') == -1) { - return false; - } - var classList = classes.split(/\s+/); - for (var i = 0; i < classList.length; i++) { - if (!classList[i] || classList[i] == className) { - classList.splice(i, 1); - i--; - } - } - if (classList.length) { - element.setAttribute('class', classList.join(' ')); - } else { - Blockly.utils.removeAttribute(element, 'class'); - } - return true; -}; - -/** - * Checks if an element has the specified CSS class. - * Similar to Closure's goog.dom.classes.has, except it handles SVG elements. - * @param {!Element} element DOM element to check. - * @param {string} className Name of class to check. - * @return {boolean} True if class exists, false otherwise. - * @package - */ -Blockly.utils.hasClass = function(element, className) { - var classes = element.getAttribute('class'); - return (' ' + classes + ' ').indexOf(' ' + className + ' ') != -1; -}; - -/** - * Don't do anything for this event, just halt propagation. - * @param {!Event} e An event. - */ -Blockly.utils.noEvent = function(e) { - // This event has been handled. No need to bubble up to the document. - e.preventDefault(); - e.stopPropagation(); -}; - -/** - * Is this event targeting a text input widget? - * @param {!Event} e An event. - * @return {boolean} True if text input. - */ -Blockly.utils.isTargetInput = function(e) { - return e.target.type == 'textarea' || e.target.type == 'text' || - e.target.type == 'number' || e.target.type == 'email' || - e.target.type == 'password' || e.target.type == 'search' || - e.target.type == 'tel' || e.target.type == 'url' || - e.target.isContentEditable; -}; - -/** - * Return the coordinates of the top-left corner of this element relative to - * its parent. Only for SVG elements and children (e.g. rect, g, path). - * @param {!Element} element SVG element to find the coordinates of. - * @return {!goog.math.Coordinate} Object with .x and .y properties. - */ -Blockly.utils.getRelativeXY = function(element) { - var xy = new goog.math.Coordinate(0, 0); - // First, check for x and y attributes. - var x = element.getAttribute('x'); - if (x) { - xy.x = parseInt(x, 10); - } - var y = element.getAttribute('y'); - if (y) { - xy.y = parseInt(y, 10); - } - // Second, check for transform="translate(...)" attribute. - var transform = element.getAttribute('transform'); - var r = transform && transform.match(Blockly.utils.getRelativeXY.XY_REGEX_); - if (r) { - xy.x += parseFloat(r[1]); - if (r[3]) { - xy.y += parseFloat(r[3]); - } - } - - // Then check for style = transform: translate(...) or translate3d(...) - var style = element.getAttribute('style'); - if (style && style.indexOf('translate') > -1) { - var styleComponents = style.match(Blockly.utils.getRelativeXY.XY_STYLE_REGEX_); - if (styleComponents) { - xy.x += parseFloat(styleComponents[1]); - if (styleComponents[3]) { - xy.y += parseFloat(styleComponents[3]); - } - } - } - return xy; -}; - -/** - * Return the coordinates of the top-left corner of this element relative to - * the div blockly was injected into. - * @param {!Element} element SVG element to find the coordinates of. If this is - * not a child of the div blockly was injected into, the behaviour is - * undefined. - * @return {!goog.math.Coordinate} Object with .x and .y properties. - */ -Blockly.utils.getInjectionDivXY_ = function(element) { - var x = 0; - var y = 0; - while (element) { - var xy = Blockly.utils.getRelativeXY(element); - var scale = Blockly.utils.getScale_(element); - x = (x * scale) + xy.x; - y = (y * scale) + xy.y; - var classes = element.getAttribute('class') || ''; - if ((' ' + classes + ' ').indexOf(' injectionDiv ') != -1) { - break; - } - element = element.parentNode; - } - return new goog.math.Coordinate(x, y); -}; - -/** - * Return the scale of this element. - * @param {!Element} element The element to find the coordinates of. - * @return {!number} number represending the scale applied to the element. - * @private - */ -Blockly.utils.getScale_ = function(element) { - var scale = 1; - var transform = element.getAttribute('transform'); - if (transform) { - var transformComponents = - transform.match(Blockly.utils.getScale_.REGEXP_); - if (transformComponents && transformComponents[0]) { - scale = parseFloat(transformComponents[0]); - } - } - return scale; -}; - -/** - * Static regex to pull the x,y values out of an SVG translate() directive. - * Note that Firefox and IE (9,10) return 'translate(12)' instead of - * 'translate(12, 0)'. - * Note that IE (9,10) returns 'translate(16 8)' instead of 'translate(16, 8)'. - * Note that IE has been reported to return scientific notation (0.123456e-42). - * @type {!RegExp} - * @private - */ -Blockly.utils.getRelativeXY.XY_REGEX_ = - /translate\(\s*([-+\d.e]+)([ ,]\s*([-+\d.e]+)\s*)?/; - - -/** - * Static regex to pull the scale values out of a transform style property. - * Accounts for same exceptions as XY_REGEXP_. - * @type {!RegExp} - * @private - */ -Blockly.utils.getScale_REGEXP_ = /scale\(\s*([-+\d.e]+)\s*\)/; - -/** - * Static regex to pull the x,y values out of a translate3d() or translate3d() - * style property. - * Accounts for same exceptions as XY_REGEXP_. - * @type {!RegExp} - * @private - */ -Blockly.utils.getRelativeXY.XY_STYLE_REGEX_ = - /transform:\s*translate(?:3d)?\(\s*([-+\d.e]+)\s*px([ ,]\s*([-+\d.e]+)\s*px)?/; - -/** - * Helper method for creating SVG elements. - * @param {string} name Element's tag name. - * @param {!Object} attrs Dictionary of attribute names and values. - * @param {Element} parent Optional parent on which to append the element. - * @return {!SVGElement} Newly created SVG element. - */ -Blockly.utils.createSvgElement = function(name, attrs, parent /*, opt_workspace */) { - var e = /** @type {!SVGElement} */ - (document.createElementNS(Blockly.SVG_NS, name)); - for (var key in attrs) { - e.setAttribute(key, attrs[key]); - } - // IE defines a unique attribute "runtimeStyle", it is NOT applied to - // elements created with createElementNS. However, Closure checks for IE - // and assumes the presence of the attribute and crashes. - if (document.body.runtimeStyle) { // Indicates presence of IE-only attr. - e.runtimeStyle = e.currentStyle = e.style; - } - if (parent) { - parent.appendChild(e); - } - return e; -}; - -/** - * Is this event a right-click? - * @param {!Event} e Mouse event. - * @return {boolean} True if right-click. - */ -Blockly.utils.isRightButton = function(e) { - if (e.ctrlKey && goog.userAgent.MAC) { - // Control-clicking on Mac OS X is treated as a right-click. - // WebKit on Mac OS X fails to change button to 2 (but Gecko does). - return true; - } - return e.button == 2; -}; - -/** - * Return the converted coordinates of the given mouse event. - * The origin (0,0) is the top-left corner of the Blockly SVG. - * @param {!Event} e Mouse event. - * @param {!Element} svg SVG element. - * @param {SVGMatrix} matrix Inverted screen CTM to use. - * @return {!SVGPoint} Object with .x and .y properties. - */ -Blockly.utils.mouseToSvg = function(e, svg, matrix) { - var svgPoint = svg.createSVGPoint(); - svgPoint.x = e.clientX; - svgPoint.y = e.clientY; - - if (!matrix) { - matrix = svg.getScreenCTM().inverse(); - } - return svgPoint.matrixTransform(matrix); -}; - -/** - * Given an array of strings, return the length of the shortest one. - * @param {!Array.} array Array of strings. - * @return {number} Length of shortest string. - */ -Blockly.utils.shortestStringLength = function(array) { - if (!array.length) { - return 0; - } - return array.reduce(function(a, b) { - return a.length < b.length ? a : b; - }).length; -}; - -/** - * Given an array of strings, return the length of the common prefix. - * Words may not be split. Any space after a word is included in the length. - * @param {!Array.} array Array of strings. - * @param {number=} opt_shortest Length of shortest string. - * @return {number} Length of common prefix. - */ -Blockly.utils.commonWordPrefix = function(array, opt_shortest) { - if (!array.length) { - return 0; - } else if (array.length == 1) { - return array[0].length; - } - var wordPrefix = 0; - var max = opt_shortest || Blockly.utils.shortestStringLength(array); - for (var len = 0; len < max; len++) { - var letter = array[0][len]; - for (var i = 1; i < array.length; i++) { - if (letter != array[i][len]) { - return wordPrefix; - } - } - if (letter == ' ') { - wordPrefix = len + 1; - } - } - for (var i = 1; i < array.length; i++) { - var letter = array[i][len]; - if (letter && letter != ' ') { - return wordPrefix; - } - } - return max; -}; - -/** - * Given an array of strings, return the length of the common suffix. - * Words may not be split. Any space after a word is included in the length. - * @param {!Array.} array Array of strings. - * @param {number=} opt_shortest Length of shortest string. - * @return {number} Length of common suffix. - */ -Blockly.utils.commonWordSuffix = function(array, opt_shortest) { - if (!array.length) { - return 0; - } else if (array.length == 1) { - return array[0].length; - } - var wordPrefix = 0; - var max = opt_shortest || Blockly.utils.shortestStringLength(array); - for (var len = 0; len < max; len++) { - var letter = array[0].substr(-len - 1, 1); - for (var i = 1; i < array.length; i++) { - if (letter != array[i].substr(-len - 1, 1)) { - return wordPrefix; - } - } - if (letter == ' ') { - wordPrefix = len + 1; - } - } - for (var i = 1; i < array.length; i++) { - var letter = array[i].charAt(array[i].length - len - 1); - if (letter && letter != ' ') { - return wordPrefix; - } - } - return max; -}; - -/** - * Parse a string with any number of interpolation tokens (%1, %2, ...). - * It will also replace string table references (e.g., %{bky_my_msg} and - * %{BKY_MY_MSG} will both be replaced with the value in - * Blockly.Msg['MY_MSG']). Percentage sign characters '%' may be self-escaped - * (e.g., '%%'). - * @param {string} message Text which might contain string table references and - * interpolation tokens. - * @return {!Array.} Array of strings and numbers. - */ -Blockly.utils.tokenizeInterpolation = function(message) { - return Blockly.utils.tokenizeInterpolation_(message, true); -}; - -/** - * Replaces string table references in a message, if the message is a string. - * For example, "%{bky_my_msg}" and "%{BKY_MY_MSG}" will both be replaced with - * the value in Blockly.Msg['MY_MSG']. - * @param {string|?} message Message, which may be a string that contains - * string table references. - * @return {!string} String with message references replaced. - */ -Blockly.utils.replaceMessageReferences = function(message) { - if (!goog.isString(message)) { - return message; - } - var interpolatedResult = Blockly.utils.tokenizeInterpolation_(message, false); - // When parseInterpolationTokens == false, interpolatedResult should be at - // most length 1. - return interpolatedResult.length ? interpolatedResult[0] : ''; -}; - -/** - * Validates that any %{BKY_...} references in the message refer to keys of - * the Blockly.Msg string table. - * @param {string} message Text which might contain string table references. - * @return {boolean} True if all message references have matching values. - * Otherwise, false. - */ -Blockly.utils.checkMessageReferences = function(message) { - var isValid = true; // True until a bad reference is found. - - var regex = /%{BKY_([a-zA-Z][a-zA-Z0-9_]*)}/g; - var match = regex.exec(message); - while (match) { - var msgKey = match[1]; - if (Blockly.utils.getMessageArray_()[msgKey] == undefined) { - console.log('WARNING: No message string for %{BKY_' + msgKey + '}.'); - isValid = false; - } - - // Re-run on remainder of string. - message = message.substring(match.index + msgKey.length + 1); - match = regex.exec(message); - } - - return isValid; -}; - -/** - * Internal implementation of the message reference and interpolation token - * parsing used by tokenizeInterpolation() and replaceMessageReferences(). - * @param {string} message Text which might contain string table references and - * interpolation tokens. - * @param {boolean} parseInterpolationTokens Option to parse numeric - * interpolation tokens (%1, %2, ...) when true. - * @return {!Array.} Array of strings and numbers. - * @private - */ -Blockly.utils.tokenizeInterpolation_ = function(message, - parseInterpolationTokens) { - var tokens = []; - var chars = message.split(''); - chars.push(''); // End marker. - // Parse the message with a finite state machine. - // 0 - Base case. - // 1 - % found. - // 2 - Digit found. - // 3 - Message ref found. - var state = 0; - var buffer = []; - var number = null; - for (var i = 0; i < chars.length; i++) { - var c = chars[i]; - if (state == 0) { - if (c == '%') { - var text = buffer.join(''); - if (text) { - tokens.push(text); - } - buffer.length = 0; - state = 1; // Start escape. - } else { - buffer.push(c); // Regular char. - } - } else if (state == 1) { - if (c == '%') { - buffer.push(c); // Escaped %: %% - state = 0; - } else if (parseInterpolationTokens && '0' <= c && c <= '9') { - state = 2; - number = c; - var text = buffer.join(''); - if (text) { - tokens.push(text); - } - buffer.length = 0; - } else if (c == '{') { - state = 3; - } else { - buffer.push('%', c); // Not recognized. Return as literal. - state = 0; - } - } else if (state == 2) { - if ('0' <= c && c <= '9') { - number += c; // Multi-digit number. - } else { - tokens.push(parseInt(number, 10)); - i--; // Parse this char again. - state = 0; - } - } else if (state == 3) { // String table reference - if (c == '') { - // Premature end before closing '}' - buffer.splice(0, 0, '%{'); // Re-insert leading delimiter - i--; // Parse this char again. - state = 0; // and parse as string literal. - } else if (c != '}') { - buffer.push(c); - } else { - var rawKey = buffer.join(''); - if (/[a-zA-Z][a-zA-Z0-9_]*/.test(rawKey)) { // Strict matching - // Found a valid string key. Attempt case insensitive match. - var keyUpper = rawKey.toUpperCase(); - - // BKY_ is the prefix used to namespace the strings used in Blockly - // core files and the predefined blocks in ../blocks/. These strings - // are defined in ../msgs/ files. - var bklyKey = goog.string.startsWith(keyUpper, 'BKY_') ? - keyUpper.substring(4) : null; - if (bklyKey && bklyKey in Blockly.Msg) { - var rawValue = Blockly.Msg[bklyKey]; - if (goog.isString(rawValue)) { - // Attempt to dereference substrings, too, appending to the end. - Array.prototype.push.apply(tokens, - Blockly.utils.tokenizeInterpolation(rawValue)); - } else if (parseInterpolationTokens) { - // When parsing interpolation tokens, numbers are special - // placeholders (%1, %2, etc). Make sure all other values are - // strings. - tokens.push(String(rawValue)); - } else { - tokens.push(rawValue); - } - } else { - // No entry found in the string table. Pass reference as string. - tokens.push('%{' + rawKey + '}'); - } - buffer.length = 0; // Clear the array - state = 0; - } else { - tokens.push('%{' + rawKey + '}'); - buffer.length = 0; - state = 0; // and parse as string literal. - } - } - } - } - var text = buffer.join(''); - if (text) { - tokens.push(text); - } - - // Merge adjacent text tokens into a single string. - var mergedTokens = []; - buffer.length = 0; - for (var i = 0; i < tokens.length; ++i) { - if (typeof tokens[i] == 'string') { - buffer.push(tokens[i]); - } else { - text = buffer.join(''); - if (text) { - mergedTokens.push(text); - } - buffer.length = 0; - mergedTokens.push(tokens[i]); - } - } - text = buffer.join(''); - if (text) { - mergedTokens.push(text); - } - buffer.length = 0; - - return mergedTokens; -}; - -/** - * Generate a unique ID. This should be globally unique. - * 87 characters ^ 20 length > 128 bits (better than a UUID). - * @return {string} A globally unique ID string. - */ -Blockly.utils.genUid = function() { - var length = 20; - var soupLength = Blockly.utils.genUid.soup_.length; - var id = []; - for (var i = 0; i < length; i++) { - id[i] = Blockly.utils.genUid.soup_.charAt(Math.random() * soupLength); - } - return id.join(''); -}; - -/** - * Legal characters for the unique ID. Should be all on a US keyboard. - * No characters that conflict with XML or JSON. Requests to remove additional - * 'problematic' characters from this soup will be denied. That's your failure - * to properly escape in your own environment. Issues #251, #625, #682, #1304. - * @private - */ -Blockly.utils.genUid.soup_ = '!#$%()*+,-./:;=?@[]^_`{|}~' + - 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; - -/** - * Wrap text to the specified width. - * @param {string} text Text to wrap. - * @param {number} limit Width to wrap each line. - * @return {string} Wrapped text. - */ -Blockly.utils.wrap = function(text, limit) { - var lines = text.split('\n'); - for (var i = 0; i < lines.length; i++) { - lines[i] = Blockly.utils.wrapLine_(lines[i], limit); - } - return lines.join('\n'); -}; - -/** - * Wrap single line of text to the specified width. - * @param {string} text Text to wrap. - * @param {number} limit Width to wrap each line. - * @return {string} Wrapped text. - * @private - */ -Blockly.utils.wrapLine_ = function(text, limit) { - if (text.length <= limit) { - // Short text, no need to wrap. - return text; - } - // Split the text into words. - var words = text.trim().split(/\s+/); - // Set limit to be the length of the largest word. - for (var i = 0; i < words.length; i++) { - if (words[i].length > limit) { - limit = words[i].length; - } - } - - var lastScore; - var score = -Infinity; - var lastText; - var lineCount = 1; - do { - lastScore = score; - lastText = text; - // Create a list of booleans representing if a space (false) or - // a break (true) appears after each word. - var wordBreaks = []; - // Seed the list with evenly spaced linebreaks. - var steps = words.length / lineCount; - var insertedBreaks = 1; - for (var i = 0; i < words.length - 1; i++) { - if (insertedBreaks < (i + 1.5) / steps) { - insertedBreaks++; - wordBreaks[i] = true; - } else { - wordBreaks[i] = false; - } - } - wordBreaks = Blockly.utils.wrapMutate_(words, wordBreaks, limit); - score = Blockly.utils.wrapScore_(words, wordBreaks, limit); - text = Blockly.utils.wrapToText_(words, wordBreaks); - lineCount++; - } while (score > lastScore); - return lastText; -}; - -/** - * Compute a score for how good the wrapping is. - * @param {!Array.} words Array of each word. - * @param {!Array.} wordBreaks Array of line breaks. - * @param {number} limit Width to wrap each line. - * @return {number} Larger the better. - * @private - */ -Blockly.utils.wrapScore_ = function(words, wordBreaks, limit) { - // If this function becomes a performance liability, add caching. - // Compute the length of each line. - var lineLengths = [0]; - var linePunctuation = []; - for (var i = 0; i < words.length; i++) { - lineLengths[lineLengths.length - 1] += words[i].length; - if (wordBreaks[i] === true) { - lineLengths.push(0); - linePunctuation.push(words[i].charAt(words[i].length - 1)); - } else if (wordBreaks[i] === false) { - lineLengths[lineLengths.length - 1]++; - } - } - var maxLength = Math.max.apply(Math, lineLengths); - - var score = 0; - for (var i = 0; i < lineLengths.length; i++) { - // Optimize for width. - // -2 points per char over limit (scaled to the power of 1.5). - score -= Math.pow(Math.abs(limit - lineLengths[i]), 1.5) * 2; - // Optimize for even lines. - // -1 point per char smaller than max (scaled to the power of 1.5). - score -= Math.pow(maxLength - lineLengths[i], 1.5); - // Optimize for structure. - // Add score to line endings after punctuation. - if ('.?!'.indexOf(linePunctuation[i]) != -1) { - score += limit / 3; - } else if (',;)]}'.indexOf(linePunctuation[i]) != -1) { - score += limit / 4; - } - } - // All else being equal, the last line should not be longer than the - // previous line. For example, this looks wrong: - // aaa bbb - // ccc ddd eee - if (lineLengths.length > 1 && lineLengths[lineLengths.length - 1] <= - lineLengths[lineLengths.length - 2]) { - score += 0.5; - } - return score; -}; - -/** - * Mutate the array of line break locations until an optimal solution is found. - * No line breaks are added or deleted, they are simply moved around. - * @param {!Array.} words Array of each word. - * @param {!Array.} wordBreaks Array of line breaks. - * @param {number} limit Width to wrap each line. - * @return {!Array.} New array of optimal line breaks. - * @private - */ -Blockly.utils.wrapMutate_ = function(words, wordBreaks, limit) { - var bestScore = Blockly.utils.wrapScore_(words, wordBreaks, limit); - var bestBreaks; - // Try shifting every line break forward or backward. - for (var i = 0; i < wordBreaks.length - 1; i++) { - if (wordBreaks[i] == wordBreaks[i + 1]) { - continue; - } - var mutatedWordBreaks = [].concat(wordBreaks); - mutatedWordBreaks[i] = !mutatedWordBreaks[i]; - mutatedWordBreaks[i + 1] = !mutatedWordBreaks[i + 1]; - var mutatedScore = - Blockly.utils.wrapScore_(words, mutatedWordBreaks, limit); - if (mutatedScore > bestScore) { - bestScore = mutatedScore; - bestBreaks = mutatedWordBreaks; - } - } - if (bestBreaks) { - // Found an improvement. See if it may be improved further. - return Blockly.utils.wrapMutate_(words, bestBreaks, limit); - } - // No improvements found. Done. - return wordBreaks; -}; - -/** - * Reassemble the array of words into text, with the specified line breaks. - * @param {!Array.} words Array of each word. - * @param {!Array.} wordBreaks Array of line breaks. - * @return {string} Plain text. - * @private - */ -Blockly.utils.wrapToText_ = function(words, wordBreaks) { - var text = []; - for (var i = 0; i < words.length; i++) { - text.push(words[i]); - if (wordBreaks[i] !== undefined) { - text.push(wordBreaks[i] ? '\n' : ' '); - } - } - return text.join(''); -}; - -/** - * Check if 3D transforms are supported by adding an element - * and attempting to set the property. - * @return {boolean} true if 3D transforms are supported. - */ -Blockly.utils.is3dSupported = function() { - if (Blockly.utils.is3dSupported.cached_ !== undefined) { - return Blockly.utils.is3dSupported.cached_; - } - // CC-BY-SA Lorenzo Polidori - // stackoverflow.com/questions/5661671/detecting-transform-translate3d-support - if (!goog.global.getComputedStyle) { - return false; - } - - var el = document.createElement('p'); - var has3d = 'none'; - var transforms = { - 'webkitTransform': '-webkit-transform', - 'OTransform': '-o-transform', - 'msTransform': '-ms-transform', - 'MozTransform': '-moz-transform', - 'transform': 'transform' - }; - - // Add it to the body to get the computed style. - document.body.insertBefore(el, null); - - for (var t in transforms) { - if (el.style[t] !== undefined) { - el.style[t] = 'translate3d(1px,1px,1px)'; - var computedStyle = goog.global.getComputedStyle(el); - if (!computedStyle) { - // getComputedStyle in Firefox returns null when blockly is loaded - // inside an iframe with display: none. Returning false and not - // caching is3dSupported means we try again later. This is most likely - // when users are interacting with blocks which should mean blockly is - // visible again. - // See https://bugzilla.mozilla.org/show_bug.cgi?id=548397 - document.body.removeChild(el); - return false; - } - has3d = computedStyle.getPropertyValue(transforms[t]); - } - } - document.body.removeChild(el); - Blockly.utils.is3dSupported.cached_ = has3d !== 'none'; - return Blockly.utils.is3dSupported.cached_; -}; - -/** - * Insert a node after a reference node. - * Contrast with node.insertBefore function. - * @param {!Element} newNode New element to insert. - * @param {!Element} refNode Existing element to precede new node. - * @package - */ -Blockly.utils.insertAfter = function(newNode, refNode) { - var siblingNode = refNode.nextSibling; - var parentNode = refNode.parentNode; - if (!parentNode) { - throw 'Reference node has no parent.'; - } - if (siblingNode) { - parentNode.insertBefore(newNode, siblingNode); - } else { - parentNode.appendChild(newNode); - } -}; - -/** - * Calls a function after the page has loaded, possibly immediately. - * @param {function()} fn Function to run. - * @throws Error Will throw if no global document can be found (e.g., Node.js). - */ -Blockly.utils.runAfterPageLoad = function(fn) { - if (!document) { - throw new Error('Blockly.utils.runAfterPageLoad() requires browser document.'); - } - if (document.readyState === 'complete') { - fn(); // Page has already loaded. Call immediately. - } else { - // Poll readyState. - var readyStateCheckInterval = setInterval(function() { - if (document.readyState === 'complete') { - clearInterval(readyStateCheckInterval); - fn(); - } - }, 10); - } -}; - -/** - * Sets the CSS transform property on an element. This function sets the - * non-vendor-prefixed and vendor-prefixed versions for backwards compatibility - * with older browsers. See http://caniuse.com/#feat=transforms2d - * @param {!Element} node The node which the CSS transform should be applied. - * @param {string} transform The value of the CSS `transform` property. - */ -Blockly.utils.setCssTransform = function(node, transform) { - node.style['transform'] = transform; - node.style['-webkit-transform'] = transform; -}; - -/** - * Get the position of the current viewport in window coordinates. This takes - * scroll into account. - * @return {!Object} an object containing window width, height, and scroll - * position in window coordinates. - * @package - */ -Blockly.utils.getViewportBBox = function() { - // Pixels. - var windowSize = goog.dom.getViewportSize(); - // Pixels, in window coordinates. - var scrollOffset = goog.style.getViewportPageOffset(document); - return { - right: windowSize.width + scrollOffset.x, - bottom: windowSize.height + scrollOffset.y, - top: scrollOffset.y, - left: scrollOffset.x - }; -}; - -/** - * Fast prefix-checker. - * Copied from Closure's goog.string.startsWith. - * @param {string} str The string to check. - * @param {string} prefix A string to look for at the start of `str`. - * @return {boolean} True if `str` begins with `prefix`. - * @package - */ -Blockly.utils.startsWith = function(str, prefix) { - return str.lastIndexOf(prefix, 0) == 0; -}; - -/** - * Converts degrees to radians. - * Copied from Closure's goog.math.toRadians. - * @param {number} angleDegrees Angle in degrees. - * @return {number} Angle in radians. - * @package - */ -Blockly.utils.toRadians = function(angleDegrees) { - return angleDegrees * Math.PI / 180; -}; diff --git a/core/variable_events.js b/core/variable_events.js deleted file mode 100644 index 0dcabce7e1..0000000000 --- a/core/variable_events.js +++ /dev/null @@ -1,259 +0,0 @@ -/** - * @license - * Visual Blocks Editor - * - * Copyright 2018 Google Inc. - * https://developers.google.com/blockly/ - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @fileoverview Classes for all types of variable events. - * @author fenichel@google.com (Rachel Fenichel) - */ -'use strict'; - -goog.provide('Blockly.Events.VarBase'); -goog.provide('Blockly.Events.VarCreate'); -goog.provide('Blockly.Events.VarDelete'); -goog.provide('Blockly.Events.VarRename'); - -goog.require('Blockly.Events'); -goog.require('Blockly.Events.Abstract'); - -goog.require('goog.array'); -goog.require('goog.math.Coordinate'); - - -/** - * Abstract class for a variable event. - * @param {Blockly.VariableModel} variable The variable this event corresponds - * to. - * @extends {Blockly.Events.Abstract} - * @constructor - */ -Blockly.Events.VarBase = function(variable) { - Blockly.Events.VarBase.superClass_.constructor.call(this); - - /** - * The variable id for the variable this event pertains to. - * @type {string} - */ - this.varId = variable.getId(); - this.workspaceId = variable.workspace.id; -}; -goog.inherits(Blockly.Events.VarBase, Blockly.Events.Abstract); - -/** - * Encode the event as JSON. - * @return {!Object} JSON representation. - */ -Blockly.Events.VarBase.prototype.toJson = function() { - var json = Blockly.Events.VarBase.superClass_.toJson.call(this); - json['varId'] = this.varId; - return json; -}; - -/** - * Decode the JSON event. - * @param {!Object} json JSON representation. - */ -Blockly.Events.VarBase.prototype.fromJson = function(json) { - Blockly.Events.VarBase.superClass_.toJson.call(this); - this.varId = json['varId']; -}; - -/** - * Class for a variable creation event. - * @param {Blockly.VariableModel} variable The created variable. - * Null for a blank event. - * @extends {Blockly.Events.VarBase} - * @constructor - */ -Blockly.Events.VarCreate = function(variable) { - if (!variable) { - return; // Blank event to be populated by fromJson. - } - Blockly.Events.VarCreate.superClass_.constructor.call(this, variable); - this.varType = variable.type; - this.varName = variable.name; - this.isLocal = variable.isLocal; - this.isCloud = variable.isCloud; -}; -goog.inherits(Blockly.Events.VarCreate, Blockly.Events.VarBase); - -/** - * Type of this event. - * @type {string} - */ -Blockly.Events.VarCreate.prototype.type = Blockly.Events.VAR_CREATE; - -/** - * Encode the event as JSON. - * @return {!Object} JSON representation. - */ -Blockly.Events.VarCreate.prototype.toJson = function() { - var json = Blockly.Events.VarCreate.superClass_.toJson.call(this); - json['varType'] = this.varType; - json['varName'] = this.varName; - json['isLocal'] = this.isLocal; - json['isCloud'] = this.isCloud; - return json; -}; - -/** - * Decode the JSON event. - * @param {!Object} json JSON representation. - */ -Blockly.Events.VarCreate.prototype.fromJson = function(json) { - Blockly.Events.VarCreate.superClass_.fromJson.call(this, json); - this.varType = json['varType']; - this.varName = json['varName']; - this.isLocal = json['isLocal']; - this.isCloud = json['isCloud']; -}; - -/** - * Run a variable creation event. - * @param {boolean} forward True if run forward, false if run backward (undo). - */ -Blockly.Events.VarCreate.prototype.run = function(forward) { - var workspace = this.getEventWorkspace_(); - if (forward) { - workspace.createVariable(this.varName, this.varType, this.varId, this.isLocal, this.isCloud); - } else { - workspace.deleteVariableById(this.varId); - } -}; - -/** - * Class for a variable deletion event. - * @param {Blockly.VariableModel} variable The deleted variable. - * Null for a blank event. - * @extends {Blockly.Events.VarBase} - * @constructor - */ -Blockly.Events.VarDelete = function(variable) { - if (!variable) { - return; // Blank event to be populated by fromJson. - } - Blockly.Events.VarDelete.superClass_.constructor.call(this, variable); - this.varType = variable.type; - this.varName = variable.name; - this.isLocal = variable.isLocal; - this.isCloud = variable.isCloud; -}; -goog.inherits(Blockly.Events.VarDelete, Blockly.Events.VarBase); - -/** - * Type of this event. - * @type {string} - */ -Blockly.Events.VarDelete.prototype.type = Blockly.Events.VAR_DELETE; - -/** - * Encode the event as JSON. - * @return {!Object} JSON representation. - */ -Blockly.Events.VarDelete.prototype.toJson = function() { - var json = Blockly.Events.VarDelete.superClass_.toJson.call(this); - json['varType'] = this.varType; - json['varName'] = this.varName; - json['isLocal'] = this.isLocal; - json['isCloud'] = this.isCloud; - return json; -}; - -/** - * Decode the JSON event. - * @param {!Object} json JSON representation. - */ -Blockly.Events.VarDelete.prototype.fromJson = function(json) { - Blockly.Events.VarDelete.superClass_.fromJson.call(this, json); - this.varType = json['varType']; - this.varName = json['varName']; - this.isLocal = json['isLocal']; - this.isCloud = json['isCloud']; -}; - -/** - * Run a variable deletion event. - * @param {boolean} forward True if run forward, false if run backward (undo). - */ -Blockly.Events.VarDelete.prototype.run = function(forward) { - var workspace = this.getEventWorkspace_(); - if (forward) { - workspace.deleteVariableById(this.varId); - } else { - workspace.createVariable(this.varName, this.varType, this.varId, this.isLocal, this.isCloud); - } -}; - -/** - * Class for a variable rename event. - * @param {Blockly.VariableModel} variable The renamed variable. - * Null for a blank event. - * @param {string} newName The new name the variable will be changed to. - * @extends {Blockly.Events.VarBase} - * @constructor - */ -Blockly.Events.VarRename = function(variable, newName) { - if (!variable) { - return; // Blank event to be populated by fromJson. - } - Blockly.Events.VarRename.superClass_.constructor.call(this, variable); - this.oldName = variable.name; - this.newName = newName; -}; -goog.inherits(Blockly.Events.VarRename, Blockly.Events.VarBase); - -/** - * Type of this event. - * @type {string} - */ -Blockly.Events.VarRename.prototype.type = Blockly.Events.VAR_RENAME; - -/** - * Encode the event as JSON. - * @return {!Object} JSON representation. - */ -Blockly.Events.VarRename.prototype.toJson = function() { - var json = Blockly.Events.VarRename.superClass_.toJson.call(this); - json['oldName'] = this.oldName; - json['newName'] = this.newName; - return json; -}; - -/** - * Decode the JSON event. - * @param {!Object} json JSON representation. - */ -Blockly.Events.VarRename.prototype.fromJson = function(json) { - Blockly.Events.VarRename.superClass_.fromJson.call(this, json); - this.oldName = json['oldName']; - this.newName = json['newName']; -}; - -/** - * Run a variable rename event. - * @param {boolean} forward True if run forward, false if run backward (undo). - */ -Blockly.Events.VarRename.prototype.run = function(forward) { - var workspace = this.getEventWorkspace_(); - if (forward) { - workspace.renameVariableById(this.varId, this.newName); - } else { - workspace.renameVariableById(this.varId, this.oldName); - } -}; diff --git a/core/variable_map.js b/core/variable_map.js deleted file mode 100644 index f391c0938b..0000000000 --- a/core/variable_map.js +++ /dev/null @@ -1,415 +0,0 @@ -/** - * @license - * Visual Blocks Editor - * - * Copyright 2017 Google Inc. - * https://developers.google.com/blockly/ - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @fileoverview Object representing a map of variables and their types. - * @author marisaleung@google.com (Marisa Leung) - */ -'use strict'; - -goog.provide('Blockly.VariableMap'); - -goog.require('Blockly.Events.VarDelete'); -goog.require('Blockly.Events.VarRename'); -goog.require('Blockly.VariableModel'); - - -/** - * Class for a variable map. This contains a dictionary data structure with - * variable types as keys and lists of variables as values. The list of - * variables are the type indicated by the key. - * @param {!Blockly.Workspace} workspace The workspace this map belongs to. - * @constructor - */ -Blockly.VariableMap = function(workspace) { - /** - * A map from variable type to list of variable names. The lists contain all - * of the named variables in the workspace, including variables - * that are not currently in use. - * @type {!Object.>} - * @private - */ - this.variableMap_ = {}; - - /** - * The workspace this map belongs to. - * @type {!Blockly.Workspace} - */ - this.workspace = workspace; -}; - -/** - * Clear the variable map. - */ -Blockly.VariableMap.prototype.clear = function() { - this.variableMap_ = new Object(null); -}; - -/* Begin functions for renaming variables. */ - -/** - * Rename the given variable by updating its name in the variable map. - * @param {!Blockly.VariableModel} variable Variable to rename. - * @param {string} newName New variable name. - * @package - */ -Blockly.VariableMap.prototype.renameVariable = function(variable, newName) { - var type = variable.type; - var conflictVar = this.getVariable(newName, type); - var blocks = this.workspace.getAllBlocks(); - Blockly.Events.setGroup(true); - try { - if (!conflictVar) { - this.renameVariableAndUses_(variable, newName, blocks); - } else { - // We don't want to rename the variable if one with the exact new name - // already exists. - console.warn('Unexpected conflict when attempting to rename ' + - 'variable with name: ' + variable.name + ' and id: ' + variable.getId() + - ' to new name: ' + newName + '. A variable with the new name already exists' + - ' and has id: ' + conflictVar.getId()); - - } - } finally { - Blockly.Events.setGroup(false); - } -}; - -/** - * Rename a variable by updating its name in the variable map. Identify the - * variable to rename with the given ID. - * @param {string} id ID of the variable to rename. - * @param {string} newName New variable name. - */ -Blockly.VariableMap.prototype.renameVariableById = function(id, newName) { - var variable = this.getVariableById(id); - if (!variable) { - throw new Error('Tried to rename a variable that didn\'t exist. ID: ' + id); - } - - this.renameVariable(variable, newName); -}; - -/** - * Update the name of the given variable and refresh all references to it. - * The new name must not conflict with any existing variable names. - * @param {!Blockly.VariableModel} variable Variable to rename. - * @param {string} newName New variable name. - * @param {!Array.} blocks The list of all blocks in the - * workspace. - * @private - */ -Blockly.VariableMap.prototype.renameVariableAndUses_ = function(variable, - newName, blocks) { - Blockly.Events.fire(new Blockly.Events.VarRename(variable, newName)); - variable.name = newName; - for (var i = 0; i < blocks.length; i++) { - blocks[i].updateVarName(variable); - } -}; - -/** - * Update the name of the given variable to the same name as an existing - * variable. The two variables are coalesced into a single variable with the ID - * of the existing variable that was already using newName. - * Refresh all references to the variable. - * @param {!Blockly.VariableModel} variable Variable to rename. - * @param {string} newName New variable name. - * @param {!Blockly.VariableModel} conflictVar The variable that was already - * using newName. - * @param {!Array.} blocks The list of all blocks in the - * workspace. - * @private - */ -Blockly.VariableMap.prototype.renameVariableWithConflict_ = function(variable, - newName, conflictVar, blocks) { - var type = variable.type; - var oldCase = conflictVar.name; - - if (newName != oldCase) { - // Simple rename to change the case and update references. - this.renameVariableAndUses_(conflictVar, newName, blocks); - } - - // These blocks now refer to a different variable. - // These will fire change events. - for (var i = 0; i < blocks.length; i++) { - blocks[i].renameVarById(variable.getId(), conflictVar.getId()); - } - - // Finally delete the original variable, which is now unreferenced. - Blockly.Events.fire(new Blockly.Events.VarDelete(variable)); - // And remove it from the list. - var variableList = this.getVariablesOfType(type); - var variableIndex = variableList.indexOf(variable); - this.variableMap_[type].splice(variableIndex, 1); - -}; - -/* End functions for renaming variabless. */ - -/** - * Create a variable with a given name, optional type, and optional id. - * @param {!string} name The name of the variable. This must be unique across - * each variable type. - * @param {?string} opt_type The type of the variable like 'int' or 'string'. - * Does not need to be unique. Field_variable can filter variables based on - * their type. This will default to '' which is a specific type. - * @param {string=} opt_id The unique ID of the variable. This will default to - * a UUID. - * @param {boolean=} opt_isLocal Whether the variable is locally scoped. - * @param {boolean=} opt_isCloud Whether the variable is a cloud variable. - * @return {?Blockly.VariableModel} The newly created variable. - */ -Blockly.VariableMap.prototype.createVariable = function(name, - opt_type, opt_id, opt_isLocal, opt_isCloud) { - var variable = this.getVariable(name, opt_type); - if (variable) { - if (opt_id && variable.getId() != opt_id) { - // There is a variable conflict. Variable conflicts should be eliminated - // in the scratch-vm, or before we get to this point, - // so log a warning, because throwing an error crashes projects. - console.warn('Variable "' + name + '" is already in use and its id is "' - + variable.getId() + '" which conflicts with the passed in ' + - 'id, "' + opt_id + '".'); - } - // The variable already exists and has the same ID. - return variable; - } - if (opt_id) { - variable = this.getVariableById(opt_id); - if (variable) { - console.warn('Variable id, "' + opt_id + '", is already in use.'); - return variable; - } - } - opt_id = opt_id || Blockly.utils.genUid(); - opt_type = opt_type || ''; - - variable = new Blockly.VariableModel(this.workspace, name, opt_type, opt_id, - opt_isLocal, opt_isCloud); - // If opt_type is not a key, create a new list. - if (!this.variableMap_[opt_type]) { - this.variableMap_[opt_type] = [variable]; - } else { - // Else append the variable to the preexisting list. - this.variableMap_[opt_type].push(variable); - } - return variable; -}; - -/* Begin functions for variable deletion. */ - -/** - * Delete a variable. - * @param {Blockly.VariableModel} variable Variable to delete. - */ -Blockly.VariableMap.prototype.deleteVariable = function(variable) { - var variableList = this.variableMap_[variable.type]; - for (var i = 0, tempVar; tempVar = variableList[i]; i++) { - if (tempVar.getId() == variable.getId()) { - variableList.splice(i, 1); - Blockly.Events.fire(new Blockly.Events.VarDelete(variable)); - return; - } - } -}; - -/** - * Delete a variable and all of its uses from this workspace by the passed - * in ID. May prompt the user for confirmation. - * @param {string} id ID of variable to delete. - */ -Blockly.VariableMap.prototype.deleteVariableById = function(id) { - var variable = this.getVariableById(id); - if (variable) { - // Check whether this variable is a function parameter before deleting. - var variableName = variable.name; - var uses = this.getVariableUsesById(id); - for (var i = 0, block; block = uses[i]; i++) { - if (block.type == Blockly.PROCEDURES_DEFINITION_BLOCK_TYPE || - block.type == 'procedures_defreturn') { - var procedureName = block.getFieldValue('NAME'); - var deleteText = Blockly.Msg.CANNOT_DELETE_VARIABLE_PROCEDURE. - replace('%1', variableName). - replace('%2', procedureName); - Blockly.alert(deleteText); - return; - } - } - - var map = this; - if (uses.length > 1) { - // Confirm before deleting multiple blocks. - var confirmText = Blockly.Msg.DELETE_VARIABLE_CONFIRMATION. - replace('%1', String(uses.length)). - replace('%2', variableName); - Blockly.confirm(confirmText, - function(ok) { - if (ok) { - map.deleteVariableInternal_(variable, uses); - } - }); - } else { - // No confirmation necessary for a single block. - map.deleteVariableInternal_(variable, uses); - } - } else { - console.warn("Can't delete non-existent variable: " + id); - } -}; - -/** - * Deletes a variable and all of its uses from this workspace without asking the - * user for confirmation. - * @param {!Blockly.VariableModel} variable Variable to delete. - * @param {!Array.} uses An array of uses of the variable. - * @private - */ -Blockly.VariableMap.prototype.deleteVariableInternal_ = function(variable, - uses) { - var existingGroup = Blockly.Events.getGroup(); - if (!existingGroup) { - Blockly.Events.setGroup(true); - } - try { - for (var i = 0; i < uses.length; i++) { - uses[i].dispose(true, false); - } - this.deleteVariable(variable); - } finally { - if (!existingGroup) { - Blockly.Events.setGroup(false); - } - } -}; - -/* End functions for variable deletion. */ - -/** - * Find the variable by the given name and type and return it. Return null if - * it is not found. - * @param {string} name The name to check for. - * @param {string=} opt_type The type of the variable. If not provided it - * defaults to the empty string, which is a specific type. - * @return {Blockly.VariableModel} The variable with the given name, or null if - * it was not found. - */ -Blockly.VariableMap.prototype.getVariable = function(name, opt_type) { - var type = opt_type || ''; - var list = this.variableMap_[type]; - if (list) { - for (var j = 0, variable; variable = list[j]; j++) { - if (variable.name == name) { - return variable; - } - } - } - return null; -}; - -/** - * Find the variable by the given ID and return it. Return null if it is not - * found. - * @param {!string} id The id to check for. - * @return {?Blockly.VariableModel} The variable with the given id. - */ -Blockly.VariableMap.prototype.getVariableById = function(id) { - var keys = Object.keys(this.variableMap_); - for (var i = 0; i < keys.length; i++ ) { - var key = keys[i]; - for (var j = 0, variable; variable = this.variableMap_[key][j]; j++) { - if (variable.getId() == id) { - return variable; - } - } - } - return null; -}; - -/** - * Get a list containing all of the variables of a specified type. If type is - * null, return list of variables with empty string type. - * @param {?string} type Type of the variables to find. - * @return {!Array.} The sought after variables of the - * passed in type. An empty array if none are found. - */ -Blockly.VariableMap.prototype.getVariablesOfType = function(type) { - type = type || ''; - var variable_list = this.variableMap_[type]; - if (variable_list) { - return variable_list.slice(); - } - return []; -}; - -/** - * Return all variable types. This list always contains the empty string. - * @return {!Array.} List of variable types. - * @package - */ -Blockly.VariableMap.prototype.getVariableTypes = function() { - var types = Object.keys(this.variableMap_); - var hasEmpty = false; - for (var i = 0; i < types.length; i++) { - if (types[i] == '') { - hasEmpty = true; - } - } - if (!hasEmpty) { - types.push(''); - } - return types; -}; - -/** - * Return all variables of all types. - * @return {!Array.} List of variable models. - */ -Blockly.VariableMap.prototype.getAllVariables = function() { - var all_variables = []; - var keys = Object.keys(this.variableMap_); - for (var i = 0; i < keys.length; i++ ) { - all_variables = all_variables.concat(this.variableMap_[keys[i]]); - } - return all_variables; -}; - -/** - * Find all the uses of a named variable. - * @param {string} id ID of the variable to find. - * @return {!Array.} Array of block usages. - */ -Blockly.VariableMap.prototype.getVariableUsesById = function(id) { - var uses = []; - var blocks = this.workspace.getAllBlocks(); - // Iterate through every block and check the name. - for (var i = 0; i < blocks.length; i++) { - var blockVariables = blocks[i].getVarModels(); - if (blockVariables) { - for (var j = 0; j < blockVariables.length; j++) { - if (blockVariables[j].getId() == id) { - uses.push(blocks[i]); - } - } - } - } - return uses; -}; diff --git a/core/variable_model.js b/core/variable_model.js deleted file mode 100644 index 4c62d8c624..0000000000 --- a/core/variable_model.js +++ /dev/null @@ -1,116 +0,0 @@ -/** - * @license - * Visual Blocks Editor - * - * Copyright 2017 Google Inc. - * https://developers.google.com/blockly/ - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @fileoverview Components for the variable model. - * @author marisaleung@google.com (Marisa Leung) - */ -'use strict'; - -goog.provide('Blockly.VariableModel'); - -goog.require('Blockly.Events.VarCreate'); - -goog.require('goog.string'); - - -/** - * Class for a variable model. - * Holds information for the variable including name, ID, and type. - * @param {!Blockly.Workspace} workspace The variable's workspace. - * @param {!string} name The name of the variable. This must be unique across - * each variable type. - * @param {?string} opt_type The type of the variable like 'int' or 'string'. - * Does not need to be unique. Field_variable can filter variables based on - * their type. This will default to '' which is a specific type. - * @param {string=} opt_id The unique ID of the variable. This will default to - * a UUID. - * @param {boolean=} opt_isLocal Whether the variable is locally scoped. - * @param {boolean=} opt_isCloud Whether the variable is a cloud variable. - * @see {Blockly.FieldVariable} - * @constructor - */ -Blockly.VariableModel = function(workspace, name, opt_type, opt_id, - opt_isLocal, opt_isCloud) { - /** - * The workspace the variable is in. - * @type {!Blockly.Workspace} - */ - this.workspace = workspace; - - /** - * The name of the variable, typically defined by the user. It must be - * unique across all names used for procedures and variables. It may be - * changed by the user. - * @type {string} - */ - this.name = name; - - /** - * The type of the variable, such as 'int' or 'sound_effect'. This may be - * used to build a list of variables of a specific type. By default this is - * the empty string '', which is a specific type. - * @see {Blockly.FieldVariable} - * @type {string} - */ - this.type = opt_type || ''; - - /** - * A unique id for the variable. This should be defined at creation and - * not change, even if the name changes. In most cases this should be a - * UUID. - * @type {string} - * @private - */ - this.id_ = opt_id || Blockly.utils.genUid(); - - /** - * Whether this variable is locally scoped. - * @package - */ - this.isLocal = opt_isLocal || false; - - /** - * Whether the variable is a cloud variable. - * @package - */ - this.isCloud = opt_isCloud || false; - - Blockly.Events.fire(new Blockly.Events.VarCreate(this)); -}; - -/** - * @return {!string} The ID for the variable. - */ -Blockly.VariableModel.prototype.getId = function() { - return this.id_; -}; - -/** - * A custom compare function for the VariableModel objects. - * @param {Blockly.VariableModel} var1 First variable to compare. - * @param {Blockly.VariableModel} var2 Second variable to compare. - * @return {number} -1 if name of var1 is less than name of var2, 0 if equal, - * and 1 if greater. - * @package - */ -Blockly.VariableModel.compareByName = function(var1, var2) { - return Blockly.scratchBlocksUtils.compareStrings(var1.name, var2.name); -}; diff --git a/core/warning.js b/core/warning.js deleted file mode 100644 index 8ea805bd31..0000000000 --- a/core/warning.js +++ /dev/null @@ -1,199 +0,0 @@ -/** - * @license - * Visual Blocks Editor - * - * Copyright 2012 Google Inc. - * https://developers.google.com/blockly/ - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @fileoverview Object representing a warning. - * @author fraser@google.com (Neil Fraser) - */ -'use strict'; - -goog.provide('Blockly.Warning'); - -goog.require('Blockly.Bubble'); -goog.require('Blockly.Events.Ui'); -goog.require('Blockly.Icon'); - - -/** - * Class for a warning. - * @param {!Blockly.Block} block The block associated with this warning. - * @extends {Blockly.Icon} - * @constructor - */ -Blockly.Warning = function(block) { - Blockly.Warning.superClass_.constructor.call(this, block); - this.createIcon(); - // The text_ object can contain multiple warnings. - this.text_ = {}; -}; -goog.inherits(Blockly.Warning, Blockly.Icon); - -/** - * Does this icon get hidden when the block is collapsed. - */ -Blockly.Warning.prototype.collapseHidden = false; - -/** - * Draw the warning icon. - * @param {!Element} group The icon group. - * @private - */ -Blockly.Warning.prototype.drawIcon_ = function(group) { - // Triangle with rounded corners. - Blockly.utils.createSvgElement('path', - { - 'class': 'blocklyIconShape', - 'd': 'M2,15Q-1,15 0.5,12L6.5,1.7Q8,-1 9.5,1.7L15.5,12Q17,15 14,15z' - }, - group); - // Can't use a real '!' text character since different browsers and operating - // systems render it differently. - // Body of exclamation point. - Blockly.utils.createSvgElement('path', - { - 'class': 'blocklyIconSymbol', - 'd': 'm7,4.8v3.16l0.27,2.27h1.46l0.27,-2.27v-3.16z' - }, - group); - // Dot of exclamation point. - Blockly.utils.createSvgElement('rect', - { - 'class': 'blocklyIconSymbol', - 'x': '7', - 'y': '11', - 'height': '2', - 'width': '2' - }, - group); -}; - -/** - * Create the text for the warning's bubble. - * @param {string} text The text to display. - * @return {!SVGTextElement} The top-level node of the text. - * @private - */ -Blockly.Warning.textToDom_ = function(text) { - var paragraph = /** @type {!SVGTextElement} */ - (Blockly.utils.createSvgElement( - 'text', - { - 'class': 'blocklyText blocklyBubbleText', - 'y': Blockly.Bubble.BORDER_WIDTH - }, - null) - ); - var lines = text.split('\n'); - for (var i = 0; i < lines.length; i++) { - var tspanElement = Blockly.utils.createSvgElement('tspan', - {'dy': '1em', 'x': Blockly.Bubble.BORDER_WIDTH}, paragraph); - var textNode = document.createTextNode(lines[i]); - tspanElement.appendChild(textNode); - } - return paragraph; -}; - -/** - * Show or hide the warning bubble. - * @param {boolean} visible True if the bubble should be visible. - */ -Blockly.Warning.prototype.setVisible = function(visible) { - if (visible == this.isVisible()) { - // No change. - return; - } - Blockly.Events.fire( - new Blockly.Events.Ui(this.block_, 'warningOpen', !visible, visible)); - if (visible) { - // Create the bubble to display all warnings. - var paragraph = Blockly.Warning.textToDom_(this.getText()); - this.bubble_ = new Blockly.Bubble( - /** @type {!Blockly.WorkspaceSvg} */ (this.block_.workspace), - paragraph, this.block_.svgPath_, this.iconXY_, null, null); - if (this.block_.RTL) { - // Right-align the paragraph. - // This cannot be done until the bubble is rendered on screen. - var maxWidth = paragraph.getBBox().width; - for (var i = 0, textElement; textElement = paragraph.childNodes[i]; i++) { - textElement.setAttribute('text-anchor', 'end'); - textElement.setAttribute('x', maxWidth + Blockly.Bubble.BORDER_WIDTH); - } - } - this.updateColour(); - // Bump the warning into the right location. - var size = this.bubble_.getBubbleSize(); - this.bubble_.setBubbleSize(size.width, size.height); - } else { - // Dispose of the bubble. - this.bubble_.dispose(); - this.bubble_ = null; - this.body_ = null; - } -}; - -/** - * Bring the warning to the top of the stack when clicked on. - * @param {!Event} _e Mouse up event. - * @private - */ -Blockly.Warning.prototype.bodyFocus_ = function(_e) { - this.bubble_.promote_(); -}; - -/** - * Set this warning's text. - * @param {string} text Warning text (or '' to delete). - * @param {string} id An ID for this text entry to be able to maintain - * multiple warnings. - */ -Blockly.Warning.prototype.setText = function(text, id) { - if (this.text_[id] == text) { - return; - } - if (text) { - this.text_[id] = text; - } else { - delete this.text_[id]; - } - if (this.isVisible()) { - this.setVisible(false); - this.setVisible(true); - } -}; - -/** - * Get this warning's texts. - * @return {string} All texts concatenated into one string. - */ -Blockly.Warning.prototype.getText = function() { - var allWarnings = []; - for (var id in this.text_) { - allWarnings.push(this.text_[id]); - } - return allWarnings.join('\n'); -}; - -/** - * Dispose of this warning. - */ -Blockly.Warning.prototype.dispose = function() { - this.block_.warning = null; - Blockly.Icon.prototype.dispose.call(this); -}; diff --git a/core/widgetdiv.js b/core/widgetdiv.js deleted file mode 100644 index 44c476a77f..0000000000 --- a/core/widgetdiv.js +++ /dev/null @@ -1,344 +0,0 @@ -/** - * @license - * Visual Blocks Editor - * - * Copyright 2013 Google Inc. - * https://developers.google.com/blockly/ - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @fileoverview A div that floats on top of Blockly. This singleton contains - * temporary HTML UI widgets that the user is currently interacting with. - * E.g. text input areas, colour pickers, context menus. - * @author fraser@google.com (Neil Fraser) - */ -'use strict'; - -/** - * @name Blockly.WidgetDiv - * @namespace - **/ -goog.provide('Blockly.WidgetDiv'); - -goog.require('Blockly.Css'); -goog.require('goog.dom'); -goog.require('goog.dom.TagName'); -goog.require('goog.style'); - - -/** - * The HTML container. Set once by Blockly.WidgetDiv.createDom. - * @type {Element} - */ -Blockly.WidgetDiv.DIV = null; - -/** - * The object currently using this container. - * @type {Object} - * @private - */ -Blockly.WidgetDiv.owner_ = null; - -/** - * Optional cleanup function set by whichever object uses the widget. - * This is called as soon as a dispose is desired. If the dispose should - * be animated, the animation should start on the call of dispose_. - * @type {Function} - * @private - */ -Blockly.WidgetDiv.dispose_ = null; - -/** - * Optional function called at the end of a dispose animation. - * Set by whichever object is using the widget. - * @type {Function} - * @private - */ -Blockly.WidgetDiv.disposeAnimationFinished_ = null; - -/** - * Timer ID for the dispose animation. - * @type {number} - * @private - */ -Blockly.WidgetDiv.disposeAnimationTimer_ = null; - -/** - * Length of time in seconds for the dispose animation. - * @type {number} - * @private - */ -Blockly.WidgetDiv.disposeAnimationTimerLength_ = 0; - - -/** - * Create the widget div and inject it onto the page. - */ -Blockly.WidgetDiv.createDom = function() { - if (Blockly.WidgetDiv.DIV) { - return; // Already created. - } - // Create an HTML container for popup overlays (e.g. editor widgets). - Blockly.WidgetDiv.DIV = - goog.dom.createDom(goog.dom.TagName.DIV, 'blocklyWidgetDiv'); - document.body.appendChild(Blockly.WidgetDiv.DIV); -}; - -/** - * Initialize and display the widget div. Close the old one if needed. - * @param {!Object} newOwner The object that will be using this container. - * @param {boolean} rtl Right-to-left (true) or left-to-right (false). - * @param {Function=} opt_dispose Optional cleanup function to be run when the widget - * is closed. If the dispose is animated, this function must start the animation. - * @param {Function=} opt_disposeAnimationFinished Optional cleanup function to be run - * when the widget is done animating and must disappear. - * @param {number=} opt_disposeAnimationTimerLength Length of animation time in seconds - if a dispose animation is provided. - */ -Blockly.WidgetDiv.show = function(newOwner, rtl, opt_dispose, - opt_disposeAnimationFinished, opt_disposeAnimationTimerLength) { - Blockly.WidgetDiv.hide(); - Blockly.WidgetDiv.owner_ = newOwner; - Blockly.WidgetDiv.dispose_ = opt_dispose; - Blockly.WidgetDiv.disposeAnimationFinished_ = opt_disposeAnimationFinished; - Blockly.WidgetDiv.disposeAnimationTimerLength_ = opt_disposeAnimationTimerLength; - // Temporarily move the widget to the top of the screen so that it does not - // cause a scrollbar jump in Firefox when displayed. - var xy = goog.style.getViewportPageOffset(document); - Blockly.WidgetDiv.DIV.style.top = xy.y + 'px'; - Blockly.WidgetDiv.DIV.style.direction = rtl ? 'rtl' : 'ltr'; - Blockly.WidgetDiv.DIV.style.display = 'block'; -}; - -/** - * Repositions the widgetDiv on window resize. If it doesn't know how to - * calculate the new position, it wll just hide it instead. - */ -Blockly.WidgetDiv.repositionForWindowResize = function() { - // This condition mainly catches the widget div when it is being used as a - // text input. It is important not to close it in this case because on Android, - // when a field is focused, the soft keyboard opens triggering a window resize - // event and we want the widget div to stick around so users can type into it. - if (Blockly.WidgetDiv.owner_ - && Blockly.WidgetDiv.owner_.getScaledBBox_ - && Blockly.WidgetDiv.owner_.getSize) { - var widgetScaledBBox = Blockly.WidgetDiv.owner_.getScaledBBox_(); - var widgetSize = Blockly.WidgetDiv.owner_.getSize(); - Blockly.WidgetDiv.positionInternal_(widgetScaledBBox.left, widgetScaledBBox.top, - widgetSize.height); - } else { - Blockly.WidgetDiv.hide(); - } -}; - -/** - * Destroy the widget and hide the div. - * @param {boolean=} opt_noAnimate If set, animation will not be run for the hide. - */ -Blockly.WidgetDiv.hide = function(opt_noAnimate) { - if (Blockly.WidgetDiv.disposeAnimationTimer_) { - // An animation timer is set already. - // This happens when a previous widget was animating out, - // but Blockly is hiding the widget to create a new one. - // So, short-circuit the animation and clear the timer. - window.clearTimeout(Blockly.WidgetDiv.disposeAnimationTimer_); - Blockly.WidgetDiv.disposeAnimationFinished_ && Blockly.WidgetDiv.disposeAnimationFinished_(); - Blockly.WidgetDiv.disposeAnimationFinished_ = null; - Blockly.WidgetDiv.disposeAnimationTimer_ = null; - Blockly.WidgetDiv.owner_ = null; - Blockly.WidgetDiv.hideAndClearDom_(); - } else if (Blockly.WidgetDiv.isVisible()) { - // No animation timer set, but the widget is visible - // Start animation out (or immediately hide) - Blockly.WidgetDiv.dispose_ && Blockly.WidgetDiv.dispose_(); - Blockly.WidgetDiv.dispose_ = null; - // If we want to animate out, set the appropriate timer for final dispose. - if (Blockly.WidgetDiv.disposeAnimationFinished_ && !opt_noAnimate) { - Blockly.WidgetDiv.disposeAnimationTimer_ = window.setTimeout( - Blockly.WidgetDiv.hide, // Come back to hide and take the first branch. - Blockly.WidgetDiv.disposeAnimationTimerLength_ * 1000 - ); - } else { - // No timer provided (or no animation desired) - auto-hide the DOM now. - Blockly.WidgetDiv.disposeAnimationFinished_ && Blockly.WidgetDiv.disposeAnimationFinished_(); - Blockly.WidgetDiv.disposeAnimationFinished_ = null; - Blockly.WidgetDiv.owner_ = null; - Blockly.WidgetDiv.hideAndClearDom_(); - } - } -}; - -/** - * Hide all DOM for the WidgetDiv, and clear its children. - * @private - */ -Blockly.WidgetDiv.hideAndClearDom_ = function() { - Blockly.WidgetDiv.DIV.style.display = 'none'; - Blockly.WidgetDiv.DIV.style.left = ''; - Blockly.WidgetDiv.DIV.style.top = ''; - Blockly.WidgetDiv.DIV.style.height = ''; - goog.dom.removeChildren(Blockly.WidgetDiv.DIV); -}; - -/** - * Is the container visible? - * @return {boolean} True if visible. - */ -Blockly.WidgetDiv.isVisible = function() { - return !!Blockly.WidgetDiv.owner_; -}; - -/** - * Destroy the widget and hide the div if it is being used by the specified - * object. - * @param {!Object} oldOwner The object that was using this container. - */ -Blockly.WidgetDiv.hideIfOwner = function(oldOwner) { - if (Blockly.WidgetDiv.owner_ == oldOwner) { - Blockly.WidgetDiv.hide(); - } -}; - -/** - * Position the widget at a given location. Prevent the widget from going - * offscreen top or left (right in RTL). - * @param {number} anchorX Horizontal location (window coordinates, not body). - * @param {number} anchorY Vertical location (window coordinates, not body). - * @param {!goog.math.Size} windowSize Height/width of window. - * @param {!goog.math.Coordinate} scrollOffset X/y of window scrollbars. - * @param {boolean} rtl True if RTL, false if LTR. - */ -Blockly.WidgetDiv.position = function(anchorX, anchorY, windowSize, - scrollOffset, rtl) { - // Don't let the widget go above the top edge of the window. - if (anchorY < scrollOffset.y) { - anchorY = scrollOffset.y; - } - if (rtl) { - // Don't let the widget go right of the right edge of the window. - if (anchorX > windowSize.width + scrollOffset.x) { - anchorX = windowSize.width + scrollOffset.x; - } - } else { - // Don't let the widget go left of the left edge of the window. - if (anchorX < scrollOffset.x) { - anchorX = scrollOffset.x; - } - } - Blockly.WidgetDiv.positionInternal_(anchorX, anchorY, windowSize.height); -}; - -/** - * Set the widget div's position and height. This function does nothing clever: - * it will not ensure that your widget div ends up in the visible window. - * @param {number} x Horizontal location (window coordinates, not body). - * @param {number} y Vertical location (window coordinates, not body). - * @param {number} height The height of the widget div (pixels). - * @private - */ -Blockly.WidgetDiv.positionInternal_ = function(x, y, height) { - Blockly.WidgetDiv.DIV.style.left = x + 'px'; - Blockly.WidgetDiv.DIV.style.top = y + 'px'; - Blockly.WidgetDiv.DIV.style.height = height + 'px'; -}; - -/** - * Position the widget div based on an anchor rectangle. - * The widget should be placed adjacent to but not overlapping the anchor - * rectangle. The preferred position is directly below and aligned to the left - * (ltr) or right (rtl) side of the anchor. - * @param {!Object} viewportBBox The bounding rectangle of the current viewport, - * in window coordinates. - * @param {!Object} anchorBBox The bounding rectangle of the anchor, in window - * coordinates. - * @param {!goog.math.Size} widgetSize The size of the widget that is inside the - * widget div, in window coordinates. - * @param {boolean} rtl Whether the workspace is in RTL mode. This determines - * horizontal alignment. - * @package - */ -Blockly.WidgetDiv.positionWithAnchor = function(viewportBBox, anchorBBox, - widgetSize, rtl) { - var y = Blockly.WidgetDiv.calculateY_(viewportBBox, anchorBBox, widgetSize); - var x = Blockly.WidgetDiv.calculateX_(viewportBBox, anchorBBox, widgetSize, - rtl); - - if (y < 0) { - Blockly.WidgetDiv.positionInternal_(x, 0, widgetSize.height + y); - } - else { - Blockly.WidgetDiv.positionInternal_(x, y, widgetSize.height); - } -}; - -/** - * Calculate an x position (in window coordinates) such that the widget will not - * be offscreen on the right or left. - * @param {!Object} viewportBBox The bounding rectangle of the current viewport, - * in window coordinates. - * @param {!Object} anchorBBox The bounding rectangle of the anchor, in window - * coordinates. - * @param {goog.math.Size} widgetSize The dimensions of the widget inside the - * widget div. - * @param {boolean} rtl Whether the Blockly workspace is in RTL mode. - * @return {number} A valid x-coordinate for the top left corner of the widget - * div, in window coordinates. - * @private - */ -Blockly.WidgetDiv.calculateX_ = function(viewportBBox, anchorBBox, widgetSize, - rtl) { - if (rtl) { - // Try to align the right side of the field and the right side of the widget. - var widgetLeft = anchorBBox.right - widgetSize.width; - // Don't go offscreen left. - var x = Math.max(widgetLeft, viewportBBox.left); - // But really don't go offscreen right: - return Math.min(x, viewportBBox.right - widgetSize.width); - } else { - // Try to align the left side of the field and the left side of the widget. - // Don't go offscreen right. - var x = Math.min(anchorBBox.left, - viewportBBox.right - widgetSize.width); - // But left is more important, because that's where the text is. - return Math.max(x, viewportBBox.left); - } -}; - -/** - * Calculate a y position (in window coordinates) such that the widget will not - * be offscreen on the top or bottom. - * @param {!Object} viewportBBox The bounding rectangle of the current viewport, - * in window coordinates. - * @param {!Object} anchorBBox The bounding rectangle of the anchor, in window - * coordinates. - * @param {goog.math.Size} widgetSize The dimensions of the widget inside the - * widget div. - * @return {number} A valid y-coordinate for the top left corner of the widget - * div, in window coordinates. - * @private - */ -Blockly.WidgetDiv.calculateY_ = function(viewportBBox, anchorBBox, widgetSize) { - // Flip the widget vertically if off the bottom. - if (anchorBBox.bottom + widgetSize.height >= - viewportBBox.bottom) { - // The bottom of the widget is at the top of the field. - return anchorBBox.top - widgetSize.height; - // The widget could go off the top of the window, but it would also go off - // the bottom. The window is just too small. - } else { - // The top of the widget is at the bottom of the field. - return anchorBBox.bottom; - } -}; diff --git a/core/workspace.js b/core/workspace.js deleted file mode 100644 index 904315dc3f..0000000000 --- a/core/workspace.js +++ /dev/null @@ -1,673 +0,0 @@ -/** - * @license - * Visual Blocks Editor - * - * Copyright 2012 Google Inc. - * https://developers.google.com/blockly/ - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @fileoverview Object representing a workspace. - * @author fraser@google.com (Neil Fraser) - */ -'use strict'; - -goog.provide('Blockly.Workspace'); - -goog.require('Blockly.VariableMap'); -goog.require('Blockly.WorkspaceComment'); -goog.require('goog.array'); -goog.require('goog.math'); - - -/** - * Class for a workspace. This is a data structure that contains blocks. - * There is no UI, and can be created headlessly. - * @param {!Blockly.Options=} opt_options Dictionary of options. - * @constructor - */ -Blockly.Workspace = function(opt_options) { - /** @type {string} */ - this.id = Blockly.utils.genUid(); - Blockly.Workspace.WorkspaceDB_[this.id] = this; - /** @type {!Blockly.Options} */ - this.options = opt_options || {}; - /** @type {boolean} */ - this.RTL = !!this.options.RTL; - /** @type {boolean} */ - this.horizontalLayout = !!this.options.horizontalLayout; - /** @type {number} */ - this.toolboxPosition = this.options.toolboxPosition; - - /** - * @type {!Array.} - * @private - */ - this.topBlocks_ = []; - /** - * @type {!Array.} - * @private - */ - this.topComments_ = []; - /** - * @type {!Object} - * @private - */ - this.commentDB_ = Object.create(null); - /** - * @type {!Array.} - * @private - */ - this.listeners_ = []; - - /** @type {!Array.} */ - this.tapListeners_ = []; - - /** - * @type {!Array.} - * @protected - */ - this.undoStack_ = []; - - /** - * @type {!Array.} - * @protected - */ - this.redoStack_ = []; - - /** - * @type {!Object} - * @private - */ - this.blockDB_ = Object.create(null); - - /** - * @type {!Blockly.VariableMap} - * A map from variable type to list of variable names. The lists contain all - * of the named variables in the workspace, including variables - * that are not currently in use. - * @private - */ - this.variableMap_ = new Blockly.VariableMap(this); - - /** - * Blocks in the flyout can refer to variables that don't exist in the main - * workspace. For instance, the "get item in list" block refers to an "item" - * variable regardless of whether the variable has been created yet. - * A FieldVariable must always refer to a Blockly.VariableModel. We reconcile - * these by tracking "potential" variables in the flyout. These variables - * become real when references to them are dragged into the main workspace. - * @type {!Blockly.VariableMap} - * @private - */ - this.potentialVariableMap_ = null; -}; - -/** - * Returns `true` if the workspace is visible and `false` if it's headless. - * @type {boolean} - */ -Blockly.Workspace.prototype.rendered = false; - -/** - * Returns `true` if the workspace is currently in the process of a bulk clear. - * @type {boolean} - * @package - */ -Blockly.Workspace.prototype.isClearing = false; - -/** - * Maximum number of undo events in stack. `0` turns off undo, `Infinity` sets it to unlimited. - * @type {number} - */ -Blockly.Workspace.prototype.MAX_UNDO = 1024; - -// TODO (#1354) Update this function when it is fixed upstream -/** - * Refresh the toolbox. This is a no-op in a non-rendered workspace, - * but may be overriden by subclasses. - * @private - */ -Blockly.Workspace.prototype.refreshToolboxSelection_ = function() { - // No-op. Overriden by subclass. -}; - -/** - * Dispose of this workspace. - * Unlink from all DOM elements to prevent memory leaks. - */ -Blockly.Workspace.prototype.dispose = function() { - this.listeners_.length = 0; - this.clear(); - // Remove from workspace database. - delete Blockly.Workspace.WorkspaceDB_[this.id]; -}; - -/** - * Angle away from the horizontal to sweep for blocks. Order of execution is - * generally top to bottom, but a small angle changes the scan to give a bit of - * a left to right bias (reversed in RTL). Units are in degrees. - * See: http://tvtropes.org/pmwiki/pmwiki.php/Main/DiagonalBilling. - */ -Blockly.Workspace.SCAN_ANGLE = 3; - -/** - * Add a block to the list of top blocks. - * @param {!Blockly.Block} block Block to add. - */ -Blockly.Workspace.prototype.addTopBlock = function(block) { - this.topBlocks_.push(block); -}; - -/** - * Remove a block from the list of top blocks. - * @param {!Blockly.Block} block Block to remove. - */ -Blockly.Workspace.prototype.removeTopBlock = function(block) { - if (!goog.array.remove(this.topBlocks_, block)) { - throw 'Block not present in workspace\'s list of top-most blocks.'; - } -}; - -/** - * Finds the top-level blocks and returns them. Blocks are optionally sorted - * by position; top to bottom (with slight LTR or RTL bias). - * @param {boolean} ordered Sort the list if true. - * @return {!Array.} The top-level block objects. - */ -Blockly.Workspace.prototype.getTopBlocks = function(ordered) { - // Copy the topBlocks_ list. - var blocks = [].concat(this.topBlocks_); - if (ordered && blocks.length > 1) { - var offset = Math.sin(goog.math.toRadians(Blockly.Workspace.SCAN_ANGLE)); - if (this.RTL) { - offset *= -1; - } - blocks.sort(function(a, b) { - var aXY = a.getRelativeToSurfaceXY(); - var bXY = b.getRelativeToSurfaceXY(); - return (aXY.y + offset * aXY.x) - (bXY.y + offset * bXY.x); - }); - } - return blocks; -}; - -/** - * Add a comment to the list of top comments. - * @param {!Blockly.WorkspaceComment} comment comment to add. - * @package - */ -Blockly.Workspace.prototype.addTopComment = function(comment) { - this.topComments_.push(comment); - - // Note: If the comment database starts to hold block comments, this may need - // to move to a separate function. - if (this.commentDB_[comment.id]) { - console.warn('Overriding an existing comment on this workspace, with id "' + - comment.id + '"'); - } - this.commentDB_[comment.id] = comment; -}; - -/** - * Remove a comment from the list of top comments. - * @param {!Blockly.WorkspaceComment} comment comment to remove. - * @package - */ -Blockly.Workspace.prototype.removeTopComment = function(comment) { - if (!goog.array.remove(this.topComments_, comment)) { - throw 'Comment not present in workspace\'s list of top-most comments.'; - } - // Note: If the comment database starts to hold block comments, this may need - // to move to a separate function. - delete this.commentDB_[comment.id]; -}; - -/** - * Finds the top-level comments and returns them. Comments are optionally sorted - * by position; top to bottom (with slight LTR or RTL bias). - * @param {boolean} ordered Sort the list if true. - * @return {!Array.} The top-level comment objects. - * @package - */ -Blockly.Workspace.prototype.getTopComments = function(ordered) { - // Copy the topComments_ list. - var comments = [].concat(this.topComments_); - if (ordered && comments.length > 1) { - var offset = Math.sin(goog.math.toRadians(Blockly.Workspace.SCAN_ANGLE)); - if (this.RTL) { - offset *= -1; - } - comments.sort(function(a, b) { - var aXY = a instanceof Blockly.ScratchBlockComment ? a.getXY() : a.getRelativeToSurfaceXY(); - var bXY = b instanceof Blockly.ScratchBlockComment ? b.getXY() : b.getRelativeToSurfaceXY(); - return (aXY.y + offset * aXY.x) - (bXY.y + offset * bXY.x); - }); - } - return comments; -}; - -/** - * Find all blocks in workspace. Blocks are optionally sorted - * by position; top to bottom (with slight LTR or RTL bias). - * @param {boolean} ordered Sort the list if true. - * @return {!Array.} Array of blocks. - */ -Blockly.Workspace.prototype.getAllBlocks = function(ordered) { - if (ordered) { - // Slow, but ordered. - // This gets all levels of descendants because getDescendants - // is called recuusively. They are added to a new list, not the - // list that it's iterating over. - var topBlocks = this.getTopBlocks(true); - var blocks = []; - for (var i = 0; i < topBlocks.length; i++) { - blocks.push.apply(blocks, topBlocks[i].getDescendants(true)); - } - } else { - // Fast, but in no particular order. - // This gets all of levels of descendants by always adding to the - // list that it's iterating over. - var blocks = this.getTopBlocks(false); - for (var i = 0; i < blocks.length; i++) { - blocks.push.apply(blocks, blocks[i].getChildren(false)); - } - } - return blocks; -}; - -/** - * Dispose of all blocks and comments in workspace. - */ -Blockly.Workspace.prototype.clear = function() { - this.isClearing = true; - var existingGroup = Blockly.Events.getGroup(); - if (!existingGroup) { - Blockly.Events.setGroup(true); - } - while (this.topBlocks_.length) { - this.topBlocks_[0].dispose(); - } - while (this.topComments_.length) { - this.topComments_[this.topComments_.length - 1].dispose(); - } - if (!existingGroup) { - Blockly.Events.setGroup(false); - } - this.variableMap_.clear(); - // Any block with a drop-down or WidgetDiv was disposed. - if (Blockly.DropDownDiv) { - Blockly.DropDownDiv.hideWithoutAnimation(); - } - if (Blockly.WidgetDiv) { - Blockly.WidgetDiv.hide(true); - } - if (this.potentialVariableMap_) { - this.potentialVariableMap_.clear(); - } - this.isClearing = false; -}; - -/* Begin functions that are just pass-throughs to the variable map. */ -/** - * Rename a variable by updating its name in the variable map. Identify the - * variable to rename with the given ID. - * @param {string} id ID of the variable to rename. - * @param {string} newName New variable name. - */ -Blockly.Workspace.prototype.renameVariableById = function(id, newName) { - this.variableMap_.renameVariableById(id, newName); -}; - -/** - * Create a variable with a given name, optional type, and optional ID. - * @param {!string} name The name of the variable. This must be unique across - * each variable type. - * @param {?string} opt_type The type of the variable like 'int' or 'string'. - * Does not need to be unique. Field_variable can filter variables based on - * their type. This will default to '' which is a specific type. - * @param {string=} opt_id The unique ID of the variable. This will default to - * a UUID. - * @param {boolean=} opt_isLocal Whether the variable to create is locally scoped. - * @param {boolean=} opt_isCloud Whether the variable to create is locally scoped. - * @return {?Blockly.VariableModel} The newly created variable. - */ -Blockly.Workspace.prototype.createVariable = function(name, opt_type, opt_id, - opt_isLocal, opt_isCloud) { - return this.variableMap_.createVariable(name, opt_type, opt_id, opt_isLocal, opt_isCloud); -}; - -/** - * Find all the uses of the given variable, which is identified by ID. - * @param {string} id ID of the variable to find. - * @return {!Array.} Array of block usages. - */ -Blockly.Workspace.prototype.getVariableUsesById = function(id) { - return this.variableMap_.getVariableUsesById(id); -}; - -/** - * Delete a variables by the passed in ID and all of its uses from this - * workspace. May prompt the user for confirmation. - * @param {string} id ID of variable to delete. - */ -Blockly.Workspace.prototype.deleteVariableById = function(id) { - this.variableMap_.deleteVariableById(id); -}; - -/** - * Deletes a variable and all of its uses from this workspace without asking the - * user for confirmation. - * @param {!Blockly.VariableModel} variable Variable to delete. - * @param {!Array.} uses An array of uses of the variable. - * @private - */ -Blockly.Workspace.prototype.deleteVariableInternal_ = function(variable, uses) { - this.variableMap_.deleteVariableInternal_(variable, uses); -}; - -/** - * Check whether a variable exists with the given name. The check is - * case-insensitive. - * @param {string} _name The name to check for. - * @return {number} The index of the name in the variable list, or -1 if it is - * not present. - * @deprecated April 2017 - */ - -Blockly.Workspace.prototype.variableIndexOf = function(_name) { - console.warn( - 'Deprecated call to Blockly.Workspace.prototype.variableIndexOf'); - return -1; -}; - -/** - * Find the variable by the given name and return it. Return null if it is not - * found. - * TODO (#1199): Possibly delete this function. - * @param {!string} name The name to check for. - * @param {string=} opt_type The type of the variable. If not provided it - * defaults to the empty string, which is a specific type. - * @return {?Blockly.VariableModel} the variable with the given name. - */ -Blockly.Workspace.prototype.getVariable = function(name, opt_type) { - return this.variableMap_.getVariable(name, opt_type); -}; - -/** - * Find the variable by the given ID and return it. Return null if it is not - * found. - * @param {!string} id The ID to check for. - * @return {?Blockly.VariableModel} The variable with the given ID. - */ -Blockly.Workspace.prototype.getVariableById = function(id) { - return this.variableMap_.getVariableById(id); -}; - -/** - * Find the variable with the specified type. If type is null, return list of - * variables with empty string type. - * @param {?string} type Type of the variables to find. - * @return {Array.} The sought after variables of the - * passed in type. An empty array if none are found. - */ -Blockly.Workspace.prototype.getVariablesOfType = function(type) { - return this.variableMap_.getVariablesOfType(type); -}; - -/** - * Return all variable types. - * @return {!Array.} List of variable types. - * @package - */ -Blockly.Workspace.prototype.getVariableTypes = function() { - return this.variableMap_.getVariableTypes(); -}; - -/** - * Return all variables of all types. - * @return {!Array.} List of variable models. - */ -Blockly.Workspace.prototype.getAllVariables = function() { - return this.variableMap_.getAllVariables(); -}; - -/* End functions that are just pass-throughs to the variable map. */ - -/** - * Returns the horizontal offset of the workspace. - * Intended for LTR/RTL compatibility in XML. - * Not relevant for a headless workspace. - * @return {number} Width. - */ -Blockly.Workspace.prototype.getWidth = function() { - return 0; -}; - -/** - * Obtain a newly created block. - * @param {?string} prototypeName Name of the language object containing - * type-specific functions for this block. - * @param {string=} opt_id Optional ID. Use this ID if provided, otherwise - * create a new ID. - * @return {!Blockly.Block} The created block. - */ -Blockly.Workspace.prototype.newBlock = function(prototypeName, opt_id) { - return new Blockly.Block(this, prototypeName, opt_id); -}; - -/** - * Undo or redo the previous action. - * @param {boolean} redo False if undo, true if redo. - */ -Blockly.Workspace.prototype.undo = function(redo) { - var inputStack = redo ? this.redoStack_ : this.undoStack_; - var outputStack = redo ? this.undoStack_ : this.redoStack_; - var inputEvent = inputStack.pop(); - if (!inputEvent) { - return; - } - var events = [inputEvent]; - // Do another undo/redo if the next one is of the same group. - while (inputStack.length && inputEvent.group && - inputEvent.group == inputStack[inputStack.length - 1].group) { - events.push(inputStack.pop()); - } - // Push these popped events on the opposite stack. - for (var i = 0, event; event = events[i]; i++) { - outputStack.push(event); - } - events = Blockly.Events.filter(events, redo); - Blockly.Events.recordUndo = false; - if (Blockly.selected) { - Blockly.Events.disable(); - try { - Blockly.selected.unselect(); - } finally { - Blockly.Events.enable(); - } - } - try { - for (var i = 0, event; event = events[i]; i++) { - event.run(redo); - } - } finally { - Blockly.Events.recordUndo = true; - } -}; - -/** - * Clear the undo/redo stacks. - */ -Blockly.Workspace.prototype.clearUndo = function() { - this.undoStack_.length = 0; - this.redoStack_.length = 0; - // Stop any events already in the firing queue from being undoable. - Blockly.Events.clearPendingUndo(); -}; - -/** - * @return {boolean} whether there are any events in the redo stack. - * @package - */ -Blockly.Workspace.prototype.hasRedoStack = function() { - return this.redoStack_.length != 0; -}; - -/** - * @return {boolean} whether there are any events in the undo stack. - * @package - */ -Blockly.Workspace.prototype.hasUndoStack = function() { - return this.undoStack_.length != 0; -}; -/** - * When something in this workspace changes, call a function. - * @param {!Function} func Function to call. - * @return {!Function} Function that can be passed to - * removeChangeListener. - */ -Blockly.Workspace.prototype.addChangeListener = function(func) { - this.listeners_.push(func); - return func; -}; - -/** - * Stop listening for this workspace's changes. - * @param {Function} func Function to stop calling. - */ -Blockly.Workspace.prototype.removeChangeListener = function(func) { - goog.array.remove(this.listeners_, func); -}; - -/** - * Fire a change event. - * @param {!Blockly.Events.Abstract} event Event to fire. - */ -Blockly.Workspace.prototype.fireChangeListener = function(event) { - if (event.recordUndo) { - this.undoStack_.push(event); - this.redoStack_.length = 0; - if (this.undoStack_.length > this.MAX_UNDO) { - this.undoStack_.unshift(); - } - } - // Copy listeners in case a listener attaches/detaches itself. - var currentListeners = this.listeners_.slice(); - for (var i = 0, func; func = currentListeners[i]; i++) { - func(event); - } -}; - -/** - * Find the block on this workspace with the specified ID. - * @param {string} id ID of block to find. - * @return {Blockly.Block} The sought after block or null if not found. - */ -Blockly.Workspace.prototype.getBlockById = function(id) { - var block = this.blockDB_[id]; - if (!block && this.getFlyout() && this.getFlyout().getWorkspace()) { - block = this.getFlyout().getWorkspace().blockDB_[id]; - } - return block || null; -}; - -/** - * Find the comment on this workspace with the specified ID. - * @param {string} id ID of comment to find. - * @return {Blockly.WorkspaceComment} The sought after comment or null if not - * found. - * @package - */ -Blockly.Workspace.prototype.getCommentById = function(id) { - return this.commentDB_[id] || null; -}; - -/** - * Getter for the flyout associated with this workspace. This is null in a - * non-rendered workspace, but may be overriden by subclasses. - * @return {Blockly.Flyout} The flyout on this workspace. - */ -Blockly.Workspace.prototype.getFlyout = function() { - return null; -}; - -/** - * Checks whether all value and statement inputs in the workspace are filled - * with blocks. - * @param {boolean=} opt_shadowBlocksAreFilled An optional argument controlling - * whether shadow blocks are counted as filled. Defaults to true. - * @return {boolean} True if all inputs are filled, false otherwise. - */ -Blockly.Workspace.prototype.allInputsFilled = function(opt_shadowBlocksAreFilled) { - var blocks = this.getTopBlocks(false); - for (var i = 0, block; block = blocks[i]; i++) { - if (!block.allInputsFilled(opt_shadowBlocksAreFilled)) { - return false; - } - } - return true; -}; - -/** - * Return the variable map that contains "potential" variables. These exist in - * the flyout but not in the workspace. - * @return {?Blockly.VariableMap} The potential variable map. - * @package - */ -Blockly.Workspace.prototype.getPotentialVariableMap = function() { - return this.potentialVariableMap_; -}; - -/** - * Create and store the potential variable map for this workspace. - * @package - */ -Blockly.Workspace.prototype.createPotentialVariableMap = function() { - this.potentialVariableMap_ = new Blockly.VariableMap(this); -}; - -/** - * Return the map of all variables on the workspace. - * @return {?Blockly.VariableMap} The variable map. - * @package - */ -Blockly.Workspace.prototype.getVariableMap = function() { - return this.variableMap_; -}; - -/** - * Database of all workspaces. - * @private - */ -Blockly.Workspace.WorkspaceDB_ = Object.create(null); - -/** - * Find the workspace with the specified ID. - * @param {string} id ID of workspace to find. - * @return {Blockly.Workspace} The sought after workspace or null if not found. - */ -Blockly.Workspace.getById = function(id) { - return Blockly.Workspace.WorkspaceDB_[id] || null; -}; - -// Export symbols that would otherwise be renamed by Closure compiler. -Blockly.Workspace.prototype['clear'] = Blockly.Workspace.prototype.clear; -Blockly.Workspace.prototype['clearUndo'] = - Blockly.Workspace.prototype.clearUndo; -Blockly.Workspace.prototype['addChangeListener'] = - Blockly.Workspace.prototype.addChangeListener; -Blockly.Workspace.prototype['removeChangeListener'] = - Blockly.Workspace.prototype.removeChangeListener; diff --git a/core/workspace_audio.js b/core/workspace_audio.js deleted file mode 100644 index f81758a03d..0000000000 --- a/core/workspace_audio.js +++ /dev/null @@ -1,170 +0,0 @@ -/** - * @license - * Visual Blocks Editor - * - * Copyright 2017 Google Inc. - * https://developers.google.com/blockly/ - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @fileoverview Object in charge of loading, storing, and playing audio for a - * workspace. - * @author fenichel@google.com (Rachel Fenichel) - */ -'use strict'; - -goog.provide('Blockly.WorkspaceAudio'); - -goog.require('goog.userAgent'); - - -/** - * Class for loading, storing, and playing audio for a workspace. - * @param {Blockly.WorkspaceSvg} parentWorkspace The parent of the workspace - * this audio object belongs to, or null. - * @constructor - */ -Blockly.WorkspaceAudio = function(parentWorkspace) { - - /** - * The parent of the workspace this object belongs to, or null. May be - * checked for sounds that this object can't find. - * @type {Blockly.WorkspaceSvg} - * @private - */ - this.parentWorkspace_ = parentWorkspace; - - /** - * Database of pre-loaded sounds. - * @private - * @const - */ - this.SOUNDS_ = Object.create(null); -}; - -/** - * Time that the last sound was played. - * @type {Date} - * @private - */ -Blockly.WorkspaceAudio.prototype.lastSound_ = null; - -/** - * Dispose of this audio manager. - * @package - */ -Blockly.WorkspaceAudio.prototype.dispose = function() { - this.parentWorkspace_ = null; - this.SOUNDS_ = null; -}; - -/** - * Load an audio file. Cache it, ready for instantaneous playing. - * @param {!Array.} filenames List of file types in decreasing order of - * preference (i.e. increasing size). E.g. ['media/go.mp3', 'media/go.wav'] - * Filenames include path from Blockly's root. File extensions matter. - * @param {string} name Name of sound. - * @package - */ -Blockly.WorkspaceAudio.prototype.load = function(filenames, name) { - if (!filenames.length) { - return; - } - try { - var audioTest = new window['Audio'](); - } catch (e) { - // No browser support for Audio. - // IE can throw an error even if the Audio object exists. - return; - } - var sound; - for (var i = 0; i < filenames.length; i++) { - var filename = filenames[i]; - var ext = filename.match(/\.(\w+)$/); - if (ext && audioTest.canPlayType('audio/' + ext[1])) { - // Found an audio format we can play. - sound = new window['Audio'](filename); - break; - } - } - if (sound && sound.play) { - this.SOUNDS_[name] = sound; - } -}; - -/** - * Preload all the audio files so that they play quickly when asked for. - * @package - */ -Blockly.WorkspaceAudio.prototype.preload = function() { - for (var name in this.SOUNDS_) { - var sound = this.SOUNDS_[name]; - sound.volume = 0.01; - var playPromise = sound.play(); - - // Edge does not return a promise, so we need to check. - if (playPromise) { - // If we don't wait for the play request to complete before calling pause() we will get an exception: - // Uncaught (in promise) DOMException: The play() request was interrupted by a call to pause(). - // See more: https://developers.google.com/web/updates/2017/06/play-request-was-interrupted - playPromise.then(sound.pause).catch(function() { - // Play without user interaction was prevented. - }); - } else { - sound.pause(); - } - - // iOS can only process one sound at a time. Trying to load more than one - // corrupts the earlier ones. Just load one and leave the others uncached. - if (goog.userAgent.IPAD || goog.userAgent.IPHONE) { - break; - } - } -}; - -/** - * Play a named sound at specified volume. If volume is not specified, - * use full volume (1). - * @param {string} name Name of sound. - * @param {number=} opt_volume Volume of sound (0-1). - */ -Blockly.WorkspaceAudio.prototype.play = function(name, opt_volume) { - var sound = this.SOUNDS_[name]; - if (sound) { - // Don't play one sound on top of another. - var now = new Date; - if (this.lastSound_ != null && - now - this.lastSound_ < Blockly.SOUND_LIMIT) { - return; - } - this.lastSound_ = now; - var mySound; - var ie9 = goog.userAgent.DOCUMENT_MODE && - goog.userAgent.DOCUMENT_MODE === 9; - if (ie9 || goog.userAgent.IPAD || goog.userAgent.ANDROID) { - // Creating a new audio node causes lag in IE9, Android and iPad. Android - // and IE9 refetch the file from the server, iPad uses a singleton audio - // node which must be deleted and recreated for each new audio tag. - mySound = sound; - } else { - mySound = sound.cloneNode(); - } - mySound.volume = (opt_volume === undefined ? 1 : opt_volume); - mySound.play(); - } else if (this.parentWorkspace_) { - // Maybe a workspace on a lower level knows about this sound. - this.parentWorkspace_.getAudioManager().play(name, opt_volume); - } -}; diff --git a/core/workspace_comment.js b/core/workspace_comment.js deleted file mode 100644 index 02c6e3fecd..0000000000 --- a/core/workspace_comment.js +++ /dev/null @@ -1,432 +0,0 @@ -/** - * @license - * Visual Blocks Editor - * - * Copyright 2017 Google Inc. - * https://developers.google.com/blockly/ - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @fileoverview Object representing a code comment on the workspace. - * @author fenichel@google.com (Rachel Fenichel) - */ -'use strict'; - -goog.provide('Blockly.WorkspaceComment'); - -goog.require('Blockly.Events.CommentChange'); -goog.require('Blockly.Events.CommentCreate'); -goog.require('Blockly.Events.CommentDelete'); -goog.require('Blockly.Events.CommentMove'); - -goog.require('goog.math.Coordinate'); - - -/** - * Class for a workspace comment. - * @param {!Blockly.Workspace} workspace The block's workspace. - * @param {string} content The content of this workspace comment. - * @param {number} height Height of the comment. - * @param {number} width Width of the comment. - * @param {boolean} minimized Whether this comment is in the minimized state - * @param {string=} opt_id Optional ID. Use this ID if provided, otherwise - * create a new ID. If the ID conflicts with an in-use ID, a new one will - * be generated. - * @constructor - */ -Blockly.WorkspaceComment = function(workspace, content, height, width, minimized, opt_id) { - /** @type {string} */ - this.id = (opt_id && !workspace.getCommentById(opt_id)) ? - opt_id : Blockly.utils.genUid(); - - workspace.addTopComment(this); - - /** - * The comment's position in workspace units. (0, 0) is at the workspace's - * origin; scale does not change this value. - * @type {!goog.math.Coordinate} - * @protected - */ - this.xy_ = new goog.math.Coordinate(0, 0); - - /** - * The comment's height in workspace units. Scale does not change this value. - * @type {number} - * @private - */ - this.height_ = height; - - /** - * The comment's width in workspace units. Scale does not change this value. - * @type {number} - * @private - */ - this.width_ = width; - - /** - * The comment's minimized state. - * @type{boolean} - * @private - */ - this.isMinimized_ = minimized; - - /** - * @type {!Blockly.Workspace} - */ - this.workspace = workspace; - - /** - * @protected - * @type {boolean} - */ - this.RTL = workspace.RTL; - - /** - * @type {boolean} - * @private - */ - this.deletable_ = true; - - /** - * @type {boolean} - * @private - */ - this.movable_ = true; - - /** - * @protected - * @type {!string} - */ - this.content_ = content; - - /** - * @package - * @type {boolean} - */ - this.isComment = true; - - Blockly.WorkspaceComment.fireCreateEvent(this); -}; - -/** - * Maximum lable length (actual label length will include - * one additional character, the ellipsis). - * @private - */ -Blockly.WorkspaceComment.MAX_LABEL_LENGTH = 12; - -/** - * Maximum character length for comment text. - * @private - */ -Blockly.WorkspaceComment.COMMENT_TEXT_LIMIT = 8000; - -/** - * Dispose of this comment. - * @package - */ -Blockly.WorkspaceComment.prototype.dispose = function() { - if (!this.workspace) { - // The comment has already been deleted. - return; - } - - if (Blockly.Events.isEnabled()) { - Blockly.Events.fire(new Blockly.Events.CommentDelete(this)); - } - - // Remove from the list of top comments and the comment database. - this.workspace.removeTopComment(this); - this.workspace = null; -}; - -// Height, width, x, and y are all stored on even non-rendered comments, to -// preserve state if you pass the contents through a headless workspace. - -/** - * Get comment height. - * @return {number} comment height. - * @package - */ -Blockly.WorkspaceComment.prototype.getHeight = function() { - return this.height_; -}; - -/** - * Set comment height. - * @param {number} height comment height. - * @package - */ -Blockly.WorkspaceComment.prototype.setHeight = function(height) { - this.height_ = height; -}; - -/** - * Get comment width. - * @return {number} comment width. - * @package - */ -Blockly.WorkspaceComment.prototype.getWidth = function() { - return this.width_; -}; - -/** - * Set comment width. - * @param {number} width comment width. - * @package - */ -Blockly.WorkspaceComment.prototype.setWidth = function(width) { - this.width_ = width; -}; - -/** - * Get the height and width of this comment. - * @return {{height: number, width: number}} The height and width of this comment; - * these numbers do not change as the workspace scales. - */ -Blockly.WorkspaceComment.prototype.getHeightWidth = function() { - return {height: this.height_, width: this.width_}; -}; - -/** - * Get stored location. - * @return {!goog.math.Coordinate} The comment's stored location. This is not - * valid if the comment is currently being dragged. - * @package - */ -Blockly.WorkspaceComment.prototype.getXY = function() { - return this.xy_.clone(); -}; - -/** - * Move a comment by a relative offset. - * @param {number} dx Horizontal offset, in workspace units. - * @param {number} dy Vertical offset, in workspace units. - * @package - */ -Blockly.WorkspaceComment.prototype.moveBy = function(dx, dy) { - var event = new Blockly.Events.CommentMove(this); - this.xy_.translate(dx, dy); - event.recordNew(); - Blockly.Events.fire(event); -}; - -/** - * Get whether this comment is deletable or not. - * @return {boolean} True if deletable. - * @package - */ -Blockly.WorkspaceComment.prototype.isDeletable = function() { - return this.deletable_ && - !(this.workspace && this.workspace.options.readOnly); -}; - -/** - * Set whether this comment is deletable or not. - * @param {boolean} deletable True if deletable. - * @package - */ -Blockly.WorkspaceComment.prototype.setDeletable = function(deletable) { - this.deletable_ = deletable; -}; - -/** - * Get whether this comment is movable or not. - * @return {boolean} True if movable. - * @package - */ -Blockly.WorkspaceComment.prototype.isMovable = function() { - return this.movable_ && - !(this.workspace && this.workspace.options.readOnly); -}; - -/** - * Set whether this comment is movable or not. - * @param {boolean} movable True if movable. - * @package - */ -Blockly.WorkspaceComment.prototype.setMovable = function(movable) { - this.movable_ = movable; -}; - -/** - * Returns this comment's text. - * @return {string} Comment text. - * @package - */ -Blockly.WorkspaceComment.prototype.getText = function() { - return this.content_; -}; - -/** - * Set this comment's text content. - * @param {string} text Comment text. - * @package - */ -Blockly.WorkspaceComment.prototype.setText = function(text) { - if (this.content_ != text) { - Blockly.Events.fire(new Blockly.Events.CommentChange( - this, {text: this.content_}, {text: text})); - this.content_ = text; - } -}; - -/** - * Check whether this comment is currently minimized. - * @return {boolean} True if minimized - * @package - */ -Blockly.WorkspaceComment.prototype.isMinimized = function() { - return this.isMinimized_; -}; - -/** - * Encode a comment subtree as XML with XY coordinates. - * @param {boolean=} opt_noId True if the encoder should skip the comment id. - * @return {!Element} Tree of XML elements. - * @package - */ -Blockly.WorkspaceComment.prototype.toXmlWithXY = function(opt_noId) { - var element = this.toXml(opt_noId); - element.setAttribute('x', Math.round(this.xy_.x)); - element.setAttribute('y', Math.round(this.xy_.y)); - element.setAttribute('h', this.height_); - element.setAttribute('w', this.width_); - return element; -}; - -/** - * Get the truncated text for this comment to display in the minimized - * top bar. - * @return {string} The truncated comment text - * @package - */ -Blockly.WorkspaceComment.prototype.getLabelText = function() { - if (this.content_.length > Blockly.WorkspaceComment.MAX_LABEL_LENGTH) { - if (this.RTL) { - return '\u2026' + this.content_.slice(0, Blockly.WorkspaceComment.MAX_LABEL_LENGTH); - } - return this.content_.slice(0, Blockly.WorkspaceComment.MAX_LABEL_LENGTH) + '\u2026'; - } else { - return this.content_; - } -}; - -/** - * Encode a comment subtree as XML, but don't serialize the XY coordinates or - * width and height. If you need that additional information use toXmlWithXY. - * @param {boolean=} opt_noId True if the encoder should skip the comment id. - * @return {!Element} Tree of XML elements. - * @package - */ -Blockly.WorkspaceComment.prototype.toXml = function(opt_noId) { - var commentElement = goog.dom.createDom('comment'); - if (!opt_noId) { - commentElement.setAttribute('id', this.id); - } - if (this.isMinimized_) { - commentElement.setAttribute('minimized', true); - } - commentElement.textContent = this.getText(); - return commentElement; -}; - -/** - * Fire a create event for the given workspace comment, if comments are enabled. - * @param {!Blockly.WorkspaceComment} comment The comment that was just created. - * @package - */ -Blockly.WorkspaceComment.fireCreateEvent = function(comment) { - if (Blockly.Events.isEnabled()) { - var existingGroup = Blockly.Events.getGroup(); - if (!existingGroup) { - Blockly.Events.setGroup(true); - } - try { - Blockly.Events.fire(new Blockly.Events.CommentCreate(comment)); - } finally { - if (!existingGroup) { - Blockly.Events.setGroup(false); - } - } - } -}; - -/** - * Decode an XML comment tag and create a comment on the workspace. - * @param {!Element} xmlComment XML comment element. - * @param {!Blockly.Workspace} workspace The workspace. - * @return {!Blockly.WorkspaceComment} The created workspace comment. - * @package - */ -Blockly.WorkspaceComment.fromXml = function(xmlComment, workspace) { - var info = Blockly.WorkspaceComment.parseAttributes(xmlComment); - - var comment = new Blockly.WorkspaceComment( - workspace, info.content, info.h, info.w, info.minimized, info.id); - - if (!isNaN(info.x) && !isNaN(info.y)) { - comment.moveBy(info.x, info.y); - } - - Blockly.WorkspaceComment.fireCreateEvent(comment); - return comment; -}; - -/** - * Decode an XML comment tag and return the results in an object. - * @param {!Element} xml XML comment element. - * @return {!Object} An object containing the information about the comment. - * @package - */ -Blockly.WorkspaceComment.parseAttributes = function(xml) { - var xmlH = xml.getAttribute('h'); - var xmlW = xml.getAttribute('w'); - - return { - /* @type {string} */ - id: xml.getAttribute('id'), - /** - * The height of the comment in workspace units, or 100 if not specified. - * @type {number} - */ - h: xmlH ? parseInt(xmlH, 10) : 100, - /** - * The width of the comment in workspace units, or 100 if not specified. - * @type {number} - */ - w: xmlW ? parseInt(xmlW, 10) : 100, - /** - * The x position of the comment in workspace coordinates, or NaN if not - * specified in the XML. - * @type {number} - */ - x: parseInt(xml.getAttribute('x'), 10), - /** - * The y position of the comment in workspace coordinates, or NaN if not - * specified in the XML. - * @type {number} - */ - y: parseInt(xml.getAttribute('y'), 10), - /** - * Whether this comment is minimized. Defaults to false if not specified in - * the XML. - * @type {boolean} - */ - minimized: xml.getAttribute('minimized') == 'true' || false, - /* @type {string} */ - content: xml.textContent - }; -}; diff --git a/core/workspace_comment_render_svg.js b/core/workspace_comment_render_svg.js deleted file mode 100644 index 94cf850ba9..0000000000 --- a/core/workspace_comment_render_svg.js +++ /dev/null @@ -1,723 +0,0 @@ -/** - * @license - * Visual Blocks Editor - * - * Copyright 2017 Google Inc. - * https://developers.google.com/blockly/ - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @fileoverview Methods for rendering a workspace comment as SVG - * @author fenichel@google.com (Rachel Fenichel) - */ -'use strict'; - -goog.provide('Blockly.WorkspaceCommentSvg.render'); - -goog.require('Blockly.WorkspaceCommentSvg'); - -/** - * Radius of the border around the comment. - * @type {number} - * @const - * @private - */ -Blockly.WorkspaceCommentSvg.BORDER_WIDTH = 1; - -/** - * Size of the resize icon. - * @type {number} - * @const - * @private - */ -Blockly.WorkspaceCommentSvg.RESIZE_SIZE = 16; - -/** - * Offset from the foreignobject edge to the textarea edge. - * @type {number} - * @const - * @private - */ -Blockly.WorkspaceCommentSvg.TEXTAREA_OFFSET = 12; - -/** - * The height of the comment top bar. - * @package - */ -Blockly.WorkspaceCommentSvg.TOP_BAR_HEIGHT = 32; - -/** - * The size of the minimize arrow icon in the comment top bar. - * @private - */ -Blockly.WorkspaceCommentSvg.MINIMIZE_ICON_SIZE = 32; - -/** - * The size of the delete icon in the comment top bar. - * @private - */ -Blockly.WorkspaceCommentSvg.DELETE_ICON_SIZE = 32; - -/** - * The inset for the top bar icons. - * @private - */ -Blockly.WorkspaceCommentSvg.TOP_BAR_ICON_INSET = 0; - -/** - * The bottom corner padding of the resize handle touch target. - * Extends slightly outside the comment box. - * @private - */ -Blockly.WorkspaceCommentSvg.RESIZE_CORNER_PAD = 4; - -/** - * The top/side padding around resize handle touch target. - * Extends about one extra "diagonal" above resize handle. - * @private - */ -Blockly.WorkspaceCommentSvg.RESIZE_OUTER_PAD = 8; - -/** - * Width that a minimized comment should have. - * @private - */ -Blockly.WorkspaceCommentSvg.MINIMIZE_WIDTH = 200; - -/** - * Returns a bounding box describing the dimensions of this comment. - * @return {!{height: number, width: number}} Object with height and width - * properties in workspace units. - * @package - */ -Blockly.WorkspaceCommentSvg.prototype.getHeightWidth = function() { - return { width: this.getWidth(), height: this.getHeight() }; -}; - -/** - * Renders the workspace comment. - * @package - */ -Blockly.WorkspaceCommentSvg.prototype.render = function() { - if (this.rendered_) { - return; - } - - var size = this.getHeightWidth(); - - // Add text area - this.commentEditor_ = this.createEditor_(); - this.svgGroup_.appendChild(this.commentEditor_); - - this.createCommentTopBar_(); - - this.svgRectTarget_ = Blockly.utils.createSvgElement('rect', - { - 'class': 'blocklyDraggable scratchCommentTarget', - 'x': 0, - 'y': Blockly.WorkspaceCommentSvg.TOP_BAR_HEIGHT, - 'rx': 4 * Blockly.WorkspaceCommentSvg.BORDER_WIDTH, - 'ry': 4 * Blockly.WorkspaceCommentSvg.BORDER_WIDTH - }); - this.svgGroup_.appendChild(this.svgRectTarget_); - - // Add the resize icon - this.addResizeDom_(); - - // Show / hide relevant things based on minimized state - if (this.isMinimized()) { - this.minimizeArrow_.setAttributeNS('http://www.w3.org/1999/xlink', - 'xlink:href', Blockly.mainWorkspace.options.pathToMedia + 'comment-arrow-up.svg'); - this.commentEditor_.setAttribute('display', 'none'); - this.resizeGroup_.setAttribute('display', 'none'); - } else { - this.minimizeArrow_.setAttributeNS('http://www.w3.org/1999/xlink', - 'xlink:href', Blockly.mainWorkspace.options.pathToMedia + 'comment-arrow-down.svg'); - this.topBarLabel_.setAttribute('display', 'none'); - } - - this.setSize(size.width, size.height); - - // Set the content - this.textarea_.value = this.content_; - - this.rendered_ = true; - - if (this.resizeGroup_) { - Blockly.bindEventWithChecks_( - this.resizeGroup_, 'mousedown', this, this.resizeMouseDown_); - Blockly.bindEventWithChecks_( - this.resizeGroup_, 'mouseup', this, this.resizeMouseUp_); - } - - Blockly.bindEventWithChecks_( - this.minimizeArrow_, 'mousedown', this, this.minimizeArrowMouseDown_, true); - Blockly.bindEventWithChecks_( - this.minimizeArrow_, 'mouseout', this, this.minimizeArrowMouseOut_, true); - Blockly.bindEventWithChecks_( - this.minimizeArrow_, 'mouseup', this, this.minimizeArrowMouseUp_, true); - Blockly.bindEventWithChecks_( - this.deleteIcon_, 'mousedown', this, this.deleteMouseDown_, true); - Blockly.bindEventWithChecks_( - this.deleteIcon_, 'mouseout', this, this.deleteMouseOut_, true); - Blockly.bindEventWithChecks_( - this.deleteIcon_, 'mouseup', this, this.deleteMouseUp_, true); -}; - -/** - * Create the text area for the comment. - * @return {!Element} The top-level node of the editor. - * @private - */ -Blockly.WorkspaceCommentSvg.prototype.createEditor_ = function() { - this.foreignObject_ = Blockly.utils.createSvgElement( - 'foreignObject', - { - 'x': Blockly.WorkspaceCommentSvg.BORDER_WIDTH, - 'y': Blockly.WorkspaceCommentSvg.BORDER_WIDTH + Blockly.WorkspaceCommentSvg.TOP_BAR_HEIGHT, - 'class': 'scratchCommentForeignObject' - }, - null); - var body = document.createElementNS(Blockly.HTML_NS, 'body'); - body.setAttribute('xmlns', Blockly.HTML_NS); - body.className = 'blocklyMinimalBody scratchCommentBody'; - var textarea = document.createElementNS(Blockly.HTML_NS, 'textarea'); - textarea.className = 'scratchCommentTextarea scratchCommentText'; - textarea.setAttribute('dir', this.RTL ? 'RTL' : 'LTR'); - textarea.setAttribute('maxlength', Blockly.WorkspaceComment.COMMENT_TEXT_LIMIT); - textarea.setAttribute('placeholder', Blockly.Msg.WORKSPACE_COMMENT_DEFAULT_TEXT); - body.appendChild(textarea); - this.textarea_ = textarea; - this.textarea_.style.margin = (Blockly.WorkspaceCommentSvg.TEXTAREA_OFFSET) + 'px'; - this.foreignObject_.appendChild(body); - Blockly.bindEventWithChecks_(textarea, 'mousedown', this, function(e) { - e.stopPropagation(); // Propagation causes preventDefault from workspace handler - }, true, true); - // Don't zoom with mousewheel. - Blockly.bindEventWithChecks_(textarea, 'wheel', this, function(e) { - e.stopPropagation(); - }); - Blockly.bindEventWithChecks_(textarea, 'change', this, function(_e) { - if (this.text_ != textarea.value) { - this.setText(textarea.value); - } - }); - - this.labelText_ = this.getLabelText(); - - return this.foreignObject_; -}; - -/** - * Add the resize icon to the DOM - * @private - */ -Blockly.WorkspaceCommentSvg.prototype.addResizeDom_ = function() { - this.resizeGroup_ = Blockly.utils.createSvgElement( - 'g', - { - 'class': this.RTL ? 'scratchCommentResizeSW' : 'scratchCommentResizeSE' - }, - this.svgGroup_); - var resizeSize = Blockly.WorkspaceCommentSvg.RESIZE_SIZE; - var outerPad = Blockly.ScratchBubble.RESIZE_OUTER_PAD; - var cornerPad = Blockly.ScratchBubble.RESIZE_CORNER_PAD; - // Build an (invisible) triangle that will catch resizes. It is padded on the - // top/left by outerPad, and padded down/right by cornerPad. - Blockly.utils.createSvgElement('polygon', - { - 'points': [ - -outerPad, resizeSize + cornerPad, - resizeSize + cornerPad, resizeSize + cornerPad, - resizeSize + cornerPad, -outerPad - ].join(' ') - }, - this.resizeGroup_); - Blockly.utils.createSvgElement( - 'line', - { - 'class': 'blocklyResizeLine', - 'x1': resizeSize / 3, 'y1': resizeSize - 1, - 'x2': resizeSize - 1, 'y2': resizeSize / 3 - }, this.resizeGroup_); - Blockly.utils.createSvgElement( - 'line', - { - 'class': 'blocklyResizeLine', - 'x1': resizeSize * 2 / 3, 'y1': resizeSize - 1, - 'x2': resizeSize - 1, 'y2': resizeSize * 2 / 3 - }, this.resizeGroup_); -}; - -/** - * Create the comment top bar and its contents. - * @private - */ -Blockly.WorkspaceCommentSvg.prototype.createCommentTopBar_ = function() { - this.svgHandleTarget_ = Blockly.utils.createSvgElement('rect', - { - 'class': 'blocklyDraggable scratchCommentTopBar', - 'rx': Blockly.WorkspaceCommentSvg.BORDER_WIDTH, - 'ry': Blockly.WorkspaceCommentSvg.BORDER_WIDTH, - 'height': Blockly.WorkspaceCommentSvg.TOP_BAR_HEIGHT - }, this.svgGroup_); - - this.createTopBarIcons_(); - this.createTopBarLabel_(); -}; - -/** - * Create the comment top bar label. This is the truncated comment text - * that shows when comment is minimized. - * @private - */ -Blockly.WorkspaceCommentSvg.prototype.createTopBarLabel_ = function() { - this.topBarLabel_ = Blockly.utils.createSvgElement('text', - { - 'class': 'scratchCommentText', - 'x': this.width_ / 2, - 'y': (Blockly.WorkspaceCommentSvg.TOP_BAR_HEIGHT / 2) + Blockly.WorkspaceCommentSvg.BORDER_WIDTH, - 'text-anchor': 'middle', - 'dominant-baseline': 'middle' - }, this.svgGroup_); - - var labelTextNode = document.createTextNode(this.labelText_); - this.topBarLabel_.appendChild(labelTextNode); -}; - -/** - * Create the minimize toggle and delete icons that in the comment top bar. - * @private - */ -Blockly.WorkspaceCommentSvg.prototype.createTopBarIcons_ = function() { - var topBarMiddleY = (Blockly.WorkspaceCommentSvg.TOP_BAR_HEIGHT / 2) + - Blockly.WorkspaceCommentSvg.BORDER_WIDTH; - - // Minimize Toggle Icon in Comment Top Bar - var xInset = Blockly.WorkspaceCommentSvg.TOP_BAR_ICON_INSET; - this.minimizeArrow_ = Blockly.utils.createSvgElement('image', - { - 'x': xInset, - 'y': topBarMiddleY - Blockly.WorkspaceCommentSvg.MINIMIZE_ICON_SIZE / 2, - 'width': Blockly.WorkspaceCommentSvg.MINIMIZE_ICON_SIZE, - 'height': Blockly.WorkspaceCommentSvg.MINIMIZE_ICON_SIZE - }, this.svgGroup_); - - // Delete Icon in Comment Top Bar - this.deleteIcon_ = Blockly.utils.createSvgElement('image', - { - 'x': xInset, - 'y': topBarMiddleY - Blockly.WorkspaceCommentSvg.DELETE_ICON_SIZE / 2, - 'width': Blockly.WorkspaceCommentSvg.DELETE_ICON_SIZE, - 'height': Blockly.WorkspaceCommentSvg.DELETE_ICON_SIZE - }, this.svgGroup_); - this.deleteIcon_.setAttributeNS('http://www.w3.org/1999/xlink', - 'xlink:href', Blockly.mainWorkspace.options.pathToMedia + 'delete-x.svg'); -}; - -/** - * Handle a mouse-down on bubble's minimize icon. - * @param {!Event} e Mouse down event. - * @private - */ -Blockly.WorkspaceCommentSvg.prototype.minimizeArrowMouseDown_ = function(e) { - // Set a property to indicate that this minimize arrow icon had a mouse down - // event. This property will get reset if the mouse leaves the icon, or when - // a mouse up event occurs on this icon. - this.shouldToggleMinimize_ = true; - e.stopPropagation(); -}; - -/** - * Handle a mouse-out on bubble's minimize icon. - * @param {!Event} _e Mouse out event. - * @private - */ -Blockly.WorkspaceCommentSvg.prototype.minimizeArrowMouseOut_ = function(_e) { - // If the mouse leaves the minimize arrow icon, make sure the - // shouldToggleMinimize_ property gets reset. - this.shouldToggleMinimize_ = false; -}; - -/** - * Handle a mouse-up on bubble's minimize icon. - * @param {!Event} e Mouse up event. - * @private - */ -Blockly.WorkspaceCommentSvg.prototype.minimizeArrowMouseUp_ = function(e) { - // First check if this is the icon that had a mouse down event on it and that - // the mouse never left the icon. - if (this.shouldToggleMinimize_) { - this.shouldToggleMinimize = false; - this.toggleMinimize_(); - } - e.stopPropagation(); -}; - -/** - * Handle a mouse-down on bubble's minimize icon. - * @param {!Event} e Mouse down event. - * @private - */ -Blockly.WorkspaceCommentSvg.prototype.deleteMouseDown_ = function(e) { - // Set a property to indicate that this delete icon had a mouse down event. - // This property will get reset if the mouse leaves the icon, or when - // a mouse up event occurs on this icon. - this.shouldDelete_ = true; - e.stopPropagation(); -}; - -/** - * Handle a mouse-out on bubble's minimize icon. - * @param {!Event} _e Mouse out event. - * @private - */ -Blockly.WorkspaceCommentSvg.prototype.deleteMouseOut_ = function(_e) { - // If the mouse leaves the delete icon, reset the shouldDelete_ property. - this.shouldDelete_ = false; -}; - -/** - * Handle a mouse-up on bubble's delete icon. - * @param {!Event} e Mouse up event. - * @private - */ -Blockly.WorkspaceCommentSvg.prototype.deleteMouseUp_ = function(e) { - // First check that this same icon had a mouse down event on it and that the - // mouse never left the icon. - if (this.shouldDelete_) { - this.dispose(); - } - e.stopPropagation(); -}; - -/** - * Handle a mouse-down on comment's resize corner. - * @param {!Event} e Mouse down event. - * @private - */ -Blockly.WorkspaceCommentSvg.prototype.resizeMouseDown_ = function(e) { - this.resizeStartSize_ = {width: this.width_, height: this.height_}; - this.unbindDragEvents_(); - this.workspace.setResizesEnabled(false); - if (Blockly.utils.isRightButton(e)) { - // No right-click. - e.stopPropagation(); - return; - } - // Left-click (or middle click) - this.workspace.startDrag(e, new goog.math.Coordinate( - this.workspace.RTL ? -this.width_ : this.width_, this.height_)); - - this.onMouseUpWrapper_ = Blockly.bindEventWithChecks_( - document, 'mouseup', this, this.resizeMouseUp_); - this.onMouseMoveWrapper_ = Blockly.bindEventWithChecks_( - document, 'mousemove', this, this.resizeMouseMove_); - Blockly.hideChaff(); - // This event has been handled. No need to bubble up to the document. - e.stopPropagation(); -}; - - -/** - * Set the apperance of the workspace comment bubble to the minimized or full size - * appearance. In the minimized state, the comment should only have the top bar - * displayed, with the minimize icon swapped to the minimized state, and - * truncated comment text is shown in the middle of the top bar. There should be - * no resize handle when the workspace comment is in its minimized state. - * @param {boolean} minimize Whether the bubble should be minimized - * @param {?string} labelText Optional label text for the comment top bar - * when it is minimized. - * @private - */ -Blockly.WorkspaceCommentSvg.prototype.setRenderedMinimizeState_ = function(minimize, labelText) { - if (minimize) { - // Change minimize icon - this.minimizeArrow_.setAttributeNS('http://www.w3.org/1999/xlink', - 'xlink:href', Blockly.mainWorkspace.options.pathToMedia + 'comment-arrow-up.svg'); - // Hide text area - this.commentEditor_.setAttribute('display', 'none'); - // Hide resize handle if it exists - if (this.resizeGroup_) { - this.resizeGroup_.setAttribute('display', 'none'); - } - if (labelText && this.labelText_ != labelText) { - // Update label and display - // TODO is there a better way to do this? - this.topBarLabel_.textContent = labelText; - } - Blockly.utils.removeAttribute(this.topBarLabel_, 'display'); - } else { - // Change minimize icon - this.minimizeArrow_.setAttributeNS('http://www.w3.org/1999/xlink', - 'xlink:href', Blockly.mainWorkspace.options.pathToMedia + 'comment-arrow-down.svg'); - // Hide label - this.topBarLabel_.setAttribute('display', 'none'); - // Show text area - Blockly.utils.removeAttribute(this.commentEditor_, 'display'); - // Display resize handle if it exists - if (this.resizeGroup_) { - Blockly.utils.removeAttribute(this.resizeGroup_, 'display'); - } - } -}; - -/** - * Stop binding to the global mouseup and mousemove events. - * @private - */ -Blockly.WorkspaceCommentSvg.prototype.unbindDragEvents_ = function() { - if (this.onMouseUpWrapper_) { - Blockly.unbindEvent_(this.onMouseUpWrapper_); - this.onMouseUpWrapper_ = null; - } - if (this.onMouseMoveWrapper_) { - Blockly.unbindEvent_(this.onMouseMoveWrapper_); - this.onMouseMoveWrapper_ = null; - } -}; - -/* - * Handle a mouse-up event while dragging a comment's border or resize handle. - * @param {!Event} e Mouse up event. - * @private - */ -Blockly.WorkspaceCommentSvg.prototype.resizeMouseUp_ = function(/*e*/) { - Blockly.Touch.clearTouchIdentifier(); - this.unbindDragEvents_(); - var oldHW = this.resizeStartSize_; - this.resizeStartSize_ = null; - if (this.width_ == oldHW.width && this.height_ == oldHW.height) { - return; - } - // Fire a change event for the new width/height after - // resize mouse up - Blockly.Events.fire(new Blockly.Events.CommentChange( - this, {width: oldHW.width , height: oldHW.height}, - {width: this.width_, height: this.height_})); - - this.workspace.setResizesEnabled(true); -}; - -/** - * Resize this comment to follow the mouse. - * @param {!Event} e Mouse move event. - * @private - */ -Blockly.WorkspaceCommentSvg.prototype.resizeMouseMove_ = function(e) { - this.autoLayout_ = false; - var newXY = this.workspace.moveDrag(e); - // The call to setSize below emits a CommentChange event, - // but we don't want multiple CommentChange events to be - // emitted while the user is still in the process of resizing - // the comment, so disable events here. The event is emitted in - // resizeMouseUp_. - var disabled = false; - if (Blockly.Events.isEnabled()) { - Blockly.Events.disable(); - disabled = true; - } - this.setSize(this.RTL ? -newXY.x : newXY.x, newXY.y); - if (disabled) { - Blockly.Events.enable(); - } -}; - -/** - * Callback function triggered when the comment has resized. - * Resize the text area accordingly. - * @private - */ -Blockly.WorkspaceCommentSvg.prototype.resizeComment_ = function() { - var doubleBorderWidth = 2 * Blockly.WorkspaceCommentSvg.BORDER_WIDTH; - var topOffset = Blockly.WorkspaceCommentSvg.TOP_BAR_HEIGHT; - var textOffset = Blockly.WorkspaceCommentSvg.TEXTAREA_OFFSET * 2; - - this.foreignObject_.setAttribute('width', - this.width_ - doubleBorderWidth); - this.foreignObject_.setAttribute('height', - this.height_ - doubleBorderWidth - topOffset); - if (this.RTL) { - this.foreignObject_.setAttribute('x', - -this.width_); - } - this.textarea_.style.width = - (this.width_ - textOffset) + 'px'; - this.textarea_.style.height = - (this.height_ - doubleBorderWidth - textOffset - topOffset) + 'px'; -}; - -/** - * Set size - * @param {number} width width of the container - * @param {number} height height of the container - * @package - */ -Blockly.WorkspaceCommentSvg.prototype.setSize = function(width, height) { - var oldWidth = this.width_; - var oldHeight = this.height_; - - var doubleBorderWidth = 2 * Blockly.WorkspaceCommentSvg.BORDER_WIDTH; - - if (this.isMinimized_) { - width = Blockly.WorkspaceCommentSvg.MINIMIZE_WIDTH; - height = Blockly.WorkspaceCommentSvg.TOP_BAR_HEIGHT; - } else { - // Minimum size of a 'full size' (not minimized) comment. - width = Math.max(width, doubleBorderWidth + 50); - height = Math.max(height, doubleBorderWidth + 20 + Blockly.WorkspaceCommentSvg.TOP_BAR_HEIGHT); - - // Note we are only updating this.width_ or this.height_ here - // and not in the case above, because when we're minimizing a comment, - // we want to keep track of the width/height of the maximized comment - this.width_ = width; - this.height_ = height; - Blockly.Events.fire(new Blockly.Events.CommentChange(this, - {width: oldWidth, height: oldHeight}, - {width: this.width_, height: this.height_})); - } - this.svgRect_.setAttribute('width', width); - this.svgRect_.setAttribute('height', height); - this.svgRectTarget_.setAttribute('width', width); - this.svgRectTarget_.setAttribute('height', height - Blockly.WorkspaceCommentSvg.TOP_BAR_HEIGHT); - this.svgHandleTarget_.setAttribute('width', width); - this.svgHandleTarget_.setAttribute('height', Blockly.WorkspaceCommentSvg.TOP_BAR_HEIGHT); - if (this.RTL) { - this.minimizeArrow_.setAttribute('x', width - - (Blockly.WorkspaceCommentSvg.MINIMIZE_ICON_SIZE) - - Blockly.WorkspaceCommentSvg.TOP_BAR_ICON_INSET); - this.deleteIcon_.setAttribute('x', (-width + - Blockly.WorkspaceCommentSvg.TOP_BAR_ICON_INSET)); - this.svgRect_.setAttribute('transform', 'scale(-1 1)'); - this.svgHandleTarget_.setAttribute('transform', 'scale(-1 1)'); - this.svgHandleTarget_.setAttribute('transform', 'translate(' + -width + ', 1)'); - this.minimizeArrow_.setAttribute('transform', 'translate(' + -width + ', 1)'); - this.deleteIcon_.setAttribute('tranform', 'translate(' + -width + ', 1)'); - this.svgRectTarget_.setAttribute('transform', 'translate(' + -width + ', 1)'); - this.topBarLabel_.setAttribute('transform', 'translate(' + -width + ', 1)'); - } else { - this.deleteIcon_.setAttribute('x', width - - Blockly.WorkspaceCommentSvg.DELETE_ICON_SIZE - - Blockly.WorkspaceCommentSvg.TOP_BAR_ICON_INSET); - } - - var resizeSize = Blockly.WorkspaceCommentSvg.RESIZE_SIZE; - if (this.resizeGroup_) { - if (this.RTL) { - // Mirror the resize group. - this.resizeGroup_.setAttribute('transform', 'translate(' + - (-width + doubleBorderWidth + resizeSize) + ',' + - (height - doubleBorderWidth - resizeSize) + ') scale(-1 1)'); - } else { - this.resizeGroup_.setAttribute('transform', 'translate(' + - (width - doubleBorderWidth - resizeSize) + ',' + - (height - doubleBorderWidth - resizeSize) + ')'); - } - } - - if (this.isMinimized_) { - this.topBarLabel_.setAttribute('x', width / 2); - this.topBarLabel_.setAttribute('y', height / 2); - } - - // Allow the contents to resize. - this.resizeComment_(); -}; - -/** - * Toggle the minimization state of this comment. - * @private - */ -Blockly.WorkspaceComment.prototype.toggleMinimize_ = function() { - this.setMinimized(!this.isMinimized_); -}; - -/** - * Set the minimized state for this comment. If the comment is rendered, - * change the appearance of the comment accordingly. - * @param {boolean} minimize Whether the comment should be minimized - * @package - */ -Blockly.WorkspaceComment.prototype.setMinimized = function(minimize) { - if (this.isMinimized_ == minimize) { - return; - } - Blockly.Events.fire(new Blockly.Events.CommentChange(this, - {minimized: this.isMinimized_}, {minimized: minimize})); - this.isMinimized_ = minimize; - if (minimize) { - if (this.rendered_) { - this.setRenderedMinimizeState_(true, this.getLabelText()); - } - this.setSize(Blockly.WorkspaceCommentSvg.MINIMIZE_WIDTH, - Blockly.WorkspaceCommentSvg.TOP_BAR_HEIGHT); - } else { - if (this.rendered_) { - this.setRenderedMinimizeState_(false); - } - this.setText(this.content_); - this.setSize(this.width_, this.height_); - } -}; - -/** - * Dispose of any rendered comment components. - * @private - */ -Blockly.WorkspaceCommentSvg.prototype.disposeInternal_ = function() { - this.textarea_ = null; - this.foreignObject_ = null; - this.svgRect_ = null; - this.svgRectTarget_ = null; - this.svgHandleTarget_ = null; -}; - -/** - * Set the focus on the text area. - * @package - */ -Blockly.WorkspaceCommentSvg.prototype.setFocus = function() { - var comment = this; - this.focused_ = true; - comment.textarea_.focus(); - // Defer CSS changes. - setTimeout(function() { - comment.addFocus(); - Blockly.utils.addClass( - comment.svgRectTarget_, 'scratchCommentTargetFocused'); - Blockly.utils.addClass( - comment.svgHandleTarget_, 'scratchCommentHandleTargetFocused'); - }, 0); -}; - -/** - * Remove focus from the text area. - * @package - */ -Blockly.WorkspaceCommentSvg.prototype.blurFocus = function() { - var comment = this; - this.focused_ = false; - comment.textarea_.blur(); - // Defer CSS changes. - setTimeout(function() { - if (comment.svgGroup_) { // Could have been deleted in the meantime - comment.removeFocus(); - Blockly.utils.removeClass( - comment.svgRectTarget_, 'scratchCommentTargetFocused'); - Blockly.utils.removeClass( - comment.svgHandleTarget_, 'scratchCommentHandleTargetFocused'); - } - }, 0); -}; diff --git a/core/workspace_comment_svg.js b/core/workspace_comment_svg.js deleted file mode 100644 index 2c7aa2bdc7..0000000000 --- a/core/workspace_comment_svg.js +++ /dev/null @@ -1,611 +0,0 @@ -/** - * @license - * Visual Blocks Editor - * - * Copyright 2017 Google Inc. - * https://developers.google.com/blockly/ - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @fileoverview Object representing a code comment on a rendered workspace. - * @author fenichel@google.com (Rachel Fenichel) - */ -'use strict'; - -goog.provide('Blockly.WorkspaceCommentSvg'); - -goog.require('Blockly.Events.CommentCreate'); -goog.require('Blockly.Events.CommentDelete'); -goog.require('Blockly.Events.CommentMove'); -goog.require('Blockly.WorkspaceComment'); - - -/** - * Class for a workspace comment's SVG representation. - * @param {!Blockly.Workspace} workspace The block's workspace. - * @param {string} content The content of this workspace comment. - * @param {number} height Height of the comment. - * @param {number} width Width of the comment. - * @param {boolean} minimized Whether this comment is minimized. - * @param {string=} opt_id Optional ID. Use this ID if provided, otherwise - * create a new ID. - * @extends {Blockly.WorkspaceComment} - * @constructor - */ -Blockly.WorkspaceCommentSvg = function(workspace, content, height, width, minimized, - opt_id) { - // Create core elements for the block. - /** - * @type {SVGElement} - * @private - */ - this.svgGroup_ = Blockly.utils.createSvgElement( - 'g', {}, null); - this.svgGroup_.translate_ = ''; - - this.svgRect_ = Blockly.utils.createSvgElement( - 'rect', - { - 'class': 'scratchCommentRect scratchWorkspaceCommentBorder', - 'x': 0, - 'y': 0, - 'rx': 4 * Blockly.WorkspaceCommentSvg.BORDER_WIDTH, - 'ry': 4 * Blockly.WorkspaceCommentSvg.BORDER_WIDTH - }); - this.svgGroup_.appendChild(this.svgRect_); - - - /** - * Whether the comment is rendered onscreen and is a part of the DOM. - * @type {boolean} - * @private - */ - this.rendered_ = false; - - /** - * Whether to move the comment to the drag surface when it is dragged. - * True if it should move, false if it should be translated directly. - * @type {boolean} - * @private - */ - this.useDragSurface_ = - Blockly.utils.is3dSupported() && !!workspace.blockDragSurface_; - - Blockly.WorkspaceCommentSvg.superClass_.constructor.call(this, - workspace, content, height, width, minimized, opt_id); - - this.render(); -}; goog.inherits(Blockly.WorkspaceCommentSvg, Blockly.WorkspaceComment); - -/** - * The width and height to use to size a workspace comment when it is first - * added, before it has been edited by the user. - * @type {number} - * @package - */ -Blockly.WorkspaceCommentSvg.DEFAULT_SIZE = 200; - -/** - * Dispose of this comment. - * @package - */ -Blockly.WorkspaceCommentSvg.prototype.dispose = function() { - if (!this.workspace) { - // The comment has already been deleted. - return; - } - // If this comment is being deleted, unlink the mouse events. - if (Blockly.selected == this) { - this.unselect(); - this.workspace.cancelCurrentGesture(); - } - - if (Blockly.Events.isEnabled()) { - Blockly.Events.fire(new Blockly.Events.CommentDelete(this)); - } - - goog.dom.removeNode(this.svgGroup_); - // Sever JavaScript to DOM connections. - this.svgGroup_ = null; - this.svgRect_ = null; - // Dispose of any rendered components - this.disposeInternal_(); - - Blockly.Events.disable(); - Blockly.WorkspaceCommentSvg.superClass_.dispose.call(this); - Blockly.Events.enable(); -}; - -/** - * Create and initialize the SVG representation of a workspace comment. - * May be called more than once. - * @package - */ -Blockly.WorkspaceCommentSvg.prototype.initSvg = function() { - goog.asserts.assert(this.workspace.rendered, 'Workspace is headless.'); - if (!this.workspace.options.readOnly && !this.eventsInit_) { - Blockly.bindEventWithChecks_( - this.svgRectTarget_, 'mousedown', this, this.pathMouseDown_); - Blockly.bindEventWithChecks_( - this.svgHandleTarget_, 'mousedown', this, this.pathMouseDown_); - } - this.eventsInit_ = true; - - this.updateMovable(); - if (!this.getSvgRoot().parentNode) { - this.workspace.getBubbleCanvas().appendChild(this.getSvgRoot()); - } -}; - -/** - * Handle a mouse-down on an SVG comment. - * @param {!Event} e Mouse down event or touch start event. - * @private - */ -Blockly.WorkspaceCommentSvg.prototype.pathMouseDown_ = function(e) { - var gesture = this.workspace.getGesture(e); - if (gesture) { - gesture.handleBubbleStart(e, this); - } -}; - -/** - * Show the context menu for this workspace comment. - * @param {!Event} e Mouse event. - * @private - */ -Blockly.WorkspaceCommentSvg.prototype.showContextMenu_ = function(e) { - if (this.workspace.options.readOnly) { - return; - } - // Save the current workspace comment in a variable for use in closures. - var comment = this; - var menuOptions = []; - - if (this.isDeletable() && this.isMovable()) { - menuOptions.push(Blockly.ContextMenu.commentDuplicateOption(comment)); - menuOptions.push(Blockly.ContextMenu.commentDeleteOption(comment)); - } - - Blockly.ContextMenu.show(e, menuOptions, this.RTL); -}; - -/** - * Select this comment. Highlight it visually. - * @package - */ -Blockly.WorkspaceCommentSvg.prototype.select = function() { - if (Blockly.selected == this) { - return; - } - var oldId = null; - if (Blockly.selected) { - oldId = Blockly.selected.id; - // Unselect any previously selected block or comment. - Blockly.Events.disable(); - try { - Blockly.selected.unselect(); - } finally { - Blockly.Events.enable(); - } - } - var event = new Blockly.Events.Ui(null, 'selected', oldId, this.id); - event.workspaceId = this.workspace.id; - Blockly.Events.fire(event); - Blockly.selected = this; - this.addSelect(); -}; - -/** - * Unselect this comment. Remove its highlighting. - * @package - */ -Blockly.WorkspaceCommentSvg.prototype.unselect = function() { - if (Blockly.selected != this) { - return; - } - var event = new Blockly.Events.Ui(null, 'selected', this.id, null); - event.workspaceId = this.workspace.id; - Blockly.Events.fire(event); - Blockly.selected = null; - this.removeSelect(); -}; - -/** - * Select this comment. Highlight it visually. - * @package - */ -Blockly.WorkspaceCommentSvg.prototype.addSelect = function() { - Blockly.utils.addClass( - /** @type {!Element} */ (this.svgGroup_), 'blocklySelected'); - this.setFocus(); -}; - -/** - * Unselect this comment. Remove its highlighting. - * @package - */ -Blockly.WorkspaceCommentSvg.prototype.removeSelect = function() { - Blockly.utils.removeClass( - /** @type {!Element} */ (this.svgGroup_), 'blocklySelected'); - this.blurFocus(); -}; - -/** - * Focus this comment. Highlight it visually. - * @package - */ -Blockly.WorkspaceCommentSvg.prototype.addFocus = function() { - Blockly.utils.addClass( - /** @type {!Element} */ (this.svgGroup_), 'blocklyFocused'); -}; - -/** - * Unfocus this comment. Remove its highlighting. - * @package - */ -Blockly.WorkspaceCommentSvg.prototype.removeFocus = function() { - Blockly.utils.removeClass( - /** @type {!Element} */ (this.svgGroup_), 'blocklyFocused'); -}; - -/** - * Return the coordinates of the top-left corner of this comment relative to the - * drawing surface's origin (0,0), in workspace units. - * If the comment is on the workspace, (0, 0) is the origin of the workspace - * coordinate system. - * This does not change with workspace scale. - * @return {!goog.math.Coordinate} Object with .x and .y properties in - * workspace coordinates. - * @package - */ -Blockly.WorkspaceCommentSvg.prototype.getRelativeToSurfaceXY = function() { - var x = 0; - var y = 0; - - var dragSurfaceGroup = this.useDragSurface_ ? - this.workspace.blockDragSurface_.getGroup() : null; - - var element = this.getSvgRoot(); - if (element) { - do { - // Loop through this comment and every parent. - var xy = Blockly.utils.getRelativeXY(element); - x += xy.x; - y += xy.y; - // If this element is the current element on the drag surface, include - // the translation of the drag surface itself. - if (this.useDragSurface_ && - this.workspace.blockDragSurface_.getCurrentBlock() == element) { - var surfaceTranslation = - this.workspace.blockDragSurface_.getSurfaceTranslation(); - x += surfaceTranslation.x; - y += surfaceTranslation.y; - } - element = element.parentNode; - } while (element && element != this.workspace.getBubbleCanvas() && - element != dragSurfaceGroup); - } - this.xy_ = new goog.math.Coordinate(x, y); - return this.xy_; -}; - -/** - * Move a comment by a relative offset. - * @param {number} dx Horizontal offset, in workspace units. - * @param {number} dy Vertical offset, in workspace units. - * @package - */ -Blockly.WorkspaceCommentSvg.prototype.moveBy = function(dx, dy) { - var event = new Blockly.Events.CommentMove(this); - // TODO: Do I need to look up the relative to surface XY position here? - var xy = this.getRelativeToSurfaceXY(); - this.translate(xy.x + dx, xy.y + dy); - event.recordNew(); - Blockly.Events.fire(event); - this.workspace.resizeContents(); -}; - -/** - * Transforms a comment by setting the translation on the transform attribute - * of the block's SVG. - * @param {number} x The x coordinate of the translation in workspace units. - * @param {number} y The y coordinate of the translation in workspace units. - * @package - */ -Blockly.WorkspaceCommentSvg.prototype.translate = function(x, y) { - this.xy_ = new goog.math.Coordinate(x, y); - this.getSvgRoot().setAttribute('transform', - 'translate(' + x + ',' + y + ')'); -}; - -/** - * Move this comment to its workspace's drag surface, accounting for positioning. - * Generally should be called at the same time as setDragging(true). - * Does nothing if useDragSurface_ is false. - * @private - */ -Blockly.WorkspaceCommentSvg.prototype.moveToDragSurface_ = function() { - if (!this.useDragSurface_) { - return; - } - // The translation for drag surface blocks, - // is equal to the current relative-to-surface position, - // to keep the position in sync as it move on/off the surface. - // This is in workspace coordinates. - var xy = this.getRelativeToSurfaceXY(); - this.clearTransformAttributes_(); - this.workspace.blockDragSurface_.translateSurface(xy.x, xy.y); - // Execute the move on the top-level SVG component - this.workspace.blockDragSurface_.setBlocksAndShow(this.getSvgRoot()); -}; - -/** - * Move this comment back to the workspace block canvas. - * Generally should be called at the same time as setDragging(false). - * Does nothing if useDragSurface_ is false. - * @param {!goog.math.Coordinate} newXY The position the comment should take on - * on the workspace canvas, in workspace coordinates. - * @private - */ -Blockly.WorkspaceCommentSvg.prototype.moveOffDragSurface_ = function(newXY) { - if (!this.useDragSurface_) { - return; - } - // Translate to current position, turning off 3d. - this.translate(newXY.x, newXY.y); - this.workspace.blockDragSurface_.clearAndHide(this.workspace.getCanvas()); -}; - -/** - * Move this comment during a drag, taking into account whether we are using a - * drag surface to translate blocks. - * @param {?Blockly.BlockDragSurfaceSvg} dragSurface The surface that carries - * rendered items during a drag, or null if no drag surface is in use. - * @param {!goog.math.Coordinate} newLoc The location to translate to, in - * workspace coordinates. - * @package - */ -Blockly.WorkspaceCommentSvg.prototype.moveDuringDrag = function(dragSurface, newLoc) { - if (dragSurface) { - dragSurface.translateSurface(newLoc.x, newLoc.y); - } else { - this.svgGroup_.translate_ = 'translate(' + newLoc.x + ',' + newLoc.y + ')'; - this.svgGroup_.setAttribute('transform', - this.svgGroup_.translate_ + this.svgGroup_.skew_); - } -}; - -/** - * Move the bubble group to the specified location in workspace coordinates. - * @param {number} x The x position to move to. - * @param {number} y The y position to move to. - * @package - */ -Blockly.WorkspaceCommentSvg.prototype.moveTo = function(x, y) { - this.translate(x, y); -}; - -/** - * Clear the comment of transform="..." attributes. - * Used when the comment is switching from 3d to 2d transform or vice versa. - * @private - */ -Blockly.WorkspaceCommentSvg.prototype.clearTransformAttributes_ = function() { - Blockly.utils.removeAttribute(this.getSvgRoot(), 'transform'); -}; - -/** - * Return the rendered size of the comment or the stored size if the comment is - * not rendered. This differs from getHeightWidth in the behavior of rendered - * minimized comments. This function reports the actual size of the minimized - * comment instead of the full sized comment height/width. - * @return {!{height: number, width: number}} Object with height and width - * properties in workspace units. - * @package - */ -Blockly.WorkspaceCommentSvg.prototype.getBubbleSize = function() { - if (this.rendered_) { - return { - width: parseInt(this.svgRect_.getAttribute('width')), - height: parseInt(this.svgRect_.getAttribute('height')) - }; - } else { - this.getHeightWidth(); - } -}; - -/** - * Returns the coordinates of a bounding box describing the dimensions of this - * comment. - * Coordinate system: workspace coordinates. - * @return {!{topLeft: goog.math.Coordinate, bottomRight: goog.math.Coordinate}} - * Object with top left and bottom right coordinates of the bounding box. - * @package - */ -Blockly.WorkspaceCommentSvg.prototype.getBoundingRectangle = function() { - var blockXY = this.getRelativeToSurfaceXY(); - var commentBounds = this.getHeightWidth(); - var topLeft; - var bottomRight; - if (this.RTL) { - topLeft = new goog.math.Coordinate(blockXY.x - (commentBounds.width), - blockXY.y); - // Add the width of the tab/puzzle piece knob to the x coordinate - // since X is the corner of the rectangle, not the whole puzzle piece. - bottomRight = new goog.math.Coordinate(blockXY.x, - blockXY.y + commentBounds.height); - } else { - // Subtract the width of the tab/puzzle piece knob to the x coordinate - // since X is the corner of the rectangle, not the whole puzzle piece. - topLeft = new goog.math.Coordinate(blockXY.x, blockXY.y); - bottomRight = new goog.math.Coordinate(blockXY.x + commentBounds.width, - blockXY.y + commentBounds.height); - } - return {topLeft: topLeft, bottomRight: bottomRight}; -}; - -/** - * Add or remove the UI indicating if this comment is movable or not. - * @package - */ -Blockly.WorkspaceCommentSvg.prototype.updateMovable = function() { - if (this.isMovable()) { - Blockly.utils.addClass( - /** @type {!Element} */ (this.svgGroup_), 'blocklyDraggable'); - } else { - Blockly.utils.removeClass( - /** @type {!Element} */ (this.svgGroup_), 'blocklyDraggable'); - } -}; - -/** - * Set whether this comment is movable or not. - * @param {boolean} movable True if movable. - * @package - */ -Blockly.WorkspaceCommentSvg.prototype.setMovable = function(movable) { - Blockly.WorkspaceCommentSvg.superClass_.setMovable.call(this, movable); - this.updateMovable(); -}; - -/** - * Recursively adds or removes the dragging class to this node and its children. - * @param {boolean} adding True if adding, false if removing. - * @package - */ -Blockly.WorkspaceCommentSvg.prototype.setDragging = function(adding) { - if (adding) { - var group = this.getSvgRoot(); - group.translate_ = ''; - group.skew_ = ''; - Blockly.utils.addClass( - /** @type {!Element} */ (this.svgGroup_), 'blocklyDragging'); - } else { - Blockly.utils.removeClass( - /** @type {!Element} */ (this.svgGroup_), 'blocklyDragging'); - } -}; - -/** - * Return the root node of the SVG or null if none exists. - * @return {Element} The root SVG node (probably a group). - * @package - */ -Blockly.WorkspaceCommentSvg.prototype.getSvgRoot = function() { - return this.svgGroup_; -}; - -/** - * Returns this comment's text. - * @return {string} Comment text. - * @package - */ -Blockly.WorkspaceCommentSvg.prototype.getText = function() { - return this.textarea_ ? this.textarea_.value : this.content_; -}; - -/** - * Set this comment's text. - * @param {string} text Comment text. - * @package - */ -Blockly.WorkspaceCommentSvg.prototype.setText = function(text) { - Blockly.WorkspaceCommentSvg.superClass_.setText.call(this, text); - if (this.textarea_) { - this.textarea_.value = text; - } -}; - -/** - * Update the cursor over this comment by adding or removing a class. - * @param {boolean} enable True if the delete cursor should be shown, false - * otherwise. - * @package - */ -Blockly.WorkspaceCommentSvg.prototype.setDeleteStyle = function(enable) { - if (enable) { - Blockly.utils.addClass( - /** @type {!Element} */ (this.svgGroup_), 'blocklyDraggingDelete'); - } else { - Blockly.utils.removeClass( - /** @type {!Element} */ (this.svgGroup_), 'blocklyDraggingDelete'); - } -}; - -Blockly.WorkspaceCommentSvg.prototype.setAutoLayout = function() { - // NOP for compatibility with the bubble dragger. -}; - -/** - * Decode an XML comment tag and create a rendered comment on the workspace. - * @param {!Element} xmlComment XML comment element. - * @param {!Blockly.Workspace} workspace The workspace. - * @param {number=} opt_wsWidth The width of the workspace, which is used to - * position comments correctly in RTL. - * @return {!Blockly.WorkspaceCommentSvg} The created workspace comment. - * @package - */ -Blockly.WorkspaceCommentSvg.fromXml = function(xmlComment, workspace, - opt_wsWidth) { - Blockly.Events.disable(); - try { - var info = Blockly.WorkspaceComment.parseAttributes(xmlComment); - - var comment = new Blockly.WorkspaceCommentSvg(workspace, - info.content, info.h, info.w, info.minimized, info.id); - if (workspace.rendered) { - comment.initSvg(); - comment.render(false); - } - // Position the comment correctly, taking into account the width of a - // rendered RTL workspace. - if (!isNaN(info.x) && !isNaN(info.y)) { - if (workspace.RTL) { - var wsWidth = opt_wsWidth || workspace.getWidth(); - comment.moveBy(wsWidth - info.x, info.y); - } else { - comment.moveBy(info.x, info.y); - } - } - } finally { - Blockly.Events.enable(); - } - Blockly.WorkspaceComment.fireCreateEvent(comment); - - return comment; -}; - -/** - * Encode a comment subtree as XML with XY coordinates. - * @param {boolean=} opt_noId True if the encoder should skip the comment id. - * @return {!Element} Tree of XML elements. - * @package - */ -Blockly.WorkspaceCommentSvg.prototype.toXmlWithXY = function(opt_noId) { - var width; // Not used in LTR. - if (this.workspace.RTL) { - // Here be performance dragons: This calls getMetrics(). - width = this.workspace.getWidth(); - } - var element = this.toXml(opt_noId); - var xy = this.getRelativeToSurfaceXY(); - element.setAttribute('x', - Math.round(this.workspace.RTL ? width - xy.x : xy.x)); - element.setAttribute('y', Math.round(xy.y)); - element.setAttribute('h', this.getHeight()); - element.setAttribute('w', this.getWidth()); - return element; -}; diff --git a/core/workspace_drag_surface_svg.js b/core/workspace_drag_surface_svg.js deleted file mode 100644 index 12e5e7e009..0000000000 --- a/core/workspace_drag_surface_svg.js +++ /dev/null @@ -1,195 +0,0 @@ -/** - * @license - * Visual Blocks Editor - * - * Copyright 2016 Google Inc. - * https://developers.google.com/blockly/ - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @fileoverview An SVG that floats on top of the workspace. - * Blocks are moved into this SVG during a drag, improving performance. - * The entire SVG is translated using css translation instead of SVG so the - * blocks are never repainted during drag improving performance. - * @author katelyn@google.com (Katelyn Mann) - */ - -'use strict'; - -goog.provide('Blockly.WorkspaceDragSurfaceSvg'); - -goog.require('Blockly.utils'); - -goog.require('goog.asserts'); -goog.require('goog.math.Coordinate'); - - -/** - * Blocks are moved into this SVG during a drag, improving performance. - * The entire SVG is translated using css transforms instead of SVG so the - * blocks are never repainted during drag improving performance. - * @param {!Element} container Containing element. - * @constructor - */ -Blockly.WorkspaceDragSurfaceSvg = function(container) { - this.container_ = container; - this.createDom(); -}; - -/** - * The SVG drag surface. Set once by Blockly.WorkspaceDragSurfaceSvg.createDom. - * @type {Element} - * @private - */ -Blockly.WorkspaceDragSurfaceSvg.prototype.SVG_ = null; - -/** - * SVG group inside the drag surface that holds blocks while a drag is in - * progress. Blocks are moved here by the workspace at start of a drag and moved - * back into the main SVG at the end of a drag. - * - * @type {Element} - * @private - */ -Blockly.WorkspaceDragSurfaceSvg.prototype.dragGroup_ = null; - -/** - * Containing HTML element; parent of the workspace and the drag surface. - * @type {Element} - * @private - */ -Blockly.WorkspaceDragSurfaceSvg.prototype.container_ = null; - -/** - * Create the drag surface and inject it into the container. - */ -Blockly.WorkspaceDragSurfaceSvg.prototype.createDom = function() { - if (this.SVG_) { - return; // Already created. - } - - /** - * Dom structure when the workspace is being dragged. If there is no drag in - * progress, the SVG is empty and display: none. - * - * - * /g> - * - */ - this.SVG_ = Blockly.utils.createSvgElement('svg', - { - 'xmlns': Blockly.SVG_NS, - 'xmlns:html': Blockly.HTML_NS, - 'xmlns:xlink': 'http://www.w3.org/1999/xlink', - 'version': '1.1', - 'class': 'blocklyWsDragSurface blocklyOverflowVisible' - }, null); - this.container_.appendChild(this.SVG_); -}; - -/** - * Translate the entire drag surface during a drag. - * We translate the drag surface instead of the blocks inside the surface - * so that the browser avoids repainting the SVG. - * Because of this, the drag coordinates must be adjusted by scale. - * @param {number} x X translation for the entire surface - * @param {number} y Y translation for the entire surface - * @package - */ -Blockly.WorkspaceDragSurfaceSvg.prototype.translateSurface = function(x, y) { - // This is a work-around to prevent a the blocks from rendering - // fuzzy while they are being moved on the drag surface. - var fixedX = x.toFixed(0); - var fixedY = y.toFixed(0); - - this.SVG_.style.display = 'block'; - Blockly.utils.setCssTransform( - this.SVG_, 'translate3d(' + fixedX + 'px, ' + fixedY + 'px, 0px)'); -}; - -/** - * Reports the surface translation in scaled workspace coordinates. - * Use this when finishing a drag to return blocks to the correct position. - * @return {!goog.math.Coordinate} Current translation of the surface - * @package - */ -Blockly.WorkspaceDragSurfaceSvg.prototype.getSurfaceTranslation = function() { - return Blockly.utils.getRelativeXY(this.SVG_); -}; - -/** - * Move the blockCanvas and bubbleCanvas out of the surface SVG and on to - * newSurface. - * @param {SVGElement} newSurface The element to put the drag surface contents - * into. - * @package - */ -Blockly.WorkspaceDragSurfaceSvg.prototype.clearAndHide = function(newSurface) { - if (!newSurface) { - throw 'Couldn\'t clear and hide the drag surface: missing new surface.'; - } - var blockCanvas = this.SVG_.childNodes[0]; - var bubbleCanvas = this.SVG_.childNodes[1]; - if (!blockCanvas || !bubbleCanvas || - !Blockly.utils.hasClass(blockCanvas, 'blocklyBlockCanvas') || - !Blockly.utils.hasClass(bubbleCanvas, 'blocklyBubbleCanvas')) { - throw 'Couldn\'t clear and hide the drag surface. A node was missing.'; - } - - // If there is a previous sibling, put the blockCanvas back right afterwards, - // otherwise insert it as the first child node in newSurface. - if (this.previousSibling_ != null) { - Blockly.utils.insertAfter(blockCanvas, this.previousSibling_); - } else { - newSurface.insertBefore(blockCanvas, newSurface.firstChild); - } - - // Reattach the bubble canvas after the blockCanvas. - Blockly.utils.insertAfter(bubbleCanvas, blockCanvas); - // Hide the drag surface. - this.SVG_.style.display = 'none'; - goog.asserts.assert( - this.SVG_.childNodes.length == 0, 'Drag surface was not cleared.'); - Blockly.utils.setCssTransform(this.SVG_, ''); - this.previousSibling_ = null; -}; - -/** - * Set the SVG to have the block canvas and bubble canvas in it and then - * show the surface. - * @param {!Element} blockCanvas The block canvas element from the workspace. - * @param {!Element} bubbleCanvas The element that contains the bubbles. - * @param {?Element} previousSibling The element to insert the block canvas & - bubble canvas after when it goes back in the DOM at the end of a drag. - * @param {number} width The width of the workspace SVG element. - * @param {number} height The height of the workspace SVG element. - * @param {number} scale The scale of the workspace being dragged. - * @package - */ -Blockly.WorkspaceDragSurfaceSvg.prototype.setContentsAndShow = function( - blockCanvas, bubbleCanvas, previousSibling, width, height, scale) { - goog.asserts.assert( - this.SVG_.childNodes.length == 0, 'Already dragging a block.'); - this.previousSibling_ = previousSibling; - // Make sure the blocks and bubble canvas are scaled appropriately. - blockCanvas.setAttribute('transform', 'translate(0, 0) scale(' + scale + ')'); - bubbleCanvas.setAttribute( - 'transform', 'translate(0, 0) scale(' + scale + ')'); - this.SVG_.setAttribute('width', width); - this.SVG_.setAttribute('height', height); - this.SVG_.appendChild(blockCanvas); - this.SVG_.appendChild(bubbleCanvas); - this.SVG_.style.display = 'block'; -}; diff --git a/core/workspace_dragger.js b/core/workspace_dragger.js deleted file mode 100644 index 09cb9b8186..0000000000 --- a/core/workspace_dragger.js +++ /dev/null @@ -1,132 +0,0 @@ -/** - * @license - * Visual Blocks Editor - * - * Copyright 2017 Google Inc. - * https://developers.google.com/blockly/ - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @fileoverview Methods for dragging a workspace visually. - * @author fenichel@google.com (Rachel Fenichel) - */ -'use strict'; - -goog.provide('Blockly.WorkspaceDragger'); - -goog.require('goog.math.Coordinate'); -goog.require('goog.asserts'); - - -/** - * Class for a workspace dragger. It moves the workspace around when it is - * being dragged by a mouse or touch. - * Note that the workspace itself manages whether or not it has a drag surface - * and how to do translations based on that. This simply passes the right - * commands based on events. - * @param {!Blockly.WorkspaceSvg} workspace The workspace to drag. - * @constructor - */ -Blockly.WorkspaceDragger = function(workspace) { - /** - * @type {!Blockly.WorkspaceSvg} - * @private - */ - this.workspace_ = workspace; - - /** - * The workspace's metrics object at the beginning of the drag. Contains size - * and position metrics of a workspace. - * Coordinate system: pixel coordinates. - * @type {!Object} - * @private - */ - this.startDragMetrics_ = workspace.getMetrics(); - - /** - * The scroll position of the workspace at the beginning of the drag. - * Coordinate system: pixel coordinates. - * @type {!goog.math.Coordinate} - * @private - */ - this.startScrollXY_ = new goog.math.Coordinate( - workspace.scrollX, workspace.scrollY); -}; - -/** - * Sever all links from this object. - * @package - */ -Blockly.WorkspaceDragger.prototype.dispose = function() { - this.workspace_ = null; -}; - -/** - * Start dragging the workspace. - * @package - */ -Blockly.WorkspaceDragger.prototype.startDrag = function() { - if (Blockly.selected) { - Blockly.selected.unselect(); - } - this.workspace_.setupDragSurface(); -}; - -/** - * Finish dragging the workspace and put everything back where it belongs. - * @param {!goog.math.Coordinate} currentDragDeltaXY How far the pointer has - * moved from the position at the start of the drag, in pixel coordinates. - * @package - */ -Blockly.WorkspaceDragger.prototype.endDrag = function(currentDragDeltaXY) { - // Make sure everything is up to date. - this.drag(currentDragDeltaXY); - this.workspace_.resetDragSurface(); -}; - -/** - * Move the workspace based on the most recent mouse movements. - * @param {!goog.math.Coordinate} currentDragDeltaXY How far the pointer has - * moved from the position at the start of the drag, in pixel coordinates. - * @package - */ -Blockly.WorkspaceDragger.prototype.drag = function(currentDragDeltaXY) { - var metrics = this.startDragMetrics_; - var newXY = goog.math.Coordinate.sum(this.startScrollXY_, currentDragDeltaXY); - - // Bound the new XY based on workspace bounds. - var x = Math.min(newXY.x, -metrics.contentLeft); - var y = Math.min(newXY.y, -metrics.contentTop); - x = Math.max(x, metrics.viewWidth - metrics.contentLeft - - metrics.contentWidth); - y = Math.max(y, metrics.viewHeight - metrics.contentTop - - metrics.contentHeight); - - x = -x - metrics.contentLeft; - y = -y - metrics.contentTop; - - this.updateScroll_(x, y); -}; - -/** - * Move the scrollbars to drag the workspace. - * x and y are in pixels. - * @param {number} x The new x position to move the scrollbar to. - * @param {number} y The new y position to move the scrollbar to. - * @private - */ -Blockly.WorkspaceDragger.prototype.updateScroll_ = function(x, y) { - this.workspace_.scrollbar.set(x, y); -}; diff --git a/core/workspace_svg.js b/core/workspace_svg.js deleted file mode 100644 index e358f6ec93..0000000000 --- a/core/workspace_svg.js +++ /dev/null @@ -1,2267 +0,0 @@ -/** - * @license - * Visual Blocks Editor - * - * Copyright 2014 Google Inc. - * https://developers.google.com/blockly/ - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @fileoverview Object representing a workspace rendered as SVG. - * @author fraser@google.com (Neil Fraser) - */ -'use strict'; - -goog.provide('Blockly.WorkspaceSvg'); - -// TODO(scr): Fix circular dependencies -//goog.require('Blockly.BlockSvg'); -goog.require('Blockly.Colours'); -goog.require('Blockly.ConnectionDB'); -goog.require('Blockly.constants'); -goog.require('Blockly.DataCategory'); -goog.require('Blockly.DropDownDiv'); -goog.require('Blockly.Events.BlockCreate'); -goog.require('Blockly.Gesture'); -goog.require('Blockly.Grid'); -goog.require('Blockly.Options'); -goog.require('Blockly.scratchBlocksUtils'); -goog.require('Blockly.ScrollbarPair'); -goog.require('Blockly.Touch'); -goog.require('Blockly.Trashcan'); -//goog.require('Blockly.VerticalFlyout'); -goog.require('Blockly.Workspace'); -goog.require('Blockly.WorkspaceAudio'); -goog.require('Blockly.WorkspaceComment'); -goog.require('Blockly.WorkspaceCommentSvg'); -goog.require('Blockly.WorkspaceCommentSvg.render'); -goog.require('Blockly.WorkspaceDragSurfaceSvg'); -goog.require('Blockly.Xml'); -goog.require('Blockly.ZoomControls'); - -goog.require('goog.array'); -goog.require('goog.dom'); -goog.require('goog.math.Coordinate'); -goog.require('goog.userAgent'); -goog.require('goog.math.Rect'); - -/** - * Class for a workspace. This is an onscreen area with optional trashcan, - * scrollbars, bubbles, and dragging. - * @param {!Blockly.Options} options Dictionary of options. - * @param {Blockly.BlockDragSurfaceSvg=} opt_blockDragSurface Drag surface for - * blocks. - * @param {Blockly.WorkspaceDragSurfaceSvg=} opt_wsDragSurface Drag surface for - * the workspace. - * @extends {Blockly.Workspace} - * @constructor - */ -Blockly.WorkspaceSvg = function(options, opt_blockDragSurface, opt_wsDragSurface) { - Blockly.WorkspaceSvg.superClass_.constructor.call(this, options); - this.getMetrics = - options.getMetrics || Blockly.WorkspaceSvg.getTopLevelWorkspaceMetrics_; - this.setMetrics = - options.setMetrics || Blockly.WorkspaceSvg.setTopLevelWorkspaceMetrics_; - - Blockly.ConnectionDB.init(this); - - if (opt_blockDragSurface) { - this.blockDragSurface_ = opt_blockDragSurface; - } - - if (opt_wsDragSurface) { - this.workspaceDragSurface_ = opt_wsDragSurface; - } - - this.useWorkspaceDragSurface_ = - this.workspaceDragSurface_ && Blockly.utils.is3dSupported(); - - /** - * List of currently highlighted blocks. Block highlighting is often used to - * visually mark blocks currently being executed. - * @type !Array. - * @private - */ - this.highlightedBlocks_ = []; - - /** - * Object in charge of loading, storing, and playing audio for a workspace. - * @type {Blockly.WorkspaceAudio} - * @private - */ - this.audioManager_ = new Blockly.WorkspaceAudio(options.parentWorkspace); - - /** - * This workspace's grid object or null. - * @type {Blockly.Grid} - * @private - */ - this.grid_ = this.options.gridPattern ? - new Blockly.Grid(options.gridPattern, options.gridOptions) : null; - - this.registerToolboxCategoryCallback(Blockly.VARIABLE_CATEGORY_NAME, - Blockly.DataCategory); - this.registerToolboxCategoryCallback(Blockly.PROCEDURE_CATEGORY_NAME, - Blockly.Procedures.flyoutCategory); -}; -goog.inherits(Blockly.WorkspaceSvg, Blockly.Workspace); - -/** - * A wrapper function called when a resize event occurs. - * You can pass the result to `unbindEvent_`. - * @type {Array.} - */ -Blockly.WorkspaceSvg.prototype.resizeHandlerWrapper_ = null; - -/** - * The render status of an SVG workspace. - * Returns `false` for headless workspaces and true for instances of - * `Blockly.WorkspaceSvg`. - * @type {boolean} - */ -Blockly.WorkspaceSvg.prototype.rendered = true; - -/** - * Whether the workspace is visible. False if the workspace has been hidden - * by calling `setVisible(false)`. - * @type {boolean} - * @private - */ -Blockly.WorkspaceSvg.prototype.isVisible_ = true; - -/** - * Is this workspace the surface for a flyout? - * @type {boolean} - */ -Blockly.WorkspaceSvg.prototype.isFlyout = false; - -/** - * Is this workspace the surface for a mutator? - * @type {boolean} - * @package - */ -Blockly.WorkspaceSvg.prototype.isMutator = false; - -/** - * Whether this workspace has resizes enabled. - * Disable during batch operations for a performance improvement. - * @type {boolean} - * @private - */ -Blockly.WorkspaceSvg.prototype.resizesEnabled_ = true; - -/** - * Whether this workspace has toolbox/flyout refreshes enabled. - * Disable during batch operations for a performance improvement. - * @type {boolean} - * @private - */ -Blockly.WorkspaceSvg.prototype.toolboxRefreshEnabled_ = true; - -/** - * Current horizontal scrolling offset in pixel units. - * @type {number} - */ -Blockly.WorkspaceSvg.prototype.scrollX = 0; - -/** - * Current vertical scrolling offset in pixel units. - * @type {number} - */ -Blockly.WorkspaceSvg.prototype.scrollY = 0; - -/** - * Horizontal scroll value when scrolling started in pixel units. - * @type {number} - */ -Blockly.WorkspaceSvg.prototype.startScrollX = 0; - -/** - * Vertical scroll value when scrolling started in pixel units. - * @type {number} - */ -Blockly.WorkspaceSvg.prototype.startScrollY = 0; - -/** - * Distance from mouse to object being dragged. - * @type {goog.math.Coordinate} - * @private - */ -Blockly.WorkspaceSvg.prototype.dragDeltaXY_ = null; - -/** - * Current scale. - * @type {number} - */ -Blockly.WorkspaceSvg.prototype.scale = 1; - -/** - * The workspace's trashcan (if any). - * @type {Blockly.Trashcan} - */ -Blockly.WorkspaceSvg.prototype.trashcan = null; - -/** - * This workspace's scrollbars, if they exist. - * @type {Blockly.ScrollbarPair} - */ -Blockly.WorkspaceSvg.prototype.scrollbar = null; - -/** - * The current gesture in progress on this workspace, if any. - * @type {Blockly.Gesture} - * @private - */ -Blockly.WorkspaceSvg.prototype.currentGesture_ = null; - -/** - * This workspace's surface for dragging blocks, if it exists. - * @type {Blockly.BlockDragSurfaceSvg} - * @private - */ -Blockly.WorkspaceSvg.prototype.blockDragSurface_ = null; - -/** - * This workspace's drag surface, if it exists. - * @type {Blockly.WorkspaceDragSurfaceSvg} - * @private - */ -Blockly.WorkspaceSvg.prototype.workspaceDragSurface_ = null; - -/** - * Whether to move workspace to the drag surface when it is dragged. - * True if it should move, false if it should be translated directly. - * @type {boolean} - * @private - */ -Blockly.WorkspaceSvg.prototype.useWorkspaceDragSurface_ = false; - -/** - * Whether the drag surface is actively in use. When true, calls to - * translate will translate the drag surface instead of the translating the - * workspace directly. - * This is set to true in setupDragSurface and to false in resetDragSurface. - * @type {boolean} - * @private - */ -Blockly.WorkspaceSvg.prototype.isDragSurfaceActive_ = false; - -/** - * The first parent div with 'injectionDiv' in the name, or null if not set. - * Access this with getInjectionDiv. - * @type {!Element} - * @private - */ -Blockly.WorkspaceSvg.prototype.injectionDiv_ = null; - -/** - * Last known position of the page scroll. - * This is used to determine whether we have recalculated screen coordinate - * stuff since the page scrolled. - * @type {!goog.math.Coordinate} - * @private - */ -Blockly.WorkspaceSvg.prototype.lastRecordedPageScroll_ = null; - -/** - * Map from function names to callbacks, for deciding what to do when a button - * is clicked. - * @type {!Object.} - * @private - */ -Blockly.WorkspaceSvg.prototype.flyoutButtonCallbacks_ = {}; - -/** - * Map from function names to callbacks, for deciding what to do when a custom - * toolbox category is opened. - * @type {!Object.>} - * @private - */ -Blockly.WorkspaceSvg.prototype.toolboxCategoryCallbacks_ = {}; - -/** - * Inverted screen CTM, for use in mouseToSvg. - * @type {SVGMatrix} - * @private - */ -Blockly.WorkspaceSvg.prototype.inverseScreenCTM_ = null; - -/** - * Inverted screen CTM is dirty. - * @type {Boolean} - * @private - */ -Blockly.WorkspaceSvg.prototype.inverseScreenCTMDirty_ = true; - -/** - * Getter for the inverted screen CTM. - * @return {SVGMatrix} The matrix to use in mouseToSvg - */ -Blockly.WorkspaceSvg.prototype.getInverseScreenCTM = function() { - - // Defer getting the screen CTM until we actually need it, this should - // avoid forced reflows from any calls to updateInverseScreenCTM. - if (this.inverseScreenCTMDirty_) { - var ctm = this.getParentSvg().getScreenCTM(); - if (ctm) { - this.inverseScreenCTM_ = ctm.inverse(); - this.inverseScreenCTMDirty_ = false; - } - } - - return this.inverseScreenCTM_; -}; - -/** - * Getter for isVisible - * @return {boolean} Whether the workspace is visible. False if the workspace has been hidden - * by calling `setVisible(false)`. - */ -Blockly.WorkspaceSvg.prototype.isVisible = function() { - return this.isVisible_; -}; - -/** - * Mark the inverse screen CTM as dirty. - */ -Blockly.WorkspaceSvg.prototype.updateInverseScreenCTM = function() { - this.inverseScreenCTMDirty_ = true; -}; - -/** - * Return the absolute coordinates of the top-left corner of this element, - * scales that after canvas SVG element, if it's a descendant. - * The origin (0,0) is the top-left corner of the Blockly SVG. - * @param {!Element} element Element to find the coordinates of. - * @return {!goog.math.Coordinate} Object with .x and .y properties. - * @private - */ -Blockly.WorkspaceSvg.prototype.getSvgXY = function(element) { - var x = 0; - var y = 0; - var scale = 1; - if (goog.dom.contains(this.getCanvas(), element) || - goog.dom.contains(this.getBubbleCanvas(), element)) { - // Before the SVG canvas, scale the coordinates. - scale = this.scale; - } - do { - // Loop through this block and every parent. - var xy = Blockly.utils.getRelativeXY(element); - if (element == this.getCanvas() || - element == this.getBubbleCanvas()) { - // After the SVG canvas, don't scale the coordinates. - scale = 1; - } - x += xy.x * scale; - y += xy.y * scale; - element = element.parentNode; - } while (element && element != this.getParentSvg()); - return new goog.math.Coordinate(x, y); -}; - -/** - * Return the position of the workspace origin relative to the injection div - * origin in pixels. - * The workspace origin is where a block would render at position (0, 0). - * It is not the upper left corner of the workspace SVG. - * @return {!goog.math.Coordinate} Offset in pixels. - * @package - */ -Blockly.WorkspaceSvg.prototype.getOriginOffsetInPixels = function() { - return Blockly.utils.getInjectionDivXY_(this.svgBlockCanvas_); -}; - -/** - * Return the injection div that is a parent of this workspace. - * Walks the DOM the first time it's called, then returns a cached value. - * @return {!Element} The first parent div with 'injectionDiv' in the name. - * @package - */ -Blockly.WorkspaceSvg.prototype.getInjectionDiv = function() { - // NB: it would be better to pass this in at createDom, but is more likely to - // break existing uses of Blockly. - if (!this.injectionDiv_) { - var element = this.svgGroup_; - while (element) { - var classes = element.getAttribute('class') || ''; - if ((' ' + classes + ' ').indexOf(' injectionDiv ') != -1) { - this.injectionDiv_ = element; - break; - } - element = element.parentNode; - } - } - return this.injectionDiv_; -}; - -/** - * Save resize handler data so we can delete it later in dispose. - * @param {!Array.} handler Data that can be passed to unbindEvent_. - */ -Blockly.WorkspaceSvg.prototype.setResizeHandlerWrapper = function(handler) { - this.resizeHandlerWrapper_ = handler; -}; - -/** - * Create the workspace DOM elements. - * @param {string=} opt_backgroundClass Either 'blocklyMainBackground' or - * 'blocklyMutatorBackground'. - * @return {!Element} The workspace's SVG group. - */ -Blockly.WorkspaceSvg.prototype.createDom = function(opt_backgroundClass) { - /** - * - * - * [Trashcan and/or flyout may go here] - * - * - * - * @type {SVGElement} - */ - this.svgGroup_ = Blockly.utils.createSvgElement('g', - {'class': 'blocklyWorkspace'}, null); - - // Note that a alone does not receive mouse events--it must have a - // valid target inside it. If no background class is specified, as in the - // flyout, the workspace will not receive mouse events. - if (opt_backgroundClass) { - /** @type {SVGElement} */ - this.svgBackground_ = Blockly.utils.createSvgElement('rect', - {'height': '100%', 'width': '100%', 'class': opt_backgroundClass}, - this.svgGroup_); - - if (opt_backgroundClass == 'blocklyMainBackground' && this.grid_) { - this.svgBackground_.style.fill = - 'url(#' + this.grid_.getPatternId() + ')'; - } - } - /** @type {SVGElement} */ - this.svgBlockCanvas_ = Blockly.utils.createSvgElement('g', - {'class': 'blocklyBlockCanvas'}, this.svgGroup_, this); - /** @type {SVGElement} */ - this.svgBubbleCanvas_ = Blockly.utils.createSvgElement('g', - {'class': 'blocklyBubbleCanvas'}, this.svgGroup_, this); - var bottom = Blockly.Scrollbar.scrollbarThickness; - if (this.options.hasTrashcan) { - bottom = this.addTrashcan_(bottom); - } - if (this.options.zoomOptions && this.options.zoomOptions.controls) { - this.addZoomControls_(bottom); - } - - if (!this.isFlyout) { - Blockly.bindEventWithChecks_(this.svgGroup_, 'mousedown', this, - this.onMouseDown_); - if (this.options.zoomOptions && this.options.zoomOptions.wheel) { - // Mouse-wheel. - Blockly.bindEventWithChecks_(this.svgGroup_, 'wheel', this, - this.onMouseWheel_); - } - } - - // Determine if there needs to be a category tree, or a simple list of - // blocks. This cannot be changed later, since the UI is very different. - if (this.options.hasCategories) { - /** - * @type {Blockly.Toolbox} - * @private - */ - this.toolbox_ = new Blockly.Toolbox(this); - } - if (this.grid_) { - this.grid_.update(this.scale); - } - this.recordCachedAreas(); - return this.svgGroup_; -}; - -/** - * Dispose of this workspace. - * Unlink from all DOM elements to prevent memory leaks. - */ -Blockly.WorkspaceSvg.prototype.dispose = function() { - // Stop rerendering. - this.rendered = false; - if (this.currentGesture_) { - this.currentGesture_.cancel(); - } - Blockly.WorkspaceSvg.superClass_.dispose.call(this); - if (this.svgGroup_) { - goog.dom.removeNode(this.svgGroup_); - this.svgGroup_ = null; - } - this.svgBlockCanvas_ = null; - this.svgBubbleCanvas_ = null; - if (this.toolbox_) { - this.toolbox_.dispose(); - this.toolbox_ = null; - } - if (this.flyout_) { - this.flyout_.dispose(); - this.flyout_ = null; - } - if (this.trashcan) { - this.trashcan.dispose(); - this.trashcan = null; - } - if (this.scrollbar) { - this.scrollbar.dispose(); - this.scrollbar = null; - } - if (this.zoomControls_) { - this.zoomControls_.dispose(); - this.zoomControls_ = null; - } - - if (this.audioManager_) { - this.audioManager_.dispose(); - this.audioManager_ = null; - } - - if (this.grid_) { - this.grid_.dispose(); - this.grid_ = null; - } - - if (this.toolboxCategoryCallbacks_) { - this.toolboxCategoryCallbacks_ = null; - } - if (this.flyoutButtonCallbacks_) { - this.flyoutButtonCallbacks_ = null; - } - if (!this.options.parentWorkspace) { - // Top-most workspace. Dispose of the div that the - // SVG is injected into (i.e. injectionDiv). - goog.dom.removeNode(this.getParentSvg().parentNode); - } - if (this.resizeHandlerWrapper_) { - Blockly.unbindEvent_(this.resizeHandlerWrapper_); - this.resizeHandlerWrapper_ = null; - } -}; - -/** - * Obtain a newly created block. - * @param {?string} prototypeName Name of the language object containing - * type-specific functions for this block. - * @param {string=} opt_id Optional ID. Use this ID if provided, otherwise - * create a new ID. - * @return {!Blockly.BlockSvg} The created block. - */ -Blockly.WorkspaceSvg.prototype.newBlock = function(prototypeName, opt_id) { - return new Blockly.BlockSvg(this, prototypeName, opt_id); -}; - -/** - * Add a trashcan. - * @param {number} bottom Distance from workspace bottom to bottom of trashcan. - * @return {number} Distance from workspace bottom to the top of trashcan. - * @private - */ -Blockly.WorkspaceSvg.prototype.addTrashcan_ = function(bottom) { - /** @type {Blockly.Trashcan} */ - this.trashcan = new Blockly.Trashcan(this); - var svgTrashcan = this.trashcan.createDom(); - this.svgGroup_.insertBefore(svgTrashcan, this.svgBlockCanvas_); - return this.trashcan.init(bottom); -}; - -/** - * Add zoom controls. - * @param {number} bottom Distance from workspace bottom to bottom of controls. - * @return {number} Distance from workspace bottom to the top of controls. - * @private - */ -Blockly.WorkspaceSvg.prototype.addZoomControls_ = function(bottom) { - /** @type {Blockly.ZoomControls} */ - this.zoomControls_ = new Blockly.ZoomControls(this); - var svgZoomControls = this.zoomControls_.createDom(); - this.svgGroup_.appendChild(svgZoomControls); - return this.zoomControls_.init(bottom); -}; - -/** - * Add a flyout element in an element with the given tag name. - * @param {string} tagName What type of tag the flyout belongs in. - * @return {!Element} The element containing the flyout DOM. - * @private - */ -Blockly.WorkspaceSvg.prototype.addFlyout_ = function(tagName) { - var workspaceOptions = { - disabledPatternId: this.options.disabledPatternId, - parentWorkspace: this, - RTL: this.RTL, - oneBasedIndex: this.options.oneBasedIndex, - horizontalLayout: this.horizontalLayout, - toolboxPosition: this.options.toolboxPosition, - stackGlowFilterId: this.options.stackGlowFilterId - }; - if (this.horizontalLayout) { - this.flyout_ = new Blockly.HorizontalFlyout(workspaceOptions); - } else { - this.flyout_ = new Blockly.VerticalFlyout(workspaceOptions); - } - this.flyout_.autoClose = false; - - // Return the element so that callers can place it in their desired - // spot in the DOM. For example, mutator flyouts do not go in the same place - // as main workspace flyouts. - return this.flyout_.createDom(tagName); -}; - -/** - * Getter for the flyout associated with this workspace. This flyout may be - * owned by either the toolbox or the workspace, depending on toolbox - * configuration. It will be null if there is no flyout. - * @return {Blockly.Flyout} The flyout on this workspace. - * @package - */ -Blockly.WorkspaceSvg.prototype.getFlyout = function() { - if (this.flyout_) { - return this.flyout_; - } - if (this.toolbox_) { - return this.toolbox_.flyout_; - } - return null; -}; - -/** - * Getter for the toolbox associated with this workspace, if one exists. - * @return {Blockly.Toolbox} The toolbox on this workspace. - * @package - */ -Blockly.WorkspaceSvg.prototype.getToolbox = function() { - return this.toolbox_; -}; - -/** - * Update items that use screen coordinate calculations - * because something has changed (e.g. scroll position, window size). - * @private - */ -Blockly.WorkspaceSvg.prototype.updateScreenCalculations_ = function() { - this.updateInverseScreenCTM(); - this.recordCachedAreas(); -}; - -/** - * If enabled, resize the parts of the workspace that change when the workspace - * contents (e.g. block positions) change. This will also scroll the - * workspace contents if needed. - * @package - */ -Blockly.WorkspaceSvg.prototype.resizeContents = function() { - if (!this.resizesEnabled_ || !this.rendered) { - return; - } - if (this.scrollbar) { - // TODO(picklesrus): Once rachel-fenichel's scrollbar refactoring - // is complete, call the method that only resizes scrollbar - // based on contents. - this.scrollbar.resize(); - } - this.updateInverseScreenCTM(); -}; - -/** - * Resize and reposition all of the workspace chrome (toolbox, - * trash, scrollbars etc.) - * This should be called when something changes that - * requires recalculating dimensions and positions of the - * trash, zoom, toolbox, etc. (e.g. window resize). - */ -Blockly.WorkspaceSvg.prototype.resize = function() { - if (this.toolbox_) { - this.toolbox_.position(); - } - if (this.flyout_) { - this.flyout_.position(); - } - if (this.trashcan) { - this.trashcan.position(); - } - if (this.zoomControls_) { - this.zoomControls_.position(); - } - if (this.scrollbar) { - this.scrollbar.resize(); - } - this.updateScreenCalculations_(); -}; - -/** - * Resizes and repositions workspace chrome if the page has a new - * scroll position. - * @package - */ -Blockly.WorkspaceSvg.prototype.updateScreenCalculationsIfScrolled - = function() { - /* eslint-disable indent */ - var currScroll = goog.dom.getDocumentScroll(); - if (!goog.math.Coordinate.equals(this.lastRecordedPageScroll_, - currScroll)) { - this.lastRecordedPageScroll_ = currScroll; - this.updateScreenCalculations_(); - } -}; /* eslint-enable indent */ - -/** - * Get the SVG element that forms the drawing surface. - * @return {!Element} SVG element. - */ -Blockly.WorkspaceSvg.prototype.getCanvas = function() { - return this.svgBlockCanvas_; -}; - -/** - * Get the SVG element that forms the bubble surface. - * @return {!SVGGElement} SVG element. - */ -Blockly.WorkspaceSvg.prototype.getBubbleCanvas = function() { - return this.svgBubbleCanvas_; -}; - -/** - * Get the SVG element that contains this workspace. - * @return {!Element} SVG element. - */ -Blockly.WorkspaceSvg.prototype.getParentSvg = function() { - if (this.cachedParentSvg_) { - return this.cachedParentSvg_; - } - var element = this.svgGroup_; - while (element) { - if (element.tagName == 'svg') { - this.cachedParentSvg_ = element; - return element; - } - element = element.parentNode; - } - return null; -}; - -/** - * Translate this workspace to new coordinates. - * @param {number} x Horizontal translation. - * @param {number} y Vertical translation. - */ -Blockly.WorkspaceSvg.prototype.translate = function(x, y) { - if (this.useWorkspaceDragSurface_ && this.isDragSurfaceActive_) { - this.workspaceDragSurface_.translateSurface(x,y); - } else { - var translation = 'translate(' + x + ',' + y + ') ' + - 'scale(' + this.scale + ')'; - this.svgBlockCanvas_.setAttribute('transform', translation); - this.svgBubbleCanvas_.setAttribute('transform', translation); - } - // Now update the block drag surface if we're using one. - if (this.blockDragSurface_) { - this.blockDragSurface_.translateAndScaleGroup(x, y, this.scale); - } -}; - -/** - * Called at the end of a workspace drag to take the contents - * out of the drag surface and put them back into the workspace SVG. - * Does nothing if the workspace drag surface is not enabled. - * @package - */ -Blockly.WorkspaceSvg.prototype.resetDragSurface = function() { - // Don't do anything if we aren't using a drag surface. - if (!this.useWorkspaceDragSurface_) { - return; - } - - this.isDragSurfaceActive_ = false; - - var trans = this.workspaceDragSurface_.getSurfaceTranslation(); - this.workspaceDragSurface_.clearAndHide(this.svgGroup_); - var translation = 'translate(' + trans.x + ',' + trans.y + ') ' + - 'scale(' + this.scale + ')'; - this.svgBlockCanvas_.setAttribute('transform', translation); - this.svgBubbleCanvas_.setAttribute('transform', translation); -}; - -/** - * Called at the beginning of a workspace drag to move contents of - * the workspace to the drag surface. - * Does nothing if the drag surface is not enabled. - * @package - */ -Blockly.WorkspaceSvg.prototype.setupDragSurface = function() { - // Don't do anything if we aren't using a drag surface. - if (!this.useWorkspaceDragSurface_) { - return; - } - - // This can happen if the user starts a drag, mouses up outside of the - // document where the mouseup listener is registered (e.g. outside of an - // iframe) and then moves the mouse back in the workspace. On mobile and ff, - // we get the mouseup outside the frame. On chrome and safari desktop we do - // not. - if (this.isDragSurfaceActive_) { - return; - } - - this.isDragSurfaceActive_ = true; - - // Figure out where we want to put the canvas back. The order - // in the is important because things are layered. - var previousElement = this.svgBlockCanvas_.previousSibling; - var width = parseInt(this.getParentSvg().getAttribute('width'), 10); - var height = parseInt(this.getParentSvg().getAttribute('height'), 10); - var coord = Blockly.utils.getRelativeXY(this.svgBlockCanvas_); - this.workspaceDragSurface_.setContentsAndShow(this.svgBlockCanvas_, - this.svgBubbleCanvas_, previousElement, width, height, this.scale); - this.workspaceDragSurface_.translateSurface(coord.x, coord.y); -}; - -/** - * @return {?Blockly.BlockDragSurfaceSvg} This workspace's block drag surface, - * if one is in use. - * @package - */ -Blockly.WorkspaceSvg.prototype.getBlockDragSurface = function() { - return this.blockDragSurface_; -}; - -/** - * Returns the horizontal offset of the workspace. - * Intended for LTR/RTL compatibility in XML. - * @return {number} Width. - */ -Blockly.WorkspaceSvg.prototype.getWidth = function() { - var metrics = this.getMetrics(); - return metrics ? metrics.viewWidth / this.scale : 0; -}; - -/** - * Toggles the visibility of the workspace. - * Currently only intended for main workspace. - * @param {boolean} isVisible True if workspace should be visible. - */ -Blockly.WorkspaceSvg.prototype.setVisible = function(isVisible) { - - // Tell the scrollbar whether its container is visible so it can - // tell when to hide itself. - if (this.scrollbar) { - this.scrollbar.setContainerVisible(isVisible); - } - - // Tell the flyout whether its container is visible so it can - // tell when to hide itself. - if (this.getFlyout()) { - this.getFlyout().setContainerVisible(isVisible); - } - - this.getParentSvg().style.display = isVisible ? 'block' : 'none'; - if (this.toolbox_) { - // Currently does not support toolboxes in mutators. - this.toolbox_.HtmlDiv.style.display = isVisible ? 'block' : 'none'; - } - if (isVisible) { - this.render(); - // The window may have changed size while the workspace was hidden. - // Resize recalculates scrollbar position, delete areas, etc. - this.resize(); - } else { - Blockly.hideChaff(true); - Blockly.DropDownDiv.hideWithoutAnimation(); - } - this.isVisible_ = isVisible; -}; - -/** - * Render all blocks in workspace. - */ -Blockly.WorkspaceSvg.prototype.render = function() { - // Generate list of all blocks. - var blocks = this.getAllBlocks(); - // Render each block. - for (var i = blocks.length - 1; i >= 0; i--) { - blocks[i].render(false); - } -}; - -/** - * Was used back when block highlighting (for execution) and block selection - * (for editing) were the same thing. - * Any calls of this function can be deleted. - * @deprecated October 2016 - */ -Blockly.WorkspaceSvg.prototype.traceOn = function() { - console.warn('Deprecated call to traceOn, delete this.'); -}; - -/** - * Highlight or unhighlight a block in the workspace. Block highlighting is - * often used to visually mark blocks currently being executed. - * @param {?string} id ID of block to highlight/unhighlight, - * or null for no block (used to unhighlight all blocks). - * @param {boolean=} opt_state If undefined, highlight specified block and - * automatically unhighlight all others. If true or false, manually - * highlight/unhighlight the specified block. - */ -Blockly.WorkspaceSvg.prototype.highlightBlock = function(id, opt_state) { - if (opt_state === undefined) { - // Unhighlight all blocks. - for (var i = 0, block; block = this.highlightedBlocks_[i]; i++) { - block.setHighlighted(false); - } - this.highlightedBlocks_.length = 0; - } - // Highlight/unhighlight the specified block. - var block = id ? this.getBlockById(id) : null; - if (block) { - var state = (opt_state === undefined) || opt_state; - // Using Set here would be great, but at the cost of IE10 support. - if (!state) { - goog.array.remove(this.highlightedBlocks_, block); - } else if (this.highlightedBlocks_.indexOf(block) == -1) { - this.highlightedBlocks_.push(block); - } - block.setHighlighted(state); - } -}; - -/** - * Glow/unglow a block in the workspace. - * @param {?string} id ID of block to find. - * @param {boolean} isGlowingBlock Whether to glow the block. - */ -Blockly.WorkspaceSvg.prototype.glowBlock = function(id, isGlowingBlock) { - var block = null; - if (id) { - block = this.getBlockById(id); - if (!block) { - throw 'Tried to glow block that does not exist.'; - } - } - block.setGlowBlock(isGlowingBlock); -}; - -/** - * Glow/unglow a stack in the workspace. - * @param {?string} id ID of block which starts the stack. - * @param {boolean} isGlowingStack Whether to glow the stack. - */ -Blockly.WorkspaceSvg.prototype.glowStack = function(id, isGlowingStack) { - var block = null; - if (id) { - block = this.getBlockById(id); - if (!block) { - throw 'Tried to glow stack on block that does not exist.'; - } - } - block.setGlowStack(isGlowingStack); -}; - -/** - * Visually report a value associated with a block. - * In Scratch, appears as a pop-up next to the block when a reporter block is clicked. - * @param {?string} id ID of block to report associated value. - * @param {?string} value String value to visually report. - */ -Blockly.WorkspaceSvg.prototype.reportValue = function(id, value) { - var block = this.getBlockById(id); - if (!block) { - throw 'Tried to report value on block that does not exist.'; - } - Blockly.DropDownDiv.hideWithoutAnimation(); - Blockly.DropDownDiv.clearContent(); - var contentDiv = Blockly.DropDownDiv.getContentDiv(); - var valueReportBox = goog.dom.createElement('div'); - valueReportBox.setAttribute('class', 'valueReportBox'); - valueReportBox.innerHTML = Blockly.scratchBlocksUtils.encodeEntities(value); - contentDiv.appendChild(valueReportBox); - Blockly.DropDownDiv.setColour( - Blockly.Colours.valueReportBackground, - Blockly.Colours.valueReportBorder - ); - Blockly.DropDownDiv.showPositionedByBlock(this, block); -}; - -/** - * Paste the provided block onto the workspace. - * @param {!Element} xmlBlock XML block element. - */ -Blockly.WorkspaceSvg.prototype.paste = function(xmlBlock) { - if (!this.rendered) { - return; - } - if (this.currentGesture_) { - this.currentGesture_.cancel(); // Dragging while pasting? No. - } - if (xmlBlock.tagName.toLowerCase() == 'comment') { - this.pasteWorkspaceComment_(xmlBlock); - } else { - this.pasteBlock_(xmlBlock); - } -}; - -/** - * Paste the provided block onto the workspace. - * @param {!Element} xmlBlock XML block element. - */ -Blockly.WorkspaceSvg.prototype.pasteBlock_ = function(xmlBlock) { - Blockly.Events.disable(); - try { - var block = Blockly.Xml.domToBlock(xmlBlock, this); - // Scratch-specific: Give shadow dom new IDs to prevent duplicating on paste - Blockly.scratchBlocksUtils.changeObscuredShadowIds(block); - // Move the duplicate to original position. - var blockX = parseInt(xmlBlock.getAttribute('x'), 10); - var blockY = parseInt(xmlBlock.getAttribute('y'), 10); - if (!isNaN(blockX) && !isNaN(blockY)) { - if (this.RTL) { - blockX = -blockX; - } - // Offset block until not clobbering another block and not in connection - // distance with neighbouring blocks. - do { - var collide = false; - var allBlocks = this.getAllBlocks(); - for (var i = 0, otherBlock; otherBlock = allBlocks[i]; i++) { - var otherXY = otherBlock.getRelativeToSurfaceXY(); - if (Math.abs(blockX - otherXY.x) <= 1 && - Math.abs(blockY - otherXY.y) <= 1) { - collide = true; - break; - } - } - if (!collide) { - // Check for blocks in snap range to any of its connections. - var connections = block.getConnections_(false); - for (var i = 0, connection; connection = connections[i]; i++) { - var neighbour = connection.closest(Blockly.SNAP_RADIUS, - new goog.math.Coordinate(blockX, blockY)); - if (neighbour.connection) { - collide = true; - break; - } - } - } - if (collide) { - if (this.RTL) { - blockX -= Blockly.SNAP_RADIUS; - } else { - blockX += Blockly.SNAP_RADIUS; - } - blockY += Blockly.SNAP_RADIUS * 2; - } - } while (collide); - block.moveBy(blockX, blockY); - } - } finally { - Blockly.Events.enable(); - } - if (Blockly.Events.isEnabled() && !block.isShadow()) { - Blockly.Events.fire(new Blockly.Events.BlockCreate(block)); - } - block.select(); -}; - -/** - * Paste the provided comment onto the workspace. - * @param {!Element} xmlComment XML workspace comment element. - * @private - */ -Blockly.WorkspaceSvg.prototype.pasteWorkspaceComment_ = function(xmlComment) { - Blockly.Events.disable(); - try { - var comment = Blockly.WorkspaceCommentSvg.fromXml(xmlComment, this); - // Move the duplicate to original position. - var commentX = parseInt(xmlComment.getAttribute('x'), 10); - var commentY = parseInt(xmlComment.getAttribute('y'), 10); - if (!isNaN(commentX) && !isNaN(commentY)) { - if (this.RTL) { - commentX = -commentX; - } - // Offset workspace comment. - // TODO: (github.com/google/blockly/issues/1719) properly offset comment - // such that it's not interfereing with any blocks - commentX += 50; - commentY += 50; - comment.moveBy(commentX, commentY); - } - } finally { - Blockly.Events.enable(); - } - if (Blockly.Events.isEnabled()) { - Blockly.WorkspaceComment.fireCreateEvent(comment); - } - comment.select(); -}; - -/** - * Refresh the toolbox unless there's a drag in progress. - * @private - */ -Blockly.WorkspaceSvg.prototype.refreshToolboxSelection_ = function() { - // Updating the toolbox can be expensive. Don't do it when when it is - // disabled. - if (this.toolbox_) { - if (this.toolbox_.flyout_ && !this.currentGesture_ && - this.toolboxRefreshEnabled_) { - this.toolbox_.refreshSelection(); - } - } else { - var thisTarget = this.targetWorkspace; - if (thisTarget && thisTarget.toolbox_ && thisTarget.toolbox_.flyout_ && - !thisTarget.currentGesture_ && thisTarget.toolboxRefreshEnabled_) { - thisTarget.toolbox_.refreshSelection(); - } - } -}; - -/** - * Rename a variable by updating its name in the variable map. Update the - * flyout to show the renamed variable immediately. - * @param {string} id ID of the variable to rename. - * @param {string} newName New variable name. - * @package - */ -Blockly.WorkspaceSvg.prototype.renameVariableById = function(id, newName) { - Blockly.WorkspaceSvg.superClass_.renameVariableById.call(this, id, newName); - this.refreshToolboxSelection_(); -}; - -/** - * Delete a variable by the passed in ID. Update the flyout to show - * immediately that the variable is deleted. - * @param {string} id ID of variable to delete. - * @package - */ -Blockly.WorkspaceSvg.prototype.deleteVariableById = function(id) { - Blockly.WorkspaceSvg.superClass_.deleteVariableById.call(this, id); - this.refreshToolboxSelection_(); -}; - -/** - * Create a new variable with the given name. Update the flyout to show the new - * variable immediately. - * @param {string} name The new variable's name. - * @param {string=} opt_type The type of the variable like 'int' or 'string'. - * Does not need to be unique. Field_variable can filter variables based on - * their type. This will default to '' which is a specific type. - * @param {string=} opt_id The unique ID of the variable. This will default to - * a UUID. - * @param {boolean=} opt_isLocal Whether the variable is locally scoped. - * @param {boolean=} opt_isCloud Whether the variable is a cloud variable. - * @return {?Blockly.VariableModel} The newly created variable. - * @package - */ -Blockly.WorkspaceSvg.prototype.createVariable = function(name, opt_type, opt_id, - opt_isLocal, opt_isCloud) { - var variableInMap = (this.getVariable(name, opt_type) != null); - var newVar = Blockly.WorkspaceSvg.superClass_.createVariable.call( - this, name, opt_type, opt_id, opt_isLocal, opt_isCloud); - // For performance reasons, only refresh the the toolbox for new variables. - // Variables that already exist should already be there. - if (!variableInMap && (opt_type != Blockly.BROADCAST_MESSAGE_VARIABLE_TYPE)) { - this.refreshToolboxSelection_(); - } - return newVar; -}; - -/** - * Update cached areas for this workspace. - */ -Blockly.WorkspaceSvg.prototype.recordCachedAreas = function() { - this.recordBlocksArea_(); - this.recordDeleteAreas_(); -}; - -/** - * Make a list of all the delete areas for this workspace. - * @private - */ -Blockly.WorkspaceSvg.prototype.recordDeleteAreas_ = function() { - if (this.trashcan) { - this.deleteAreaTrash_ = this.trashcan.getClientRect(); - } else { - this.deleteAreaTrash_ = null; - } - if (this.flyout_) { - this.deleteAreaToolbox_ = this.flyout_.getClientRect(); - } else if (this.toolbox_) { - this.deleteAreaToolbox_ = this.toolbox_.getClientRect(); - } else { - this.deleteAreaToolbox_ = null; - } -}; - -/** - * Record where all of blocks GUI is on the screen - * @private - */ -Blockly.WorkspaceSvg.prototype.recordBlocksArea_ = function() { - var parentSvg = this.getParentSvg(); - if (parentSvg) { - var bounds = parentSvg.getBoundingClientRect(); - this.blocksArea_ = new goog.math.Rect(bounds.left, bounds.top, bounds.width, bounds.height); - } else { - this.blocksArea_ = null; - } -}; - -/** - * Is the mouse event over a delete area (toolbox or non-closing flyout)? - * @param {!Event} e Mouse move event. - * @return {?number} Null if not over a delete area, or an enum representing - * which delete area the event is over. - */ -Blockly.WorkspaceSvg.prototype.isDeleteArea = function(e) { - var xy = new goog.math.Coordinate(e.clientX, e.clientY); - if (this.deleteAreaTrash_ && this.deleteAreaTrash_.contains(xy)) { - return Blockly.DELETE_AREA_TRASH; - } - if (this.deleteAreaToolbox_ && this.deleteAreaToolbox_.contains(xy)) { - return Blockly.DELETE_AREA_TOOLBOX; - } - return Blockly.DELETE_AREA_NONE; -}; - -/** - * Is the mouse event inside the blocks UI? - * @param {!Event} e Mouse move event. - * @return {boolean} True if event is within the bounds of the blocks UI or delete area - */ -Blockly.WorkspaceSvg.prototype.isInsideBlocksArea = function(e) { - var xy = new goog.math.Coordinate(e.clientX, e.clientY); - if (this.isDeleteArea(e) || (this.blocksArea_ && this.blocksArea_.contains(xy))) { - return true; - } - return false; -}; - -/** - * Handle a mouse-down on SVG drawing surface. - * @param {!Event} e Mouse down event. - * @private - */ -Blockly.WorkspaceSvg.prototype.onMouseDown_ = function(e) { - var gesture = this.getGesture(e); - if (gesture) { - gesture.handleWsStart(e, this); - } -}; - -/** - * Start tracking a drag of an object on this workspace. - * @param {!Event} e Mouse down event. - * @param {!goog.math.Coordinate} xy Starting location of object. - */ -Blockly.WorkspaceSvg.prototype.startDrag = function(e, xy) { - // Record the starting offset between the bubble's location and the mouse. - var point = Blockly.utils.mouseToSvg(e, this.getParentSvg(), - this.getInverseScreenCTM()); - // Fix scale of mouse event. - point.x /= this.scale; - point.y /= this.scale; - this.dragDeltaXY_ = goog.math.Coordinate.difference(xy, point); -}; - -/** - * Track a drag of an object on this workspace. - * @param {!Event} e Mouse move event. - * @return {!goog.math.Coordinate} New location of object. - */ -Blockly.WorkspaceSvg.prototype.moveDrag = function(e) { - var point = Blockly.utils.mouseToSvg(e, this.getParentSvg(), - this.getInverseScreenCTM()); - // Fix scale of mouse event. - point.x /= this.scale; - point.y /= this.scale; - return goog.math.Coordinate.sum(this.dragDeltaXY_, point); -}; - -/** - * Is the user currently dragging a block or scrolling the flyout/workspace? - * @return {boolean} True if currently dragging or scrolling. - */ -Blockly.WorkspaceSvg.prototype.isDragging = function() { - return this.currentGesture_ && this.currentGesture_.isDragging(); -}; - -/** - * Is this workspace draggable and scrollable? - * @return {boolean} True if this workspace may be dragged. - */ -Blockly.WorkspaceSvg.prototype.isDraggable = function() { - return !!this.scrollbar; -}; - -/** - * Handle a mouse-wheel on SVG drawing surface. - * @param {!Event} e Mouse wheel event. - * @private - */ -Blockly.WorkspaceSvg.prototype.onMouseWheel_ = function(e) { - // TODO: Remove gesture cancellation and compensate for coordinate skew during - // zoom. - if (this.currentGesture_) { - this.currentGesture_.cancel(); - } - - // Multiplier variable, so that non-pixel-deltaModes are supported. - // See LLK/scratch-blocks#1190. - var multiplier = e.deltaMode === 0x1 ? Blockly.LINE_SCROLL_MULTIPLIER : 1; - - if (e.ctrlKey) { - // The vertical scroll distance that corresponds to a click of a zoom button. - var PIXELS_PER_ZOOM_STEP = 50; - var delta = -e.deltaY / PIXELS_PER_ZOOM_STEP * multiplier; - var position = Blockly.utils.mouseToSvg(e, this.getParentSvg(), - this.getInverseScreenCTM()); - this.zoom(position.x, position.y, delta); - } else { - // This is a regular mouse wheel event - scroll the workspace - // First hide the WidgetDiv without animation - // (mouse scroll makes field out of place with div) - Blockly.WidgetDiv.hide(true); - Blockly.DropDownDiv.hideWithoutAnimation(); - - var x = this.scrollX - e.deltaX * multiplier; - var y = this.scrollY - e.deltaY * multiplier; - - if (e.shiftKey && e.deltaX === 0) { - // Scroll horizontally (based on vertical scroll delta) - // This is needed as for some browser/system combinations which do not - // set deltaX. See #1662. - x = this.scrollX - e.deltaY * multiplier; - y = this.scrollY; // Don't scroll vertically - } - - this.startDragMetrics = this.getMetrics(); - this.scroll(x, y); - } - e.preventDefault(); -}; - -/** - * Calculate the bounding box for the blocks on the workspace. - * Coordinate system: workspace coordinates. - * - * @return {Object} Contains the position and size of the bounding box - * containing the blocks on the workspace. - */ -Blockly.WorkspaceSvg.prototype.getBlocksBoundingBox = function() { - var topBlocks = this.getTopBlocks(false); - var topComments = this.getTopComments(false); - var topElements = topBlocks.concat(topComments); - // There are no blocks, return empty rectangle. - if (!topElements.length) { - return {x: 0, y: 0, width: 0, height: 0}; - } - - // Initialize boundary using the first block. - var boundary = topElements[0].getBoundingRectangle(); - - // Start at 1 since the 0th block was used for initialization - for (var i = 1; i < topElements.length; i++) { - var blockBoundary = topElements[i].getBoundingRectangle(); - if (blockBoundary.topLeft.x < boundary.topLeft.x) { - boundary.topLeft.x = blockBoundary.topLeft.x; - } - if (blockBoundary.bottomRight.x > boundary.bottomRight.x) { - boundary.bottomRight.x = blockBoundary.bottomRight.x; - } - if (blockBoundary.topLeft.y < boundary.topLeft.y) { - boundary.topLeft.y = blockBoundary.topLeft.y; - } - if (blockBoundary.bottomRight.y > boundary.bottomRight.y) { - boundary.bottomRight.y = blockBoundary.bottomRight.y; - } - } - return { - x: boundary.topLeft.x, - y: boundary.topLeft.y, - width: boundary.bottomRight.x - boundary.topLeft.x, - height: boundary.bottomRight.y - boundary.topLeft.y - }; -}; - -/** - * Clean up the workspace by ordering all the blocks in a column. - */ -Blockly.WorkspaceSvg.prototype.cleanUp = function() { - this.setResizesEnabled(false); - Blockly.Events.setGroup(true); - var topBlocks = this.getTopBlocks(true); - var cursorY = 0; - for (var i = 0, block; block = topBlocks[i]; i++) { - var xy = block.getRelativeToSurfaceXY(); - block.moveBy(-xy.x, cursorY - xy.y); - block.snapToGrid(); - cursorY = block.getRelativeToSurfaceXY().y + - block.getHeightWidth().height + Blockly.BlockSvg.MIN_BLOCK_Y; - } - Blockly.Events.setGroup(false); - this.setResizesEnabled(true); -}; - -/** - * Show the context menu for the workspace. - * @param {!Event} e Mouse event. - * @private - */ -Blockly.WorkspaceSvg.prototype.showContextMenu_ = function(e) { - if (this.options.readOnly || this.isFlyout) { - return; - } - var menuOptions = []; - var topBlocks = this.getTopBlocks(true); - var eventGroup = Blockly.utils.genUid(); - var ws = this; - - // Options to undo/redo previous action. - menuOptions.push(Blockly.ContextMenu.wsUndoOption(this)); - menuOptions.push(Blockly.ContextMenu.wsRedoOption(this)); - - // Option to clean up blocks. - if (this.scrollbar) { - menuOptions.push( - Blockly.ContextMenu.wsCleanupOption(this,topBlocks.length)); - } - - if (this.options.collapse) { - var hasCollapsedBlocks = false; - var hasExpandedBlocks = false; - for (var i = 0; i < topBlocks.length; i++) { - var block = topBlocks[i]; - while (block) { - if (block.isCollapsed()) { - hasCollapsedBlocks = true; - } else { - hasExpandedBlocks = true; - } - block = block.getNextBlock(); - } - } - - menuOptions.push(Blockly.ContextMenu.wsCollapseOption(hasExpandedBlocks, - topBlocks)); - - menuOptions.push(Blockly.ContextMenu.wsExpandOption(hasCollapsedBlocks, - topBlocks)); - } - - // Option to add a workspace comment. - if (this.options.comments) { - menuOptions.push(Blockly.ContextMenu.workspaceCommentOption(ws, e)); - } - - // Option to delete all blocks. - // Count the number of blocks that are deletable. - var deleteList = Blockly.WorkspaceSvg.buildDeleteList_(topBlocks); - // Scratch-specific: don't count shadow blocks in delete count - var deleteCount = 0; - for (var i = 0; i < deleteList.length; i++) { - if (!deleteList[i].isShadow()) { - deleteCount++; - } - } - - var DELAY = 10; - function deleteNext() { - Blockly.Events.setGroup(eventGroup); - var block = deleteList.shift(); - if (block) { - if (block.workspace) { - block.dispose(false, true); - setTimeout(deleteNext, DELAY); - } else { - deleteNext(); - } - } - Blockly.Events.setGroup(false); - } - - var deleteOption = { - text: deleteCount == 1 ? Blockly.Msg.DELETE_BLOCK : - Blockly.Msg.DELETE_X_BLOCKS.replace('%1', String(deleteCount)), - enabled: deleteCount > 0, - callback: function() { - if (ws.currentGesture_) { - ws.currentGesture_.cancel(); - } - if (deleteCount < 2 ) { - deleteNext(); - } else { - Blockly.confirm( - Blockly.Msg.DELETE_ALL_BLOCKS.replace('%1', String(deleteCount)), - function(ok) { - if (ok) { - deleteNext(); - } - }); - } - } - }; - menuOptions.push(deleteOption); - - Blockly.ContextMenu.show(e, menuOptions, this.RTL); -}; - -/** - * Build a list of all deletable blocks that are reachable from the given - * list of top blocks. - * @param {!Array.} topBlocks The list of top blocks on the - * workspace. - * @return {!Array.} A list of deletable blocks on the - * workspace. - * @private - */ -Blockly.WorkspaceSvg.buildDeleteList_ = function(topBlocks) { - var deleteList = []; - function addDeletableBlocks(block) { - if (block.isDeletable()) { - deleteList = deleteList.concat(block.getDescendants(false)); - } else { - var children = block.getChildren(); - for (var i = 0; i < children.length; i++) { - addDeletableBlocks(children[i]); - } - } - } - for (var i = 0; i < topBlocks.length; i++) { - addDeletableBlocks(topBlocks[i]); - } - return deleteList; -}; - -/** - * Modify the block tree on the existing toolbox. - * @param {Node|string} tree DOM tree of blocks, or text representation of same. - */ -Blockly.WorkspaceSvg.prototype.updateToolbox = function(tree) { - tree = Blockly.Options.parseToolboxTree(tree); - if (!tree) { - if (this.options.languageTree) { - throw 'Can\'t nullify an existing toolbox.'; - } - return; // No change (null to null). - } - if (!this.options.languageTree) { - throw 'Existing toolbox is null. Can\'t create new toolbox.'; - } - if (tree.getElementsByTagName('category').length) { - if (!this.toolbox_) { - throw 'Existing toolbox has no categories. Can\'t change mode.'; - } - this.options.languageTree = tree; - this.toolbox_.populate_(tree); - this.toolbox_.position(); - } else { - if (!this.flyout_) { - throw 'Existing toolbox has categories. Can\'t change mode.'; - } - this.options.languageTree = tree; - this.flyout_.show(tree.childNodes); - } -}; - -/** - * Mark this workspace as the currently focused main workspace. - */ -Blockly.WorkspaceSvg.prototype.markFocused = function() { - if (this.options.parentWorkspace) { - this.options.parentWorkspace.markFocused(); - } else { - Blockly.mainWorkspace = this; - // We call e.preventDefault in many event handlers which means we - // need to explicitly grab focus (e.g from a textarea) because - // the browser will not do it for us. How to do this is browser dependant. - this.setBrowserFocus(); - } -}; - -/** - * Set the workspace to have focus in the browser. - * @private - */ -Blockly.WorkspaceSvg.prototype.setBrowserFocus = function() { - // Blur whatever was focused since explcitly grabbing focus below does not - // work in Edge. - if (document.activeElement) { - document.activeElement.blur(); - } - try { - // Focus the workspace SVG - this is for Chrome and Firefox. - this.getParentSvg().focus(); - } catch (e) { - // IE and Edge do not support focus on SVG elements. When that fails - // above, get the injectionDiv (the workspace's parent) and focus that - // instead. This doesn't work in Chrome. - try { - // In IE11, use setActive (which is IE only) so the page doesn't scroll - // to the workspace gaining focus. - this.getParentSvg().parentNode.setActive(); - } catch (e) { - // setActive support was discontinued in Edge so when that fails, call - // focus instead. - this.getParentSvg().parentNode.focus(); - } - } -}; - -/** - * Zooming the blocks centered in (x, y) coordinate with zooming in or out. - * @param {number} x X coordinate of center. - * @param {number} y Y coordinate of center. - * @param {number} amount Amount of zooming - * (negative zooms out and positive zooms in). - */ -Blockly.WorkspaceSvg.prototype.zoom = function(x, y, amount) { - var speed = this.options.zoomOptions.scaleSpeed; - var metrics = this.getMetrics(); - var center = this.getParentSvg().createSVGPoint(); - center.x = x; - center.y = y; - center = center.matrixTransform(this.getCanvas().getCTM().inverse()); - x = center.x; - y = center.y; - var canvas = this.getCanvas(); - // Scale factor. - var scaleChange = Math.pow(speed, amount); - // Clamp scale within valid range. - var newScale = this.scale * scaleChange; - if (newScale > this.options.zoomOptions.maxScale) { - scaleChange = this.options.zoomOptions.maxScale / this.scale; - } else if (newScale < this.options.zoomOptions.minScale) { - scaleChange = this.options.zoomOptions.minScale / this.scale; - } - if (this.scale == newScale) { - return; // No change in zoom. - } - if (this.scrollbar) { - var matrix = canvas.getCTM() - .translate(x * (1 - scaleChange), y * (1 - scaleChange)) - .scale(scaleChange); - // newScale and matrix.a should be identical (within a rounding error). - // ScrollX and scrollY are in pixels. - this.scrollX = matrix.e - metrics.absoluteLeft; - this.scrollY = matrix.f - metrics.absoluteTop; - } - this.setScale(newScale); - // Hide the WidgetDiv without animation (zoom makes field out of place with div) - Blockly.WidgetDiv.hide(true); - Blockly.DropDownDiv.hideWithoutAnimation(); -}; - -/** - * Zooming the blocks centered in the center of view with zooming in or out. - * @param {number} type Type of zooming (-1 zooming out and 1 zooming in). - */ -Blockly.WorkspaceSvg.prototype.zoomCenter = function(type) { - var metrics = this.getMetrics(); - var x = metrics.viewWidth / 2; - var y = metrics.viewHeight / 2; - this.zoom(x, y, type); -}; - -/** - * Zoom the blocks to fit in the workspace if possible. - */ -Blockly.WorkspaceSvg.prototype.zoomToFit = function() { - var metrics = this.getMetrics(); - var blocksBox = this.getBlocksBoundingBox(); - var blocksWidth = blocksBox.width; - var blocksHeight = blocksBox.height; - if (!blocksWidth) { - return; // Prevents zooming to infinity. - } - var workspaceWidth = metrics.viewWidth; - var workspaceHeight = metrics.viewHeight; - if (this.flyout_) { - workspaceWidth -= this.flyout_.width_; - } - if (!this.scrollbar) { - // Origin point of 0,0 is fixed, blocks will not scroll to center. - blocksWidth += metrics.contentLeft; - blocksHeight += metrics.contentTop; - } - var ratioX = workspaceWidth / blocksWidth; - var ratioY = workspaceHeight / blocksHeight; - this.setScale(Math.min(ratioX, ratioY)); - this.scrollCenter(); -}; - -/** - * Center the workspace. - */ -Blockly.WorkspaceSvg.prototype.scrollCenter = function() { - if (!this.scrollbar) { - // Can't center a non-scrolling workspace. - console.warn('Tried to scroll a non-scrollable workspace.'); - return; - } - // Hide the WidgetDiv without animation (zoom makes field out of place with div) - Blockly.WidgetDiv.hide(true); - Blockly.DropDownDiv.hideWithoutAnimation(); - Blockly.hideChaff(false); - var metrics = this.getMetrics(); - var x = (metrics.contentWidth - metrics.viewWidth) / 2; - if (this.flyout_) { - x -= this.flyout_.width_ / 2; - } - var y = (metrics.contentHeight - metrics.viewHeight) / 2; - this.scrollbar.set(x, y); -}; - -/** - * Scroll the workspace to center on the given block. - * @param {?string} id ID of block center on. - * @public - */ -Blockly.WorkspaceSvg.prototype.centerOnBlock = function(id) { - if (!this.scrollbar) { - console.warn('Tried to scroll a non-scrollable workspace.'); - return; - } - - var block = this.getBlockById(id); - if (!block) { - return; - } - - // XY is in workspace coordinates. - var xy = block.getRelativeToSurfaceXY(); - // Height/width is in workspace units. - var heightWidth = block.getHeightWidth(); - - // Find the enter of the block in workspace units. - var blockCenterY = xy.y + heightWidth.height / 2; - - // In RTL the block's position is the top right of the block, not top left. - var multiplier = this.RTL ? -1 : 1; - var blockCenterX = xy.x + (multiplier * heightWidth.width / 2); - - // Workspace scale, used to convert from workspace coordinates to pixels. - var scale = this.scale; - - // Center in pixels. 0, 0 is at the workspace origin. These numbers may - // be negative. - var pixelX = blockCenterX * scale; - var pixelY = blockCenterY * scale; - - var metrics = this.getMetrics(); - - // Scrolling to here would put the block in the top-left corner of the - // visible workspace. - var scrollToBlockX = pixelX - metrics.contentLeft; - var scrollToBlockY = pixelY - metrics.contentTop; - - // viewHeight and viewWidth are in pixels. - var halfViewWidth = metrics.viewWidth / 2; - var halfViewHeight = metrics.viewHeight / 2; - - // Put the block in the center of the visible workspace instead. - var scrollToCenterX = scrollToBlockX - halfViewWidth; - var scrollToCenterY = scrollToBlockY - halfViewHeight; - - Blockly.hideChaff(); - this.scrollbar.set(scrollToCenterX, scrollToCenterY); -}; - -/** - * Set the workspace's zoom factor. - * @param {number} newScale Zoom factor. - */ -Blockly.WorkspaceSvg.prototype.setScale = function(newScale) { - if (this.options.zoomOptions.maxScale && - newScale > this.options.zoomOptions.maxScale) { - newScale = this.options.zoomOptions.maxScale; - } else if (this.options.zoomOptions.minScale && - newScale < this.options.zoomOptions.minScale) { - newScale = this.options.zoomOptions.minScale; - } - this.scale = newScale; - if (this.grid_) { - this.grid_.update(this.scale); - } - if (this.scrollbar) { - this.scrollbar.resize(); - } else { - this.translate(this.scrollX, this.scrollY); - } - Blockly.hideChaff(false); - if (this.flyout_) { - // No toolbox, resize flyout. - this.flyout_.reflow(); - } -}; - -/** - * Scroll the workspace by a specified amount, keeping in the bounds. - * Be sure to set this.startDragMetrics with cached metrics before calling. - * @param {number} x Target X to scroll to - * @param {number} y Target Y to scroll to - */ -Blockly.WorkspaceSvg.prototype.scroll = function(x, y) { - var metrics = this.startDragMetrics; // Cached values - x = Math.min(x, -metrics.contentLeft); - y = Math.min(y, -metrics.contentTop); - x = Math.max(x, metrics.viewWidth - metrics.contentLeft - - metrics.contentWidth); - y = Math.max(y, metrics.viewHeight - metrics.contentTop - - metrics.contentHeight); - // When the workspace starts scrolling, hide the WidgetDiv without animation. - // This is to prevent a dispoal animation from happening in the wrong location. - Blockly.WidgetDiv.hide(true); - Blockly.DropDownDiv.hideWithoutAnimation(); - // Move the scrollbars and the page will scroll automatically. - this.scrollbar.set(-x - metrics.contentLeft, -y - metrics.contentTop); -}; - -/** - * Update the workspace's stack glow radius to be proportional to scale. - * Ensures that stack glows always appear to be a fixed size. - */ -Blockly.WorkspaceSvg.prototype.updateStackGlowScale_ = function() { - // No such def in the flyout workspace. - if (this.options.stackGlowBlur) { - this.options.stackGlowBlur.setAttribute('stdDeviation', - Blockly.Colours.stackGlowSize / this.scale); - } -}; - -/** - * Get the dimensions of the given workspace component, in pixels. - * @param {Blockly.Toolbox|Blockly.Flyout} elem The element to get the - * dimensions of, or null. It should be a toolbox or flyout, and should - * implement getWidth() and getHeight(). - * @return {!Object} An object containing width and height attributes, which - * will both be zero if elem did not exist. - * @private - */ -Blockly.WorkspaceSvg.getDimensionsPx_ = function(elem) { - var width = 0; - var height = 0; - if (elem) { - width = elem.getWidth(); - height = elem.getHeight(); - } - return { - width: width, - height: height - }; -}; - -/** - * Get the content dimensions of the given workspace, taking into account - * whether or not it is scrollable and what size the workspace div is on screen. - * @param {!Blockly.WorkspaceSvg} ws The workspace to measure. - * @param {!Object} svgSize An object containing height and width attributes in - * CSS pixels. Together they specify the size of the visible workspace, not - * including areas covered up by the toolbox. - * @return {!Object} The dimensions of the contents of the given workspace, as - * an object containing at least - * - height and width in pixels - * - left and top in pixels relative to the workspace origin. - * @private - */ -Blockly.WorkspaceSvg.getContentDimensions_ = function(ws, svgSize) { - if (ws.scrollbar) { - return Blockly.WorkspaceSvg.getContentDimensionsBounded_(ws, svgSize); - } else { - return Blockly.WorkspaceSvg.getContentDimensionsExact_(ws); - } -}; - -/** - * Get the bounding box for all workspace contents, in pixels. - * @param {!Blockly.WorkspaceSvg} ws The workspace to inspect. - * @return {!Object} The dimensions of the contents of the given workspace, as - * an object containing - * - height and width in pixels - * - left, right, top and bottom in pixels relative to the workspace origin. - * @private - */ -Blockly.WorkspaceSvg.getContentDimensionsExact_ = function(ws) { - // Block bounding box is in workspace coordinates. - var blockBox = ws.getBlocksBoundingBox(); - var scale = ws.scale; - - // Convert to pixels. - var width = blockBox.width * scale; - var height = blockBox.height * scale; - var left = blockBox.x * scale; - var top = blockBox.y * scale; - - return { - left: left, - top: top, - right: left + width, - bottom: top + height, - width: width, - height: height - }; -}; - -/** - * Calculate the size of a scrollable workspace, which should include room for a - * half screen border around the workspace contents. - * @param {!Blockly.WorkspaceSvg} ws The workspace to measure. - * @param {!Object} svgSize An object containing height and width attributes in - * CSS pixels. Together they specify the size of the visible workspace, not - * including areas covered up by the toolbox. - * @return {!Object} The dimensions of the contents of the given workspace, as - * an object containing - * - height and width in pixels - * - left and top in pixels relative to the workspace origin. - * @private - */ -Blockly.WorkspaceSvg.getContentDimensionsBounded_ = function(ws, svgSize) { - var content = Blockly.WorkspaceSvg.getContentDimensionsExact_(ws); - - // View height and width are both in pixels, and are the same as the SVG size. - var viewWidth = svgSize.width; - var viewHeight = svgSize.height; - var halfWidth = viewWidth / 2; - var halfHeight = viewHeight / 2; - - // Add a border around the content that is at least half a screenful wide. - // Ensure border is wide enough that blocks can scroll over entire screen. - var left = Math.min(content.left - halfWidth, content.right - viewWidth); - var right = Math.max(content.right + halfWidth, content.left + viewWidth); - - var top = Math.min(content.top - halfHeight, content.bottom - viewHeight); - var bottom = Math.max(content.bottom + halfHeight, content.top + viewHeight); - - var dimensions = { - left: left, - top: top, - height: bottom - top, - width: right - left - }; - return dimensions; -}; - -/** - * Return an object with all the metrics required to size scrollbars for a - * top level workspace. The following properties are computed: - * Coordinate system: pixel coordinates. - * .viewHeight: Height of the visible rectangle, - * .viewWidth: Width of the visible rectangle, - * .contentHeight: Height of the contents, - * .contentWidth: Width of the content, - * .viewTop: Offset of top edge of visible rectangle from parent, - * .viewLeft: Offset of left edge of visible rectangle from parent, - * .contentTop: Offset of the top-most content from the y=0 coordinate, - * .contentLeft: Offset of the left-most content from the x=0 coordinate. - * .absoluteTop: Top-edge of view. - * .absoluteLeft: Left-edge of view. - * .toolboxWidth: Width of toolbox, if it exists. Otherwise zero. - * .toolboxHeight: Height of toolbox, if it exists. Otherwise zero. - * .flyoutWidth: Width of the flyout if it is always open. Otherwise zero. - * .flyoutHeight: Height of flyout if it is always open. Otherwise zero. - * .toolboxPosition: Top, bottom, left or right. - * @return {!Object} Contains size and position metrics of a top level - * workspace. - * @private - * @this Blockly.WorkspaceSvg - */ -Blockly.WorkspaceSvg.getTopLevelWorkspaceMetrics_ = function() { - - var toolboxDimensions = - Blockly.WorkspaceSvg.getDimensionsPx_(this.toolbox_); - var flyoutDimensions = - Blockly.WorkspaceSvg.getDimensionsPx_(this.flyout_); - - // Contains height and width in CSS pixels. - // svgSize is equivalent to the size of the injectionDiv at this point. - var svgSize = Blockly.svgSize(this.getParentSvg()); - if (this.toolbox_) { - if (this.toolboxPosition == Blockly.TOOLBOX_AT_TOP || - this.toolboxPosition == Blockly.TOOLBOX_AT_BOTTOM) { - svgSize.height -= toolboxDimensions.height; - } else if (this.toolboxPosition == Blockly.TOOLBOX_AT_LEFT || - this.toolboxPosition == Blockly.TOOLBOX_AT_RIGHT) { - svgSize.width -= toolboxDimensions.width; - } - } - - // svgSize is now the space taken up by the Blockly workspace, not including - // the toolbox. - var contentDimensions = - Blockly.WorkspaceSvg.getContentDimensions_(this, svgSize); - - var absoluteLeft = 0; - if (this.toolbox_ && this.toolboxPosition == Blockly.TOOLBOX_AT_LEFT) { - absoluteLeft = toolboxDimensions.width; - } - var absoluteTop = 0; - if (this.toolbox_ && this.toolboxPosition == Blockly.TOOLBOX_AT_TOP) { - absoluteTop = toolboxDimensions.height; - } - - var metrics = { - contentHeight: contentDimensions.height, - contentWidth: contentDimensions.width, - contentTop: contentDimensions.top, - contentLeft: contentDimensions.left, - - viewHeight: svgSize.height, - viewWidth: svgSize.width, - viewTop: -this.scrollY, // Must be in pixels, somehow. - viewLeft: -this.scrollX, // Must be in pixels, somehow. - - absoluteTop: absoluteTop, - absoluteLeft: absoluteLeft, - - toolboxWidth: toolboxDimensions.width, - toolboxHeight: toolboxDimensions.height, - - flyoutWidth: flyoutDimensions.width, - flyoutHeight: flyoutDimensions.height, - - toolboxPosition: this.toolboxPosition - }; - return metrics; -}; - -/** - * Sets the X/Y translations of a top level workspace to match the scrollbars. - * @param {!Object} xyRatio Contains an x and/or y property which is a float - * between 0 and 1 specifying the degree of scrolling. - * @private - * @this Blockly.WorkspaceSvg - */ -Blockly.WorkspaceSvg.setTopLevelWorkspaceMetrics_ = function(xyRatio) { - if (!this.scrollbar) { - throw 'Attempt to set top level workspace scroll without scrollbars.'; - } - var metrics = this.getMetrics(); - if (goog.isNumber(xyRatio.x)) { - this.scrollX = -metrics.contentWidth * xyRatio.x - metrics.contentLeft; - } - if (goog.isNumber(xyRatio.y)) { - this.scrollY = -metrics.contentHeight * xyRatio.y - metrics.contentTop; - } - var x = this.scrollX + metrics.absoluteLeft; - var y = this.scrollY + metrics.absoluteTop; - this.translate(x, y); - if (this.grid_) { - this.grid_.moveTo(x, y); - } -}; - -/** - * Update whether this workspace has resizes enabled. - * If enabled, workspace will resize when appropriate. - * If disabled, workspace will not resize until re-enabled. - * Use to avoid resizing during a batch operation, for performance. - * @param {boolean} enabled Whether resizes should be enabled. - */ -Blockly.WorkspaceSvg.prototype.setResizesEnabled = function(enabled) { - var reenabled = (!this.resizesEnabled_ && enabled); - this.resizesEnabled_ = enabled; - if (reenabled) { - // Newly enabled. Trigger a resize. - this.resizeContents(); - } -}; - -/** - * Update whether this workspace has toolbox refreshes enabled. - * If enabled, the toolbox will refresh when appropriate. - * If disabled, workspace will not refresh until re-enabled. - * Use to avoid refreshing during a batch operation, for performance. - * @param {boolean} enabled Whether refreshes should be enabled. - */ -Blockly.WorkspaceSvg.prototype.setToolboxRefreshEnabled = function(enabled) { - var reenabled = (!this.toolboxRefreshEnabled_ && enabled); - this.toolboxRefreshEnabled_ = enabled; - if (reenabled) { - // Newly enabled. Trigger a refresh. - this.refreshToolboxSelection_(); - } -}; - - -/** - * Dispose of all blocks in workspace, with an optimization to prevent resizes. - */ -Blockly.WorkspaceSvg.prototype.clear = function() { - this.setResizesEnabled(false); - Blockly.WorkspaceSvg.superClass_.clear.call(this); - this.setResizesEnabled(true); -}; - -/** - * Register a callback function associated with a given key, for clicks on - * buttons and labels in the flyout. - * For instance, a button specified by the XML - * - * should be matched by a call to - * registerButtonCallback("CREATE_VARIABLE", yourCallbackFunction). - * @param {string} key The name to use to look up this function. - * @param {function(!Blockly.FlyoutButton)} func The function to call when the - * given button is clicked. - */ -Blockly.WorkspaceSvg.prototype.registerButtonCallback = function(key, func) { - goog.asserts.assert(goog.isFunction(func), - 'Button callbacks must be functions.'); - this.flyoutButtonCallbacks_[key] = func; -}; - -/** - * Get the callback function associated with a given key, for clicks on buttons - * and labels in the flyout. - * @param {string} key The name to use to look up the function. - * @return {?function(!Blockly.FlyoutButton)} The function corresponding to the - * given key for this workspace; null if no callback is registered. - */ -Blockly.WorkspaceSvg.prototype.getButtonCallback = function(key) { - var result = this.flyoutButtonCallbacks_[key]; - return result ? result : null; -}; - -/** - * Remove a callback for a click on a button in the flyout. - * @param {string} key The name associated with the callback function. - */ -Blockly.WorkspaceSvg.prototype.removeButtonCallback = function(key) { - this.flyoutButtonCallbacks_[key] = null; -}; - -/** - * Register a callback function associated with a given key, for populating - * custom toolbox categories in this workspace. See the variable and procedure - * categories as an example. - * @param {string} key The name to use to look up this function. - * @param {function(!Blockly.Workspace):!Array.} func The function to - * call when the given toolbox category is opened. - */ -Blockly.WorkspaceSvg.prototype.registerToolboxCategoryCallback = function(key, - func) { - goog.asserts.assert(goog.isFunction(func), - 'Toolbox category callbacks must be functions.'); - this.toolboxCategoryCallbacks_[key] = func; -}; - -/** - * Get the callback function associated with a given key, for populating - * custom toolbox categories in this workspace. - * @param {string} key The name to use to look up the function. - * @return {?function(!Blockly.Workspace):!Array.} The function - * corresponding to the given key for this workspace, or null if no function - * is registered. - */ -Blockly.WorkspaceSvg.prototype.getToolboxCategoryCallback = function(key) { - var result = this.toolboxCategoryCallbacks_[key]; - return result ? result : null; -}; - -/** - * Remove a callback for a click on a custom category's name in the toolbox. - * @param {string} key The name associated with the callback function. - */ -Blockly.WorkspaceSvg.prototype.removeToolboxCategoryCallback = function(key) { - this.toolboxCategoryCallbacks_[key] = null; -}; - -/** - * Look up the gesture that is tracking this touch stream on this workspace. - * May create a new gesture. - * @param {!Event} e Mouse event or touch event - * @return {Blockly.Gesture} The gesture that is tracking this touch stream, - * or null if no valid gesture exists. - * @package - */ -Blockly.WorkspaceSvg.prototype.getGesture = function(e) { - var isStart = (e.type == 'mousedown' || e.type == 'touchstart'); - - var gesture = this.currentGesture_; - if (gesture) { - if (isStart && gesture.hasStarted()) { - // That's funny. We must have missed a mouse up. - // Cancel it, rather than try to retrieve all of the state we need. - gesture.cancel(); - return null; - } - return gesture; - } - - // No gesture existed on this workspace, but this looks like the start of a - // new gesture. - if (isStart) { - this.currentGesture_ = new Blockly.Gesture(e, this); - return this.currentGesture_; - } - // No gesture existed and this event couldn't be the start of a new gesture. - return null; -}; - -/** - * Clear the reference to the current gesture. - * @package - */ -Blockly.WorkspaceSvg.prototype.clearGesture = function() { - this.currentGesture_ = null; -}; - -/** - * Cancel the current gesture, if one exists. - * @package - */ -Blockly.WorkspaceSvg.prototype.cancelCurrentGesture = function() { - if (this.currentGesture_) { - this.currentGesture_.cancel(); - } -}; - -/** - * Don't even think about using this function before talking to rachel-fenichel. - * - * Force a drag to start without clicking and dragging the block itself. Used - * to attach duplicated blocks to the mouse pointer. - * @param {!Object} fakeEvent An object with the properties needed to start a - * drag, including clientX and clientY. - * @param {!Blockly.BlockSvg} block The block to start dragging. - * @package - */ -Blockly.WorkspaceSvg.prototype.startDragWithFakeEvent = function(fakeEvent, - block) { - Blockly.Touch.clearTouchIdentifier(); - Blockly.Touch.checkTouchIdentifier(fakeEvent); - var gesture = block.workspace.getGesture(fakeEvent); - gesture.forceStartBlockDrag(fakeEvent, block); -}; - -/** - * Get the audio manager for this workspace. - * @return {Blockly.WorkspaceAudio} The audio manager for this workspace. - */ -Blockly.WorkspaceSvg.prototype.getAudioManager = function() { - return this.audioManager_; -}; - -/** - * Get the grid object for this workspace, or null if there is none. - * @return {Blockly.Grid} The grid object for this workspace. - * @package - */ -Blockly.WorkspaceSvg.prototype.getGrid = function() { - return this.grid_; -}; - -// Export symbols that would otherwise be renamed by Closure compiler. -Blockly.WorkspaceSvg.prototype['setVisible'] = - Blockly.WorkspaceSvg.prototype.setVisible; diff --git a/core/xml.js b/core/xml.js deleted file mode 100644 index 1897a558d3..0000000000 --- a/core/xml.js +++ /dev/null @@ -1,919 +0,0 @@ -/** - * @license - * Visual Blocks Editor - * - * Copyright 2012 Google Inc. - * https://developers.google.com/blockly/ - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @fileoverview XML reader and writer. - * @author fraser@google.com (Neil Fraser) - */ -'use strict'; - -/** - * @name Blockly.Xml - * @namespace - **/ -goog.provide('Blockly.Xml'); - -goog.require('Blockly.Events.BlockCreate'); -goog.require('Blockly.Events.VarCreate'); - -goog.require('goog.asserts'); -goog.require('goog.dom'); - - -/** - * Encode a block tree as XML. - * @param {!Blockly.Workspace} workspace The workspace containing blocks. - * @param {boolean=} opt_noId True if the encoder should skip the block IDs. - * @return {!Element} XML document. - */ -Blockly.Xml.workspaceToDom = function(workspace, opt_noId) { - var xml = goog.dom.createDom('xml'); - xml.appendChild(Blockly.Xml.variablesToDom(workspace.getAllVariables())); - var comments = workspace.getTopComments(true).filter(function(topComment) { - return topComment instanceof Blockly.WorkspaceComment; - }); - for (var i = 0, comment; comment = comments[i]; i++) { - xml.appendChild(comment.toXmlWithXY(opt_noId)); - } - var blocks = workspace.getTopBlocks(true); - for (var i = 0, block; block = blocks[i]; i++) { - xml.appendChild(Blockly.Xml.blockToDomWithXY(block, opt_noId)); - } - return xml; -}; - -/** - * Encode a list of variables as XML. - * @param {!Array.} variableList List of all variable - * models. - * @return {!Element} List of XML elements. - */ -Blockly.Xml.variablesToDom = function(variableList) { - var variables = goog.dom.createDom('variables'); - for (var i = 0, variable; variable = variableList[i]; i++) { - var element = goog.dom.createDom('variable', null, variable.name); - element.setAttribute('type', variable.type); - element.setAttribute('id', variable.getId()); - element.setAttribute('islocal', variable.isLocal); - element.setAttribute('isCloud', variable.isCloud); - variables.appendChild(element); - } - return variables; -}; - -/** - * Encode a block subtree as XML with XY coordinates. - * @param {!Blockly.Block} block The root block to encode. - * @param {boolean=} opt_noId True if the encoder should skip the block ID. - * @return {!Element} Tree of XML elements. - */ -Blockly.Xml.blockToDomWithXY = function(block, opt_noId) { - var width; // Not used in LTR. - if (block.workspace.RTL) { - width = block.workspace.getWidth(); - } - var element = Blockly.Xml.blockToDom(block, opt_noId); - var xy = block.getRelativeToSurfaceXY(); - element.setAttribute('x', - Math.round(block.workspace.RTL ? width - xy.x : xy.x)); - element.setAttribute('y', Math.round(xy.y)); - return element; -}; - -/** - * Encode a variable field as XML. - * @param {!Blockly.FieldVariable} field The field to encode. - * @return {?Element} XML element, or null if the field did not need to be - * serialized. - * @private - */ -Blockly.Xml.fieldToDomVariable_ = function(field) { - var id = field.getValue(); - // The field had not been initialized fully before being serialized. - // This can happen if a block is created directly through a call to - // workspace.newBlock instead of from XML. - // The new block will be serialized for the first time when firing a block - // creation event. - if (id == null) { - field.initModel(); - id = field.getValue(); - } - // Get the variable directly from the field, instead of doing a lookup. This - // will work even if the variable has already been deleted. This can happen - // because the flyout defers deleting blocks until the next time the flyout is - // opened. - var variable = field.getVariable(); - - if (!variable) { - throw Error('Tried to serialize a variable field with no variable.'); - } - var container = goog.dom.createDom('field', null, variable.name); - container.setAttribute('name', field.name); - container.setAttribute('id', variable.getId()); - container.setAttribute('variabletype', variable.type); - return container; -}; - -/** - * Encode a field as XML. - * @param {!Blockly.Field} field The field to encode. - * @param {!Blockly.Workspace} workspace The workspace that the field is in. - * @return {?Element} XML element, or null if the field did not need to be - * serialized. - * @private - */ -Blockly.Xml.fieldToDom_ = function(field) { - if (field.name && field.SERIALIZABLE) { - if (field.referencesVariables()) { - return Blockly.Xml.fieldToDomVariable_(field); - } else { - var container = goog.dom.createDom('field', null, field.getValue()); - container.setAttribute('name', field.name); - return container; - } - } - return null; -}; - -/** - * Encode all of a block's fields as XML and attach them to the given tree of - * XML elements. - * @param {!Blockly.Block} block A block with fields to be encoded. - * @param {!Element} element The XML element to which the field DOM should be - * attached. - * @private - */ -Blockly.Xml.allFieldsToDom_ = function(block, element) { - for (var i = 0, input; input = block.inputList[i]; i++) { - for (var j = 0, field; field = input.fieldRow[j]; j++) { - var fieldDom = Blockly.Xml.fieldToDom_(field); - if (fieldDom) { - element.appendChild(fieldDom); - } - } - } -}; - -/** - * Encode a block subtree as XML. - * @param {!Blockly.Block} block The root block to encode. - * @param {boolean=} opt_noId True if the encoder should skip the block ID. - * @return {!Element} Tree of XML elements. - */ -Blockly.Xml.blockToDom = function(block, opt_noId) { - var element = goog.dom.createDom(block.isShadow() ? 'shadow' : 'block'); - element.setAttribute('type', block.type); - if (!opt_noId) { - element.setAttribute('id', block.id); - } - if (block.mutationToDom) { - // Custom data for an advanced block. - var mutation = block.mutationToDom(); - if (mutation && (mutation.hasChildNodes() || mutation.hasAttributes())) { - element.appendChild(mutation); - } - } - - Blockly.Xml.allFieldsToDom_(block, element); - - Blockly.Xml.scratchCommentToDom_(block, element); - - if (block.data) { - var dataElement = goog.dom.createDom('data', null, block.data); - element.appendChild(dataElement); - } - - for (var i = 0, input; input = block.inputList[i]; i++) { - var container; - var empty = true; - if (input.type == Blockly.DUMMY_INPUT) { - continue; - } else { - var childBlock = input.connection.targetBlock(); - if (input.type == Blockly.INPUT_VALUE) { - container = goog.dom.createDom('value'); - } else if (input.type == Blockly.NEXT_STATEMENT) { - container = goog.dom.createDom('statement'); - } - var shadow = input.connection.getShadowDom(); - if (shadow && (!childBlock || !childBlock.isShadow())) { - var shadowClone = Blockly.Xml.cloneShadow_(shadow); - // Remove the ID from the shadow dom clone if opt_noId - // is specified to true. - if (opt_noId && shadowClone.getAttribute('id')) { - shadowClone.removeAttribute('id'); - } - container.appendChild(shadowClone); - } - if (childBlock) { - container.appendChild(Blockly.Xml.blockToDom(childBlock, opt_noId)); - empty = false; - } - } - container.setAttribute('name', input.name); - if (!empty) { - element.appendChild(container); - } - } - if (block.inputsInlineDefault != block.inputsInline) { - element.setAttribute('inline', block.inputsInline); - } - if (block.isCollapsed()) { - element.setAttribute('collapsed', true); - } - if (block.disabled) { - element.setAttribute('disabled', true); - } - if (!block.isDeletable() && !block.isShadow()) { - element.setAttribute('deletable', false); - } - if (!block.isMovable() && !block.isShadow()) { - element.setAttribute('movable', false); - } - if (!block.isEditable()) { - element.setAttribute('editable', false); - } - - var nextBlock = block.getNextBlock(); - if (nextBlock) { - var container = goog.dom.createDom('next', null, - Blockly.Xml.blockToDom(nextBlock, opt_noId)); - element.appendChild(container); - } - var shadow = block.nextConnection && block.nextConnection.getShadowDom(); - if (shadow && (!nextBlock || !nextBlock.isShadow())) { - container.appendChild(Blockly.Xml.cloneShadow_(shadow)); - } - - return element; -}; - -/** - * Encode a ScratchBlockComment as XML. - * @param {!Blockly.ScratchBlockComment} block The block possibly containing - * a comment to encode. - * @param {!Element} element The XML element to which the comment should - * encoding should be attached. - * @private - */ -Blockly.Xml.scratchCommentToDom_ = function(block, element) { - var commentText = block.getCommentText(); - if (commentText) { - var commentElement = goog.dom.createDom('comment', null, commentText); - if (typeof block.comment == 'object') { - commentElement.setAttribute('id', block.comment.id); - commentElement.setAttribute('pinned', block.comment.isVisible()); - var hw; - if (block.comment instanceof Blockly.ScratchBlockComment) { - hw = block.comment.getHeightWidth(); - } else { - hw = block.comment.getBubbleSize(); - } - commentElement.setAttribute('h', hw.height); - commentElement.setAttribute('w', hw.width); - var xy = block.comment.getXY(); - commentElement.setAttribute('x', - Math.round(block.workspace.RTL ? block.workspace.getWidth() - xy.x - hw.width : - xy.x)); - commentElement.setAttribute('y', xy.y); - commentElement.setAttribute('minimized', block.comment.isMinimized()); - - } - element.appendChild(commentElement); - } -}; - -/** - * Deeply clone the shadow's DOM so that changes don't back-wash to the block. - * @param {!Element} shadow A tree of XML elements. - * @return {!Element} A tree of XML elements. - * @private - */ -Blockly.Xml.cloneShadow_ = function(shadow) { - shadow = shadow.cloneNode(true); - // Walk the tree looking for whitespace. Don't prune whitespace in a tag. - var node = shadow; - var textNode; - while (node) { - if (node.firstChild) { - node = node.firstChild; - } else { - while (node && !node.nextSibling) { - textNode = node; - node = node.parentNode; - if (textNode.nodeType == 3 && textNode.data.trim() == '' && - node.firstChild != textNode) { - // Prune whitespace after a tag. - goog.dom.removeNode(textNode); - } - } - if (node) { - textNode = node; - node = node.nextSibling; - if (textNode.nodeType == 3 && textNode.data.trim() == '') { - // Prune whitespace before a tag. - goog.dom.removeNode(textNode); - } - } - } - } - return shadow; -}; - -/** - * Converts a DOM structure into plain text. - * Currently the text format is fairly ugly: all one line with no whitespace. - * @param {!Element} dom A tree of XML elements. - * @return {string} Text representation. - */ -Blockly.Xml.domToText = function(dom) { - var oSerializer = new XMLSerializer(); - return oSerializer.serializeToString(dom); -}; - -/** - * Converts a DOM structure into properly indented text. - * @param {!Element} dom A tree of XML elements. - * @return {string} Text representation. - */ -Blockly.Xml.domToPrettyText = function(dom) { - // This function is not guaranteed to be correct for all XML. - // But it handles the XML that Blockly generates. - var blob = Blockly.Xml.domToText(dom); - // Place every open and close tag on its own line. - var lines = blob.split('<'); - // Indent every line. - var indent = ''; - for (var i = 1; i < lines.length; i++) { - var line = lines[i]; - if (line[0] == '/') { - indent = indent.substring(2); - } - lines[i] = indent + '<' + line; - if (line[0] != '/' && line.slice(-2) != '/>') { - indent += ' '; - } - } - // Pull simple tags back together. - // E.g. - var text = lines.join('\n'); - text = text.replace(/(<(\w+)\b[^>]*>[^\n]*)\n *<\/\2>/g, '$1'); - // Trim leading blank line. - return text.replace(/^\n/, ''); -}; - -/** - * Converts plain text into a DOM structure. - * Throws an error if XML doesn't parse. - * @param {string} text Text representation. - * @return {!Element} A tree of XML elements. - */ -Blockly.Xml.textToDom = function(text) { - var oParser = new DOMParser(); - var dom = oParser.parseFromString(text, 'text/xml'); - // The DOM should have one and only one top-level node, an XML tag. - if (!dom || !dom.firstChild || - dom.firstChild.nodeName.toLowerCase() != 'xml' || - dom.firstChild !== dom.lastChild) { - // Whatever we got back from the parser is not XML. - goog.asserts.fail('Blockly.Xml.textToDom did not obtain a valid XML tree.'); - } - return dom.firstChild; -}; - -/** - * Clear the given workspace then decode an XML DOM and - * create blocks on the workspace. - * @param {!Element} xml XML DOM. - * @param {!Blockly.Workspace} workspace The workspace. - * @return {Array.} An array containing new block ids. - */ -Blockly.Xml.clearWorkspaceAndLoadFromXml = function(xml, workspace) { - workspace.setResizesEnabled(false); - workspace.setToolboxRefreshEnabled(false); - workspace.clear(); - var blockIds = Blockly.Xml.domToWorkspace(xml, workspace); - workspace.setResizesEnabled(true); - workspace.setToolboxRefreshEnabled(true); - return blockIds; -}; - -/** - * Decode an XML DOM and create blocks on the workspace. - * @param {!Element} xml XML DOM. - * @param {!Blockly.Workspace} workspace The workspace. - * @return {Array.} An array containing new block IDs. - */ -Blockly.Xml.domToWorkspace = function(xml, workspace) { - if (xml instanceof Blockly.Workspace) { - var swap = xml; - xml = workspace; - workspace = swap; - console.warn('Deprecated call to Blockly.Xml.domToWorkspace, ' + - 'swap the arguments.'); - } - var width; // Not used in LTR. - if (workspace.RTL) { - width = workspace.getWidth(); - } - var newBlockIds = []; // A list of block IDs added by this call. - Blockly.Field.startCache(); - // Safari 7.1.3 is known to provide node lists with extra references to - // children beyond the lists' length. Trust the length, do not use the - // looping pattern of checking the index for an object. - var childCount = xml.childNodes.length; - var existingGroup = Blockly.Events.getGroup(); - if (!existingGroup) { - Blockly.Events.setGroup(true); - } - - // Disable workspace resizes as an optimization. - if (workspace.setResizesEnabled) { - workspace.setResizesEnabled(false); - } - var variablesFirst = true; - try { - for (var i = 0; i < childCount; i++) { - var xmlChild = xml.childNodes[i]; - var name = xmlChild.nodeName.toLowerCase(); - if (name == 'block' || - (name == 'shadow' && !Blockly.Events.recordUndo)) { - // Allow top-level shadow blocks if recordUndo is disabled since - // that means an undo is in progress. Such a block is expected - // to be moved to a nested destination in the next operation. - var block = Blockly.Xml.domToBlock(xmlChild, workspace); - newBlockIds.push(block.id); - var blockX = xmlChild.hasAttribute('x') ? - parseInt(xmlChild.getAttribute('x'), 10) : 10; - var blockY = xmlChild.hasAttribute('y') ? - parseInt(xmlChild.getAttribute('y'), 10) : 10; - if (!isNaN(blockX) && !isNaN(blockY)) { - block.moveBy(workspace.RTL ? width - blockX : blockX, blockY); - if (block.comment && typeof block.comment === 'object') { - var commentXY = block.comment.getXY(); - var commentWidth = block.comment.getBubbleSize().width; - block.comment.moveTo(block.workspace.RTL ? width - commentXY.x - commentWidth : commentXY.x, commentXY.y); - } - } - variablesFirst = false; - } else if (name == 'shadow') { - goog.asserts.fail('Shadow block cannot be a top-level block.'); - variablesFirst = false; - } else if (name == 'comment') { - if (workspace.rendered) { - Blockly.WorkspaceCommentSvg.fromXml(xmlChild, workspace, width); - } else { - Blockly.WorkspaceComment.fromXml(xmlChild, workspace); - } - } else if (name == 'variables') { - if (variablesFirst) { - Blockly.Xml.domToVariables(xmlChild, workspace); - } else { - throw Error('\'variables\' tag must exist once before block and ' + - 'shadow tag elements in the workspace XML, but it was found in ' + - 'another location.'); - } - variablesFirst = false; - } - } - } finally { - if (!existingGroup) { - Blockly.Events.setGroup(false); - } - Blockly.Field.stopCache(); - } - // Re-enable workspace resizing. - if (workspace.setResizesEnabled) { - workspace.setResizesEnabled(true); - } - return newBlockIds; -}; - -/** - * Decode an XML DOM and create blocks on the workspace. Position the new - * blocks immediately below prior blocks, aligned by their starting edge. - * @param {!Element} xml The XML DOM. - * @param {!Blockly.Workspace} workspace The workspace to add to. - * @return {Array.} An array containing new block IDs. - */ -Blockly.Xml.appendDomToWorkspace = function(xml, workspace) { - var bbox; // Bounding box of the current blocks. - // First check if we have a workspaceSvg, otherwise the blocks have no shape - // and the position does not matter. - if (workspace.hasOwnProperty('scale')) { - var savetab = Blockly.BlockSvg.TAB_WIDTH; - try { - Blockly.BlockSvg.TAB_WIDTH = 0; - bbox = workspace.getBlocksBoundingBox(); - } finally { - Blockly.BlockSvg.TAB_WIDTH = savetab; - } - } - // Load the new blocks into the workspace and get the IDs of the new blocks. - var newBlockIds = Blockly.Xml.domToWorkspace(xml,workspace); - if (bbox && bbox.height) { // check if any previous block - var offsetY = 0; // offset to add to y of the new block - var offsetX = 0; - var farY = bbox.y + bbox.height; //bottom position - var topX = bbox.x; // x of bounding box - // check position of the new blocks - var newX = Infinity; // x of top corner - var newY = Infinity; // y of top corner - for (var i = 0; i < newBlockIds.length; i++) { - var blockXY = workspace.getBlockById(newBlockIds[i]).getRelativeToSurfaceXY(); - if (blockXY.y < newY) { - newY = blockXY.y; - } - if (blockXY.x < newX) { //if we align also on x - newX = blockXY.x; - } - } - offsetY = farY - newY + Blockly.BlockSvg.SEP_SPACE_Y; - offsetX = topX - newX; - // move the new blocks to append them at the bottom - var width; // Not used in LTR. - if (workspace.RTL) { - width = workspace.getWidth(); - } - for (var i = 0; i < newBlockIds.length; i++) { - var block = workspace.getBlockById(newBlockIds[i]); - block.moveBy(workspace.RTL ? width - offsetX : offsetX, offsetY); - } - } - return newBlockIds; -}; - -/** - * Decode an XML block tag and create a block (and possibly sub blocks) on the - * workspace. - * @param {!Element} xmlBlock XML block element. - * @param {!Blockly.Workspace} workspace The workspace. - * @return {!Blockly.Block} The root block created. - */ -Blockly.Xml.domToBlock = function(xmlBlock, workspace) { - if (xmlBlock instanceof Blockly.Workspace) { - var swap = xmlBlock; - xmlBlock = workspace; - workspace = swap; - console.warn('Deprecated call to Blockly.Xml.domToBlock, ' + - 'swap the arguments.'); - } - // Create top-level block. - Blockly.Events.disable(); - var variablesBeforeCreation = workspace.getAllVariables(); - try { - var topBlock = Blockly.Xml.domToBlockHeadless_(xmlBlock, workspace); - // Generate list of all blocks. - var blocks = topBlock.getDescendants(false); - if (workspace.rendered) { - // Hide connections to speed up assembly. - topBlock.setConnectionsHidden(true); - // Render each block. - for (var i = blocks.length - 1; i >= 0; i--) { - blocks[i].initSvg(); - } - for (var i = blocks.length - 1; i >= 0; i--) { - blocks[i].render(false); - } - // Populating the connection database may be deferred until after the - // blocks have rendered. - if (!workspace.isFlyout) { - setTimeout(function() { - if (topBlock.workspace) { // Check that the block hasn't been deleted. - topBlock.setConnectionsHidden(false); - } - }, 1); - } - topBlock.updateDisabled(); - // Allow the scrollbars to resize and move based on the new contents. - // TODO(@picklesrus): #387. Remove when domToBlock avoids resizing. - workspace.resizeContents(); - } else { - for (var i = blocks.length - 1; i >= 0; i--) { - blocks[i].initModel(); - } - } - } finally { - Blockly.Events.enable(); - } - if (Blockly.Events.isEnabled()) { - var newVariables = Blockly.Variables.getAddedVariables(workspace, - variablesBeforeCreation); - // Fire a VarCreate event for each (if any) new variable created. - for (var i = 0; i < newVariables.length; i++) { - var thisVariable = newVariables[i]; - Blockly.Events.fire(new Blockly.Events.VarCreate(thisVariable)); - } - // Block events come after var events, in case they refer to newly created - // variables. - Blockly.Events.fire(new Blockly.Events.BlockCreate(topBlock)); - } - return topBlock; -}; - -/** - * Decode an XML list of variables and add the variables to the workspace. - * @param {!Element} xmlVariables List of XML variable elements. - * @param {!Blockly.Workspace} workspace The workspace to which the variable - * should be added. - */ -Blockly.Xml.domToVariables = function(xmlVariables, workspace) { - for (var i = 0, xmlChild; xmlChild = xmlVariables.children[i]; i++) { - var type = xmlChild.getAttribute('type'); - var id = xmlChild.getAttribute('id'); - var isLocal = xmlChild.getAttribute('islocal') == 'true'; - var isCloud = xmlChild.getAttribute('iscloud') == 'true'; - var name = xmlChild.textContent; - - if (typeof(type) === undefined || type === null) { - throw Error('Variable with id, ' + id + ' is without a type'); - } - workspace.createVariable(name, type, id, isLocal, isCloud); - } -}; - -/** - * Decode an XML block tag and create a block (and possibly sub blocks) on the - * workspace. - * @param {!Element} xmlBlock XML block element. - * @param {!Blockly.Workspace} workspace The workspace. - * @return {!Blockly.Block} The root block created. - * @private - */ -Blockly.Xml.domToBlockHeadless_ = function(xmlBlock, workspace) { - var block = null; - var prototypeName = xmlBlock.getAttribute('type'); - goog.asserts.assert( - prototypeName, 'Block type unspecified: %s', xmlBlock.outerHTML); - var id = xmlBlock.getAttribute('id'); - block = workspace.newBlock(prototypeName, id); - - var blockChild = null; - for (var i = 0, xmlChild; xmlChild = xmlBlock.childNodes[i]; i++) { - if (xmlChild.nodeType == 3) { - // Ignore any text at the level. It's all whitespace anyway. - continue; - } - var input; - - // Find any enclosed blocks or shadows in this tag. - var childBlockElement = null; - var childShadowElement = null; - for (var j = 0, grandchild; grandchild = xmlChild.childNodes[j]; j++) { - if (grandchild.nodeType == 1) { - if (grandchild.nodeName.toLowerCase() == 'block') { - childBlockElement = /** @type {!Element} */ (grandchild); - } else if (grandchild.nodeName.toLowerCase() == 'shadow') { - childShadowElement = /** @type {!Element} */ (grandchild); - } - } - } - // Use the shadow block if there is no child block. - if (!childBlockElement && childShadowElement) { - childBlockElement = childShadowElement; - } - - var name = xmlChild.getAttribute('name'); - switch (xmlChild.nodeName.toLowerCase()) { - case 'mutation': - // Custom data for an advanced block. - if (block.domToMutation) { - block.domToMutation(xmlChild); - if (block.initSvg) { - // Mutation may have added some elements that need initializing. - block.initSvg(); - } - } - break; - case 'comment': - var commentId = xmlChild.getAttribute('id'); - var bubbleX = parseInt(xmlChild.getAttribute('x'), 10); - var bubbleY = parseInt(xmlChild.getAttribute('y'), 10); - var minimized = xmlChild.getAttribute('minimized') || false; - - // Note bubbleX and bubbleY can be NaN, but the ScratchBlockComment - // constructor will handle that. - block.setCommentText(xmlChild.textContent, commentId, bubbleX, bubbleY, - minimized == 'true'); - - var visible = xmlChild.getAttribute('pinned'); - if (visible && !block.isInFlyout) { - // Give the renderer a millisecond to render and position the block - // before positioning the comment bubble. - setTimeout(function() { - if (block.comment && block.comment.setVisible) { - block.comment.setVisible(visible == 'true'); - } - }, 1); - } - var bubbleW = parseInt(xmlChild.getAttribute('w'), 10); - var bubbleH = parseInt(xmlChild.getAttribute('h'), 10); - if (!isNaN(bubbleW) && !isNaN(bubbleH) && - block.comment && block.comment.setVisible) { - if (block.comment instanceof Blockly.ScratchBlockComment) { - block.comment.setSize(bubbleW, bubbleH); - } else { - block.comment.setBubbleSize(bubbleW, bubbleH); - } - } - break; - case 'data': - block.data = xmlChild.textContent; - break; - case 'title': - // Titles were renamed to field in December 2013. - // Fall through. - case 'field': - Blockly.Xml.domToField_(block, name, xmlChild); - break; - case 'value': - case 'statement': - input = block.getInput(name); - if (!input) { - console.warn('Ignoring non-existent input ' + name + ' in block ' + - prototypeName); - break; - } - if (childShadowElement) { - input.connection.setShadowDom(childShadowElement); - } - if (childBlockElement) { - blockChild = Blockly.Xml.domToBlockHeadless_(childBlockElement, - workspace); - if (blockChild.outputConnection) { - input.connection.connect(blockChild.outputConnection); - } else if (blockChild.previousConnection) { - input.connection.connect(blockChild.previousConnection); - } else { - goog.asserts.fail( - 'Child block does not have output or previous statement.'); - } - } - break; - case 'next': - if (childShadowElement && block.nextConnection) { - block.nextConnection.setShadowDom(childShadowElement); - } - if (childBlockElement) { - goog.asserts.assert(block.nextConnection, - 'Next statement does not exist.'); - // If there is more than one XML 'next' tag. - goog.asserts.assert(!block.nextConnection.isConnected(), - 'Next statement is already connected.'); - blockChild = Blockly.Xml.domToBlockHeadless_(childBlockElement, - workspace); - goog.asserts.assert(blockChild.previousConnection, - 'Next block does not have previous statement.'); - block.nextConnection.connect(blockChild.previousConnection); - } - break; - default: - // Unknown tag; ignore. Same principle as HTML parsers. - console.warn('Ignoring unknown tag: ' + xmlChild.nodeName); - } - } - - var inline = xmlBlock.getAttribute('inline'); - if (inline) { - block.setInputsInline(inline == 'true'); - } - var disabled = xmlBlock.getAttribute('disabled'); - if (disabled) { - block.setDisabled(disabled == 'true' || disabled == 'disabled'); - } - var deletable = xmlBlock.getAttribute('deletable'); - if (deletable) { - block.setDeletable(deletable == 'true'); - } - var movable = xmlBlock.getAttribute('movable'); - if (movable) { - block.setMovable(movable == 'true'); - } - var editable = xmlBlock.getAttribute('editable'); - if (editable) { - block.setEditable(editable == 'true'); - } - var collapsed = xmlBlock.getAttribute('collapsed'); - if (collapsed) { - block.setCollapsed(collapsed == 'true'); - } - if (xmlBlock.nodeName.toLowerCase() == 'shadow') { - // Ensure all children are also shadows. - var children = block.getChildren(false); - for (var i = 0, child; child = children[i]; i++) { - goog.asserts.assert( - child.isShadow(), 'Shadow block not allowed non-shadow child.'); - } - block.setShadow(true); - } - return block; -}; - -/** - * Decode an XML variable field tag and set the value of that field. - * @param {!Blockly.Workspace} workspace The workspace that is currently being - * deserialized. - * @param {!Element} xml The field tag to decode. - * @param {string} text The text content of the XML tag. - * @param {!Blockly.FieldVariable} field The field on which the value will be - * set. - * @private - */ -Blockly.Xml.domToFieldVariable_ = function(workspace, xml, text, field) { - var type = xml.getAttribute('variabletype') || ''; - // TODO (fenichel): Does this need to be explicit or not? - if (type == '\'\'') { - type = ''; - } - - var variable; - // This check ensures that there is not both a potential variable and a real - // variable with the same name and type. - if (!workspace.getPotentialVariableMap() && !workspace.isFlyout && - workspace.getFlyout()) { - var flyoutWs = workspace.getFlyout().getWorkspace(); - variable = Blockly.Variables.realizePotentialVar(text, type, flyoutWs, true); - } - if (!variable) { - variable = Blockly.Variables.getOrCreateVariablePackage(workspace, xml.id, - text, type); - } - - // This should never happen :) - if (type != null && type !== variable.type) { - throw Error('Serialized variable type with id \'' + - variable.getId() + '\' had type ' + variable.type + ', and ' + - 'does not match variable field that references it: ' + - Blockly.Xml.domToText(xml) + '.'); - } - - field.setValue(variable.getId()); -}; - -/** - * Decode an XML field tag and set the value of that field on the given block. - * @param {!Blockly.Block} block The block that is currently being deserialized. - * @param {string} fieldName The name of the field on the block. - * @param {!Element} xml The field tag to decode. - * @private - */ -Blockly.Xml.domToField_ = function(block, fieldName, xml) { - var field = block.getField(fieldName); - if (!field) { - console.warn('Ignoring non-existent field ' + fieldName + ' in block ' + - block.type); - return; - } - - var workspace = block.workspace; - var text = xml.textContent; - if (field.referencesVariables()) { - Blockly.Xml.domToFieldVariable_(workspace, xml, text, field); - } else { - field.setValue(text); - } -}; - -/** - * Remove any 'next' block (statements in a stack). - * @param {!Element} xmlBlock XML block element. - */ -Blockly.Xml.deleteNext = function(xmlBlock) { - for (var i = 0, child; child = xmlBlock.childNodes[i]; i++) { - if (child.nodeName.toLowerCase() == 'next') { - xmlBlock.removeChild(child); - break; - } - } -}; - -// Export symbols that would otherwise be renamed by Closure compiler. -if (!goog.global['Blockly']) { - goog.global['Blockly'] = {}; -} -if (!goog.global['Blockly']['Xml']) { - goog.global['Blockly']['Xml'] = {}; -} -goog.global['Blockly']['Xml']['domToText'] = Blockly.Xml.domToText; -goog.global['Blockly']['Xml']['domToWorkspace'] = Blockly.Xml.domToWorkspace; -goog.global['Blockly']['Xml']['textToDom'] = Blockly.Xml.textToDom; -goog.global['Blockly']['Xml']['workspaceToDom'] = Blockly.Xml.workspaceToDom; -goog.global['Blockly']['Xml']['clearWorkspaceAndLoadFromXml'] = - Blockly.Xml.clearWorkspaceAndLoadFromXml; diff --git a/core/zoom_controls.js b/core/zoom_controls.js deleted file mode 100644 index 3f8f1ab760..0000000000 --- a/core/zoom_controls.js +++ /dev/null @@ -1,301 +0,0 @@ -/** - * @license - * Visual Blocks Editor - * - * Copyright 2015 Google Inc. - * https://developers.google.com/blockly/ - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @fileoverview Object representing a zoom icons. - * @author carloslfu@gmail.com (Carlos Galarza) - */ -'use strict'; - -goog.provide('Blockly.ZoomControls'); - -goog.require('Blockly.Touch'); -goog.require('goog.dom'); - - -/** - * Class for a zoom controls. - * @param {!Blockly.Workspace} workspace The workspace to sit in. - * @constructor - */ -Blockly.ZoomControls = function(workspace) { - this.workspace_ = workspace; -}; - -/** - * Zoom in icon path. - * @type {string} - * @private - */ -Blockly.ZoomControls.prototype.ZOOM_IN_PATH_ = 'zoom-in.svg'; - -/** - * Zoom out icon path. - * @type {string} - * @private - */ -Blockly.ZoomControls.prototype.ZOOM_OUT_PATH_ = 'zoom-out.svg'; - -/** - * Zoom reset icon path. - * @type {string} - * @private - */ -Blockly.ZoomControls.prototype.ZOOM_RESET_PATH_ = 'zoom-reset.svg'; - -/** - * Width of the zoom controls. - * @type {number} - * @private - */ -Blockly.ZoomControls.prototype.WIDTH_ = 36; - -/** - * Height of the zoom controls. - * @type {number} - * @private - */ -Blockly.ZoomControls.prototype.HEIGHT_ = 124; - -/** - * Distance between each zoom control. - * @type {number} - * @private - */ -Blockly.ZoomControls.prototype.MARGIN_BETWEEN_ = 8; - -/** - * Distance between zoom controls and bottom edge of workspace. - * @type {number} - * @private - */ -Blockly.ZoomControls.prototype.MARGIN_BOTTOM_ = 12; - -/** - * Distance between zoom controls and right edge of workspace. - * @type {number} - * @private - */ -Blockly.ZoomControls.prototype.MARGIN_SIDE_ = 12; - -/** - * The SVG group containing the zoom controls. - * @type {Element} - * @private - */ -Blockly.ZoomControls.prototype.svgGroup_ = null; - -/** - * Left coordinate of the zoom controls. - * @type {number} - * @private - */ -Blockly.ZoomControls.prototype.left_ = 0; - -/** - * Top coordinate of the zoom controls. - * @type {number} - * @private - */ -Blockly.ZoomControls.prototype.top_ = 0; - -/** - * Create the zoom controls. - * @return {!Element} The zoom controls SVG group. - */ -Blockly.ZoomControls.prototype.createDom = function() { - this.svgGroup_ = - Blockly.utils.createSvgElement('g', {'class': 'blocklyZoom'}, null); - this.createZoomOutSvg_(); - this.createZoomInSvg_(); - this.createZoomResetSvg_(); - return this.svgGroup_; -}; - -/** - * Initialize the zoom controls. - * @param {number} bottom Distance from workspace bottom to bottom of controls. - * @return {number} Distance from workspace bottom to the top of controls. - */ -Blockly.ZoomControls.prototype.init = function(bottom) { - this.bottom_ = this.MARGIN_BOTTOM_ + bottom; - return this.bottom_ + this.HEIGHT_; -}; - -/** - * Dispose of this zoom controls. - * Unlink from all DOM elements to prevent memory leaks. - */ -Blockly.ZoomControls.prototype.dispose = function() { - if (this.svgGroup_) { - goog.dom.removeNode(this.svgGroup_); - this.svgGroup_ = null; - } - this.workspace_ = null; -}; - -/** - * Move the zoom controls to the bottom-right corner. - */ -Blockly.ZoomControls.prototype.position = function() { - var metrics = this.workspace_.getMetrics(); - if (!metrics) { - // There are no metrics available (workspace is probably not visible). - return; - } - if (this.workspace_.RTL) { - this.left_ = this.MARGIN_SIDE_ + Blockly.Scrollbar.scrollbarThickness; - if (metrics.toolboxPosition == Blockly.TOOLBOX_AT_LEFT) { - this.left_ += metrics.flyoutWidth; - if (this.workspace_.toolbox_) { - this.left_ += metrics.absoluteLeft; - } - } - } else { - this.left_ = metrics.viewWidth + metrics.absoluteLeft - - this.WIDTH_ - this.MARGIN_SIDE_ - Blockly.Scrollbar.scrollbarThickness; - - if (metrics.toolboxPosition == Blockly.TOOLBOX_AT_RIGHT) { - this.left_ -= metrics.flyoutWidth; - } - } - this.top_ = metrics.viewHeight + metrics.absoluteTop - - this.HEIGHT_ - this.bottom_; - if (metrics.toolboxPosition == Blockly.TOOLBOX_AT_BOTTOM) { - this.top_ -= metrics.flyoutHeight; - } - this.svgGroup_.setAttribute('transform', - 'translate(' + this.left_ + ',' + this.top_ + ')'); -}; - -/** - * Create the zoom in icon and its event handler. - * The Scratch Blocks implementation of this function is different from the - * Blockly implementation. - * @private - */ -Blockly.ZoomControls.prototype.createZoomOutSvg_ = function() { - /* This markup will be generated and added to the "blocklyZoom" group: - - - */ - var ws = this.workspace_; - /** - * Zoom out control. - * @type {SVGElement} - */ - var zoomoutSvg = Blockly.utils.createSvgElement( - 'image', - { - 'width': this.WIDTH_, - 'height': this.WIDTH_, - 'y': (this.WIDTH_ * 1) + (this.MARGIN_BETWEEN_ * 1) - }, - this.svgGroup_ - ); - zoomoutSvg.setAttributeNS('http://www.w3.org/1999/xlink', 'xlink:href', - ws.options.pathToMedia + this.ZOOM_OUT_PATH_); - // Attach listener. - Blockly.bindEventWithChecks_(zoomoutSvg, 'mousedown', null, function(e) { - ws.markFocused(); - ws.zoomCenter(-1); - Blockly.Touch.clearTouchIdentifier(); // Don't block future drags. - e.stopPropagation(); // Don't start a workspace scroll. - e.preventDefault(); // Stop double-clicking from selecting text. - }); -}; - -/** - * Create the zoom out icon and its event handler. - * The Scratch Blocks implementation of this function is different from the - * Blockly implementation. - * @private - */ -Blockly.ZoomControls.prototype.createZoomInSvg_ = function() { - /* This markup will be generated and added to the "blocklyZoom" group: - - - */ - var ws = this.workspace_; - /** - * Zoom in control. - * @type {SVGElement} - */ - var zoominSvg = Blockly.utils.createSvgElement( - 'image', - { - 'width': this.WIDTH_, - 'height': this.WIDTH_, - 'y': 0 - }, - this.svgGroup_ - ); - zoominSvg.setAttributeNS('http://www.w3.org/1999/xlink', 'xlink:href', - ws.options.pathToMedia + this.ZOOM_IN_PATH_); - - // Attach listener. - Blockly.bindEventWithChecks_(zoominSvg, 'mousedown', null, function(e) { - ws.markFocused(); - ws.zoomCenter(1); - Blockly.Touch.clearTouchIdentifier(); // Don't block future drags. - e.stopPropagation(); // Don't start a workspace scroll. - e.preventDefault(); // Stop double-clicking from selecting text. - }); -}; - -/** - * Create the zoom reset icon and its event handler. - * The Scratch Blocks implementation of this function is different from the - * Blockly implementation. - * @private - */ -Blockly.ZoomControls.prototype.createZoomResetSvg_ = function() { - /* This markup will be generated and added to the "blocklyZoom" group: - - - */ - var ws = this.workspace_; - - /** - * Zoom reset control. - * @type {SVGElement} - */ - var zoomresetSvg = Blockly.utils.createSvgElement( - 'image', - { - 'width': this.WIDTH_, - 'height': this.WIDTH_, - 'y': (this.WIDTH_ * 2) + (this.MARGIN_BETWEEN_ * 2) - }, - this.svgGroup_ - ); - zoomresetSvg.setAttributeNS('http://www.w3.org/1999/xlink', 'xlink:href', - ws.options.pathToMedia + this.ZOOM_RESET_PATH_); - - // Attach event listeners. - Blockly.bindEventWithChecks_(zoomresetSvg, 'mousedown', null, function(e) { - ws.markFocused(); - ws.setScale(ws.options.zoomOptions.startScale); - ws.scrollCenter(); - Blockly.Touch.clearTouchIdentifier(); // Don't block future drags. - e.stopPropagation(); // Don't start a workspace scroll. - e.preventDefault(); // Stop double-clicking from selecting text. - }); -}; From 665d1963759caab39c1a0078a81e5e3b63734f05 Mon Sep 17 00:00:00 2001 From: Aaron Dodson Date: Mon, 14 Oct 2024 08:50:22 -0700 Subject: [PATCH 100/130] fix: Add support for flyout labels with status indicators (#212) * chore: rename and move flyout_extension_category_header.js into src * fix: add support for status indicators in flyout labels * chore: improve docs for StatusIndicatorLabel --- src/checkable_continuous_flyout.js | 14 +- src/index.js | 9 +- src/scratch_continuous_category.js | 64 +++++- src/scratch_continuous_toolbox.js | 54 +++++ src/status_indicator_label.js | 186 ++++++++++++++++++ src/status_indicator_label_flyout_inflater.js | 42 ++++ 6 files changed, 360 insertions(+), 9 deletions(-) create mode 100644 src/status_indicator_label.js create mode 100644 src/status_indicator_label_flyout_inflater.js diff --git a/src/checkable_continuous_flyout.js b/src/checkable_continuous_flyout.js index 81a83fdd96..741d83cf1c 100644 --- a/src/checkable_continuous_flyout.js +++ b/src/checkable_continuous_flyout.js @@ -7,6 +7,7 @@ import * as Blockly from "blockly/core"; import { ContinuousFlyout } from "@blockly/continuous-toolbox"; import { RecyclableBlockFlyoutInflater } from "./recyclable_block_flyout_inflater.js"; +import { StatusIndicatorLabel } from "./status_indicator_label.js"; export class CheckableContinuousFlyout extends ContinuousFlyout { /** @@ -97,7 +98,7 @@ export class CheckableContinuousFlyout extends ContinuousFlyout { const categoryLabels = this.getContents() .filter( (item) => - item.type === "label" && + (item.type === "label" || item.type === "status_indicator_label") && item.element.isLabel() && this.getParentToolbox_().getCategoryByName( item.element.getButtonText() @@ -123,4 +124,15 @@ export class CheckableContinuousFlyout extends ContinuousFlyout { // updated for the new flyout API. Blockly.VerticalFlyout.prototype.layout_.call(this, contents); } + + /** + * Updates the state of status indicators for hardware-based extensions. + */ + refreshStatusButtons() { + for (const item of this.contents) { + if (item.element instanceof StatusIndicatorLabel) { + item.element.refreshStatus(); + } + } + } } diff --git a/src/index.js b/src/index.js index 5f768c9b34..d259ff00ee 100644 --- a/src/index.js +++ b/src/index.js @@ -33,7 +33,6 @@ import { import { CheckableContinuousFlyout } from "./checkable_continuous_flyout.js"; import { buildGlowFilter, glowStack } from "./glows.js"; import { ScratchContinuousToolbox } from "./scratch_continuous_toolbox.js"; -import "./scratch_continuous_category.js"; import "./scratch_comment_icon.js"; import "./scratch_dragger.js"; import "./scratch_variable_map.js"; @@ -62,6 +61,8 @@ import { registerFieldVariableGetter } from "./fields/field_variable_getter.js"; import { registerFieldVariable } from "./fields/field_variable.js"; import { registerFieldVerticalSeparator } from "./fields/field_vertical_separator.js"; import { registerRecyclableBlockFlyoutInflater } from "./recyclable_block_flyout_inflater.js"; +import { registerStatusIndicatorLabelFlyoutInflater } from "./status_indicator_label_flyout_inflater.js"; +import { registerScratchContinuousCategory } from "./scratch_continuous_category.js"; export * from "blockly/core"; export * from "./block_reporting.js"; @@ -76,6 +77,10 @@ export { ScratchVariables }; export { contextMenuItems }; export { FieldColourSlider, FieldNote }; export { CheckboxBubble } from "./checkbox_bubble.js"; +export { + StatusIndicatorLabel, + StatusButtonState, +} from "./status_indicator_label.js"; export function inject(container, options) { registerFieldAngle(); @@ -89,6 +94,8 @@ export function inject(container, options) { registerFieldVariable(); registerFieldVerticalSeparator(); registerRecyclableBlockFlyoutInflater(); + registerStatusIndicatorLabelFlyoutInflater(); + registerScratchContinuousCategory(); Object.assign(options, { renderer: "scratch", diff --git a/src/scratch_continuous_category.js b/src/scratch_continuous_category.js index 0cbfa12e66..8406014357 100644 --- a/src/scratch_continuous_category.js +++ b/src/scratch_continuous_category.js @@ -1,7 +1,39 @@ +/** + * @license + * Copyright 2024 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + import * as Blockly from "blockly/core"; import { ContinuousCategory } from "@blockly/continuous-toolbox"; -class ScratchContinuousCategory extends ContinuousCategory { +export class ScratchContinuousCategory extends ContinuousCategory { + /** + * Whether this toolbox category has a status indicator button on its label + * in the flyout, typically for extensions that interface with hardware + * devices. + * @type {boolean} + */ + showStatusButton = false; + + /** Creates a new ScratchContinuousCategory. + * + * @param {!Blockly.toolbox.CategoryInfo} toolboxItemDef A toolbox item + * definition. + * @param {!Blockly.Toolbox} parentToolbox The toolbox this category is being + * added to. + * @param {?Blockly.ICollapsibleToolboxItem} opt_parent The parent toolbox + * category, if any. + */ + constructor(toolboxItemDef, parentToolbox, opt_parent) { + super(toolboxItemDef, parentToolbox, opt_parent); + this.showStatusButton = toolboxItemDef["showStatusButton"] === "true"; + } + + /** + * Creates a DOM element for this category's icon. + * @returns {!HTMLElement} A DOM element for this category's icon. + */ createIconDom_() { if (this.toolboxItemDef_.iconURI) { const icon = document.createElement("img"); @@ -15,16 +47,34 @@ class ScratchContinuousCategory extends ContinuousCategory { } } + /** + * Sets whether or not this category is selected. + * @param {boolean} isSelected True if this category is selected. + */ setSelected(isSelected) { super.setSelected(isSelected); // Prevent hardcoding the background color to grey. this.rowDiv_.style.backgroundColor = ""; } + + /** + * Returns whether or not this category's label in the flyout should display + * status indicators. + */ + shouldShowStatusButton() { + return this.showStatusButton; + } } -Blockly.registry.register( - Blockly.registry.Type.TOOLBOX_ITEM, - Blockly.ToolboxCategory.registrationName, - ScratchContinuousCategory, - true -); +/** Registers this toolbox category and unregisters the default one. */ +export function registerScratchContinuousCategory() { + Blockly.registry.unregister( + Blockly.registry.Type.TOOLBOX_ITEM, + ScratchContinuousCategory.registrationName + ); + Blockly.registry.register( + Blockly.registry.Type.TOOLBOX_ITEM, + ScratchContinuousCategory.registrationName, + ScratchContinuousCategory + ); +} diff --git a/src/scratch_continuous_toolbox.js b/src/scratch_continuous_toolbox.js index cfeceabfda..c613eea3ad 100644 --- a/src/scratch_continuous_toolbox.js +++ b/src/scratch_continuous_toolbox.js @@ -1,5 +1,12 @@ +/** + * @license + * Copyright 2024 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + import * as Blockly from "blockly/core"; import { ContinuousToolbox } from "@blockly/continuous-toolbox"; +import { ScratchContinuousCategory } from "./scratch_continuous_category.js"; export class ScratchContinuousToolbox extends ContinuousToolbox { postRenderCallbacks = []; @@ -8,6 +15,49 @@ export class ScratchContinuousToolbox extends ContinuousToolbox { // Intentionally a no-op, Scratch manually manages refreshing the toolbox via forceRerender(). } + /** + * Gets the contents that should be shown in the flyout. + * @returns {!Blockly.utils.toolbox.FlyoutItemInfoArray} Flyout contents. + */ + getInitialFlyoutContents_() { + // TODO(#211) Clean this up when the continuous toolbox plugin is updated. + /** @type {!Blockly.utils.toolbox.FlyoutItemInfoArray} */ + let contents = []; + for (const toolboxItem of this.getToolboxItems()) { + if (toolboxItem instanceof ScratchContinuousCategory) { + if (toolboxItem.shouldShowStatusButton()) { + contents.push({ + kind: "STATUS_INDICATOR_LABEL", + id: toolboxItem.getId(), + text: toolboxItem.getName(), + }); + } else { + // Create a label node to go at the top of the category + contents.push({ kind: "LABEL", text: toolboxItem.getName() }); + } + /** + * @type {string|Blockly.utils.toolbox.FlyoutItemInfoArray| + * Blockly.utils.toolbox.FlyoutItemInfo} + */ + let itemContents = toolboxItem.getContents(); + + // Handle custom categories (e.g. variables and functions) + if (typeof itemContents === "string") { + itemContents = + /** @type {!Blockly.utils.toolbox.DynamicCategoryInfo} */ ({ + custom: itemContents, + kind: "CATEGORY", + }); + } + contents = contents.concat(itemContents); + } + } + return contents; + } + + /** + * Forcibly rerenders the toolbox, preserving selection when possible. + */ forceRerender() { const selectedCategoryName = this.selectedItem_?.getName(); super.refreshSelection(); @@ -18,6 +68,10 @@ export class ScratchContinuousToolbox extends ContinuousToolbox { this.selectCategoryByName(selectedCategoryName); } + /** + * Runs the specified callback after the next rerender. + * @param {!Function} A callback to run whenever the toolbox next rerenders. + */ runAfterRerender(callback) { this.postRenderCallbacks.push(callback); } diff --git a/src/status_indicator_label.js b/src/status_indicator_label.js new file mode 100644 index 0000000000..b09dfb37e8 --- /dev/null +++ b/src/status_indicator_label.js @@ -0,0 +1,186 @@ +/** + * @license + * Visual Blocks Editor + * + * Copyright 2018 Google Inc. + * https://developers.google.com/blockly/ + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @fileoverview Class for a category header in the flyout for Scratch + * extensions which can display a textual label and a status button. + * @author ericr@media.mit.edu (Eric Rosenbaum) + */ + +import * as Blockly from "blockly/core"; + +/** + * Class for a category header in the flyout for Scratch extensions which can + * display a textual label and a status button. + */ +export class StatusIndicatorLabel extends Blockly.FlyoutButton { + /** + * The ID of the Scratch extension whose status is indicated by this label. + * @type {string} + */ + extensionId; + + /** + * DOM element that displays the status indicator dot. + * @type {!SVGImageElement} + */ + imageElement; + + /** + * Opaque data for mouse up listener used to unbind it in dispose(). + * @type {!Blockly.browserEvents.Data} + */ + mouseUpwrapper; + + /** + * Function to be invoked when the status indicator is clicked. + * @type {?Function} + */ + static statusButtonCallback; + + /** + * Creates a new StatusIndicatorLabel. + * + * @param {!Blockly.WorkspaceSvg} workspace The workspace in which to place + * this header. + * @param {!Blockly.WorkspaceSvg} targetWorkspace The flyout's target + * workspace. + * @param {!Element} xml The XML specifying the header. + */ + constructor(workspace, targetWorkspace, json, isFlyoutLabel) { + super(workspace, targetWorkspace, json, isFlyoutLabel); + /** + * @type {string} + */ + this.extensionId = json["id"]; + + const heightDelta = 40 - this.height; + this.height = 40; + const text = this.getSvgRoot().querySelector("text"); + const previousY = Number(text.getAttribute("y")); + + text.setAttribute("y", previousY + heightDelta / 2); + + const statusButtonWidth = 30; + const marginX = 20; + const marginY = 5; + const touchPadding = 16; + const flyoutWidth = targetWorkspace.getFlyout().getWidth(); + + const statusButtonX = workspace.RTL + ? marginX - flyoutWidth + statusButtonWidth + : (flyoutWidth - statusButtonWidth - marginX) / workspace.scale; + + /** @type {SVGElement} */ + this.imageElement = Blockly.utils.dom.createSvgElement( + "image", + { + class: "blocklyFlyoutButton", + height: statusButtonWidth + "px", + width: statusButtonWidth + "px", + x: statusButtonX + "px", + y: marginY + "px", + }, + this.getSvgRoot() + ); + const imageElementBackground = Blockly.utils.dom.createSvgElement( + "rect", + { + class: "blocklyTouchTargetBackground", + height: statusButtonWidth + 2 * touchPadding + "px", + width: statusButtonWidth + 2 * touchPadding + "px", + x: statusButtonX - touchPadding + "px", + y: marginY - touchPadding + "px", + }, + this.getSvgRoot() + ); + + this.refreshStatus(); + + this.mouseUpWrapper = Blockly.browserEvents.bind( + imageElementBackground, + "mouseup", + null, + () => { + StatusIndicatorLabel.statusButtonCallback?.call(this, this.extensionId); + } + ); + } + + /** + * Set the image on the status button using a status string. + */ + refreshStatus() { + var status = this.getExtensionState(this.extensionId); + var basePath = Blockly.getMainWorkspace().options.pathToMedia; + if (status == StatusButtonState.READY) { + this.setImageSrc(basePath + "status-ready.svg"); + } + if (status == StatusButtonState.NOT_READY) { + this.setImageSrc(basePath + "status-not-ready.svg"); + } + } + + /** + * Set the source URL of the image for the button. + * @param {?string} src New source. + * @package + */ + setImageSrc(src) { + if (src === null) { + // No change if null. + return; + } + this.imageSrc = src; + if (this.imageElement) { + this.imageElement.setAttributeNS( + "http://www.w3.org/1999/xlink", + "xlink:href", + this.imageSrc || "" + ); + } + } + + /** + * Gets the extension state. Overridden externally. + * @param {string} extensionId The ID of the extension in question. + * @return {Blockly.StatusButtonState} The state of the extension. + * @public + */ + getExtensionState(extensionId) { + return StatusButtonState.NOT_READY; + } + + /** + * Disposes of this status indicator label. + */ + dispose() { + Blockly.browserEvents.unbind(this.mouseUpWrapper); + super.dispose(); + } +} + +/** + * Set of available states for a status indicator. + */ +export const StatusButtonState = { + READY: "ready", + NOT_READY: "not ready", +}; diff --git a/src/status_indicator_label_flyout_inflater.js b/src/status_indicator_label_flyout_inflater.js new file mode 100644 index 0000000000..2ae48bc135 --- /dev/null +++ b/src/status_indicator_label_flyout_inflater.js @@ -0,0 +1,42 @@ +/** + * @license + * Copyright 2024 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + +import * as Blockly from "blockly/core"; +import { StatusIndicatorLabel } from "./status_indicator_label.js"; + +/** + * Flyout inflater responsible for creating status indicator labels. + */ +class StatusIndicatorLabelFlyoutInflater extends Blockly.LabelFlyoutInflater { + /** + * Creates a status indicator label on the flyout from the given state. + * @param {!Object} state JSON representation of a status indicator label. + * @param {!Blockly.WorkspaceSvg} flyoutWorkspace The workspace to create the + * label on. + * @returns {!StatusIndicatorLabel} The newly created status indicator label. + */ + load(state, flyoutWorkspace) { + const label = new StatusIndicatorLabel( + flyoutWorkspace, + flyoutWorkspace.targetWorkspace, + state, + true + ); + label.show(); + return label; + } +} + +/** + * Register the status indicator label flyout inflater. + */ +export function registerStatusIndicatorLabelFlyoutInflater() { + Blockly.registry.register( + Blockly.registry.Type.FLYOUT_INFLATER, + "status_indicator_label", + StatusIndicatorLabelFlyoutInflater + ); +} From cc4d9f9bc7520313145c4c0cb9978c4dfc6b3bfc Mon Sep 17 00:00:00 2001 From: Aaron Dodson Date: Mon, 14 Oct 2024 13:28:13 -0700 Subject: [PATCH 101/130] fix: fix alignment of "define" text baseline on custom blocks (#220) --- src/renderer/render_info.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/renderer/render_info.js b/src/renderer/render_info.js index 8e7a674b3b..896ed7f78f 100644 --- a/src/renderer/render_info.js +++ b/src/renderer/render_info.js @@ -78,7 +78,7 @@ export class RenderInfo extends Blockly.zelos.RenderInfo { getElemCenterline_(row, elem) { if (this.isBowlerHatBlock() && Blockly.blockRendering.Types.isField(elem)) { - return row.yPos + elem.height; + return row.yPos + row.height / 2; } else if ( this.block_.isScratchExtension && Blockly.blockRendering.Types.isField(elem) && From 1279c0aacefb8bbfaaa9786531a56c5a45cf24ee Mon Sep 17 00:00:00 2001 From: Aaron Dodson Date: Tue, 15 Oct 2024 13:55:58 -0700 Subject: [PATCH 102/130] fix: improve sizing and rendering of comments (#219) --- src/css.js | 3 +++ src/index.js | 4 ++++ src/scratch_comment_bubble.js | 1 + 3 files changed, 8 insertions(+) diff --git a/src/css.js b/src/css.js index 4fab79936e..589f876ec1 100644 --- a/src/css.js +++ b/src/css.js @@ -524,6 +524,9 @@ const styles = ` stroke-width: 3px; } + .blocklyCommentText::placeholder { + font-style: italic; + } .blocklyCommentTextarea { background-color: #fef49c; diff --git a/src/index.js b/src/index.js index d259ff00ee..8dbdba98d1 100644 --- a/src/index.js +++ b/src/index.js @@ -129,3 +129,7 @@ Blockly.ContextMenuRegistry.registry.unregister("blockDelete"); contextMenuItems.registerDeleteBlock(); Blockly.ContextMenuRegistry.registry.unregister("workspaceDelete"); contextMenuItems.registerDeleteAll(); +Blockly.comments.CommentView.defaultCommentSize = new Blockly.utils.Size( + 200, + 200 +); diff --git a/src/scratch_comment_bubble.js b/src/scratch_comment_bubble.js index 8a6b6d5c41..5c958416b7 100644 --- a/src/scratch_comment_bubble.js +++ b/src/scratch_comment_bubble.js @@ -17,6 +17,7 @@ export class ScratchCommentBubble extends Blockly.comments.CommentView { this.sourceBlock = sourceBlock; this.disposing = false; this.id = Blockly.utils.idGenerator.genUid(); + this.setPlaceholderText(Blockly.Msg.WORKSPACE_COMMENT_DEFAULT_TEXT); this.getSvgRoot().setAttribute( "style", `--colour-commentBorder: ${sourceBlock.getColourTertiary()};` From 88c700e40ea9ed05d3a237936ae44d2b62b1424f Mon Sep 17 00:00:00 2001 From: Aaron Dodson Date: Tue, 15 Oct 2024 13:56:19 -0700 Subject: [PATCH 103/130] fix: fix the color of procedure argument blocks (#216) --- src/renderer/path_object.js | 35 +++++++++++++++++++++++++++++++ src/renderer/renderer.js | 41 +++++++++++++++++++++++++++++++++++++ 2 files changed, 76 insertions(+) create mode 100644 src/renderer/path_object.js diff --git a/src/renderer/path_object.js b/src/renderer/path_object.js new file mode 100644 index 0000000000..db75409519 --- /dev/null +++ b/src/renderer/path_object.js @@ -0,0 +1,35 @@ +/** + * @license + * Copyright 2024 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + +import * as Blockly from "blockly/core"; + +/** + * An object that handles creating and setting each of the SVG elements + * used by the renderer. + */ +export class PathObject extends Blockly.zelos.PathObject { + /** + * Apply the stored colours to the block's path, taking into account whether + * the paths belong to a shadow block. + * + * @param {!Blockly.BlockSvg} block The source block. + */ + applyColour(block) { + super.applyColour(block); + + // These blocks are special in that, while they are technically shadow + // blocks when contained in a procedure definition/prototype, their parent + // (the sample procedure caller block embedded in the definition block) is + // also a shadow, so they need to use normal block colors in order to + // provide contrast with it. + if ( + block.type === "argument_reporter_string_number" || + block.type === "argument_reporter_boolean" + ) { + this.svgPath.setAttribute("fill", this.style.colourPrimary); + } + } +} diff --git a/src/renderer/renderer.js b/src/renderer/renderer.js index 88e7e24708..b26087fbda 100644 --- a/src/renderer/renderer.js +++ b/src/renderer/renderer.js @@ -8,20 +8,61 @@ import * as Blockly from "blockly/core"; import { Drawer } from "./drawer.js"; import { RenderInfo } from "./render_info.js"; import { ConstantProvider } from "./constants.js"; +import { PathObject } from "./path_object.js"; +/** + * Custom renderer for Scratch-style blocks. + */ export class ScratchRenderer extends Blockly.zelos.Renderer { + /** + * Create a new instance of the renderer's drawer. + * + * @param {!Blockly.BlockSvg} block The block to render. + * @param info {!Blockly.blockRendering.RenderInfo} An object containing all + * information needed to render this block. + * @returns {!Drawer} The drawer. + */ makeDrawer_(block, info) { return new Drawer(block, info); } + /** + * Create a new instance of the renderer's render info object. + * + * @param {!Blockly.BlockSvg} block The block to measure. + * @returns {!RenderInfo} The render info object. + */ makeRenderInfo_(block) { return new RenderInfo(this, block); } + /** + * Create a new instance of the renderer's constant provider. + * + * @returns {!ConstantProvider} The constant provider. + */ makeConstants_() { return new ConstantProvider(); } + /** + * Create a new instance of a renderer path object. + * + * @param {!SVGElement} root The root SVG element. + * @param {!Blockly.BlockStyle} style The style object to use for colouring. + * @returns {!PathObject} The renderer path object. + */ + makePathObject(root, style) { + return new PathObject(root, style, this.getConstants()); + } + + /** + * Determine whether or not to highlight a connection. + * + * @param {!Blockly.RenderedConnection} connection The connection to determine + * whether or not to highlight. + * @returns {boolean} True if we should highlight the connection. + */ shouldHighlightConnection(connection) { return ( connection.type === Blockly.ConnectionType.INPUT_VALUE && From 6a1c8a9e745d77f2aec49c3cae06dd6836bd58ef Mon Sep 17 00:00:00 2001 From: Aaron Dodson Date: Tue, 15 Oct 2024 13:56:34 -0700 Subject: [PATCH 104/130] fix: fix bug that could cause duplicated procedure argument blocks to create more duplicates on drag (#217) --- src/blocks/procedures.js | 8 +++---- src/index.js | 2 ++ src/scratch_block_paster.js | 46 +++++++++++++++++++++++++++++++++++++ 3 files changed, 51 insertions(+), 5 deletions(-) create mode 100644 src/scratch_block_paster.js diff --git a/src/blocks/procedures.js b/src/blocks/procedures.js index 20b65e217c..9fd759037b 100644 --- a/src/blocks/procedures.js +++ b/src/blocks/procedures.js @@ -37,9 +37,7 @@ class DuplicateOnDragDraggable { startDrag(e) { const data = this.block.toCopyData(); this.copy = Blockly.clipboard.paste(data, this.block.workspace); - this.baseStrat = new Blockly.dragging.BlockDragStrategy(this.copy); - this.copy.setDragStrategy(this.baseStrat); - this.baseStrat.startDrag(e); + this.copy.startDrag(e); } drag(e) { @@ -47,11 +45,11 @@ class DuplicateOnDragDraggable { .getGesture(e) .getCurrentDragger() .setDraggable(this.copy); - this.baseStrat.drag(e); + this.copy.drag(e); } endDrag(e) { - this.baseStrat?.endDrag(e); + this.copy?.endDrag(e); } revertDrag(e) { diff --git a/src/index.js b/src/index.js index 8dbdba98d1..4cab2f7794 100644 --- a/src/index.js +++ b/src/index.js @@ -61,6 +61,7 @@ import { registerFieldVariableGetter } from "./fields/field_variable_getter.js"; import { registerFieldVariable } from "./fields/field_variable.js"; import { registerFieldVerticalSeparator } from "./fields/field_vertical_separator.js"; import { registerRecyclableBlockFlyoutInflater } from "./recyclable_block_flyout_inflater.js"; +import { registerScratchBlockPaster } from "./scratch_block_paster.js"; import { registerStatusIndicatorLabelFlyoutInflater } from "./status_indicator_label_flyout_inflater.js"; import { registerScratchContinuousCategory } from "./scratch_continuous_category.js"; @@ -94,6 +95,7 @@ export function inject(container, options) { registerFieldVariable(); registerFieldVerticalSeparator(); registerRecyclableBlockFlyoutInflater(); + registerScratchBlockPaster(); registerStatusIndicatorLabelFlyoutInflater(); registerScratchContinuousCategory(); diff --git a/src/scratch_block_paster.js b/src/scratch_block_paster.js new file mode 100644 index 0000000000..7848950531 --- /dev/null +++ b/src/scratch_block_paster.js @@ -0,0 +1,46 @@ +/** + * @license + * Copyright 2024 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + +import * as Blockly from "blockly/core"; + +/** + * Class responsible for handling the pasting of copied blocks. + */ +class ScratchBlockPaster extends Blockly.clipboard.BlockPaster { + /** + * Deserializes the given block data onto the workspace. + * + * @param {!Blockly.clipboard.BlockCopyData} copyData The serialized block + * state to create a copy of on the workspace. + * @param {!Blockly.WorkspaceSvg} workspace The workspace to paste the block + * onto. + * @param {?Blockly.utils.Coordinate} coordinate The location to paste the + * block. + */ + paste(copyData, workspace, coordinate) { + const block = super.paste(copyData, workspace, coordinate); + if ( + block?.type === "argument_reporter_boolean" || + block?.type === "argument_reporter_string_number" + ) { + block.setDragStrategy(new Blockly.dragging.BlockDragStrategy(block)); + } + + return block; + } +} + +/** + * Unregisters the default block paster and registers ScratchBlockPaster in its + * place. + */ +export function registerScratchBlockPaster() { + Blockly.clipboard.registry.unregister(ScratchBlockPaster.TYPE); + Blockly.clipboard.registry.register( + ScratchBlockPaster.TYPE, + new ScratchBlockPaster() + ); +} From 75e6e6c51290e1961e9bc49d8e57364c580a53b4 Mon Sep 17 00:00:00 2001 From: Aaron Dodson Date: Tue, 15 Oct 2024 14:19:25 -0700 Subject: [PATCH 105/130] refactor: Add support for Typescript (#221) * chore: add Typescript dependencies * chore: add tsconfig.json * chore: update webpack.config.js for TS compatibility * chore: convert index.js to TS --- continuous-toolbox.d.ts | 1 + package-lock.json | 64 ++++++++++++++++++++++++++++++++++---- package.json | 2 ++ src/{index.js => index.ts} | 2 +- tsconfig.json | 10 ++++++ webpack.config.js | 36 ++++++++++++++------- 6 files changed, 96 insertions(+), 19 deletions(-) create mode 100644 continuous-toolbox.d.ts rename src/{index.js => index.ts} (98%) create mode 100644 tsconfig.json diff --git a/continuous-toolbox.d.ts b/continuous-toolbox.d.ts new file mode 100644 index 0000000000..9d8c17aa10 --- /dev/null +++ b/continuous-toolbox.d.ts @@ -0,0 +1 @@ +declare module "@blockly/continuous-toolbox"; diff --git a/package-lock.json b/package-lock.json index 67f0db052b..cf66bab374 100644 --- a/package-lock.json +++ b/package-lock.json @@ -18,6 +18,8 @@ "@commitlint/config-conventional": "^17.8.1", "eslint": "^4.19.1", "source-map-loader": "^4.0.1", + "ts-loader": "^9.5.1", + "typescript": "^5.6.3", "webpack": "^5.76.0", "webpack-cli": "^4.10.0", "webpack-dev-server": "^4.11.1" @@ -6222,6 +6224,35 @@ "node": ">=8" } }, + "node_modules/ts-loader": { + "version": "9.5.1", + "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-9.5.1.tgz", + "integrity": "sha512-rNH3sK9kGZcH9dYzC7CewQm4NtxJTjSEVRJ2DyBZR7f8/wcta+iV44UPCXc5+nzDzivKtlzV6c9P4e+oFhDLYg==", + "dev": true, + "dependencies": { + "chalk": "^4.1.0", + "enhanced-resolve": "^5.0.0", + "micromatch": "^4.0.0", + "semver": "^7.3.4", + "source-map": "^0.7.4" + }, + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "typescript": "*", + "webpack": "^5.0.0" + } + }, + "node_modules/ts-loader/node_modules/source-map": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", + "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, "node_modules/ts-node": { "version": "10.9.2", "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", @@ -6309,9 +6340,9 @@ "dev": true }, "node_modules/typescript": { - "version": "5.4.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz", - "integrity": "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==", + "version": "5.6.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.3.tgz", + "integrity": "sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==", "dev": true, "bin": { "tsc": "bin/tsc", @@ -11903,6 +11934,27 @@ "integrity": "sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==", "dev": true }, + "ts-loader": { + "version": "9.5.1", + "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-9.5.1.tgz", + "integrity": "sha512-rNH3sK9kGZcH9dYzC7CewQm4NtxJTjSEVRJ2DyBZR7f8/wcta+iV44UPCXc5+nzDzivKtlzV6c9P4e+oFhDLYg==", + "dev": true, + "requires": { + "chalk": "^4.1.0", + "enhanced-resolve": "^5.0.0", + "micromatch": "^4.0.0", + "semver": "^7.3.4", + "source-map": "^0.7.4" + }, + "dependencies": { + "source-map": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", + "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", + "dev": true + } + } + }, "ts-node": { "version": "10.9.2", "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", @@ -11956,9 +12008,9 @@ "dev": true }, "typescript": { - "version": "5.4.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz", - "integrity": "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==", + "version": "5.6.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.3.tgz", + "integrity": "sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==", "dev": true }, "undici-types": { diff --git a/package.json b/package.json index 7dc0d31c1e..cfc9274a1f 100644 --- a/package.json +++ b/package.json @@ -22,6 +22,8 @@ "@commitlint/config-conventional": "^17.8.1", "eslint": "^4.19.1", "source-map-loader": "^4.0.1", + "ts-loader": "^9.5.1", + "typescript": "^5.6.3", "webpack": "^5.76.0", "webpack-cli": "^4.10.0", "webpack-dev-server": "^4.11.1" diff --git a/src/index.js b/src/index.ts similarity index 98% rename from src/index.js rename to src/index.ts index 4cab2f7794..c914f058e4 100644 --- a/src/index.js +++ b/src/index.ts @@ -83,7 +83,7 @@ export { StatusButtonState, } from "./status_indicator_label.js"; -export function inject(container, options) { +export function inject(container: Element, options: Blockly.BlocklyOptions) { registerFieldAngle(); registerFieldColourSlider(); registerFieldDropdown(); diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000000..9035b59753 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,10 @@ +{ + "compilerOptions": { + "outDir": "./dist/", + "noImplicitAny": true, + "module": "es6", + "target": "es6", + "allowJs": true, + "moduleResolution": "node" + } +} diff --git a/webpack.config.js b/webpack.config.js index 147cc3122e..380acfaf2e 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -1,36 +1,48 @@ -const path = require('path'); +const path = require("path"); // Base config that applies to either development or production mode. const config = { - entry: './src/index.js', + entry: "./src/index.ts", output: { - library: 'ScratchBlocks', - libraryTarget: 'commonjs2', - path: path.resolve(__dirname, 'dist'), - filename: '[name].js' + library: "ScratchBlocks", + libraryTarget: "commonjs2", + path: path.resolve(__dirname, "dist"), + filename: "[name].js", + }, + resolve: { + extensions: [".ts", ".js"], + }, + module: { + rules: [ + { + test: /\.ts$/, + use: "ts-loader", + exclude: /node_modules/, + }, + ], }, // Enable webpack-dev-server to get hot refresh of the app. devServer: { - static: './build', + static: "./build", }, }; module.exports = (env, argv) => { - if (argv.mode === 'development') { + if (argv.mode === "development") { // Set the output path to the `build` directory // so we don't clobber production builds. - config.output.path = path.resolve(__dirname, 'build'); + config.output.path = path.resolve(__dirname, "build"); // Generate source maps for our code for easier debugging. // Not suitable for production builds. If you want source maps in // production, choose a different one from https://webpack.js.org/configuration/devtool - config.devtool = 'eval-cheap-module-source-map'; + config.devtool = "eval-cheap-module-source-map"; // Include the source maps for Blockly for easier debugging Blockly code. config.module.rules.push({ test: /(blockly\/.*\.js)$/, - use: [require.resolve('source-map-loader')], - enforce: 'pre', + use: [require.resolve("source-map-loader")], + enforce: "pre", }); // Ignore spurious warnings from source-map-loader From 6cb02d014c035b0af1d6c086a9cbf31e3ce77a11 Mon Sep 17 00:00:00 2001 From: Christopher Willis-Ford <7019101+cwillisf@users.noreply.github.com> Date: Fri, 18 Oct 2024 09:25:53 -0700 Subject: [PATCH 106/130] build: enable alpha and beta releases --- release.config.js | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/release.config.js b/release.config.js index 53cf4a450a..3398114626 100644 --- a/release.config.js +++ b/release.config.js @@ -5,6 +5,14 @@ module.exports = { { name: 'develop' // default channel + }, + { + name: 'alpha', + prerelease: true + }, + { + name: 'beta', + prerelease: true } ] }; From 87f8627842f3367108f14cf7a72fd77b8adc4eb1 Mon Sep 17 00:00:00 2001 From: Christopher Willis-Ford <7019101+cwillisf@users.noreply.github.com> Date: Fri, 18 Oct 2024 10:54:42 -0700 Subject: [PATCH 107/130] build: switch package info back to scratchfoundation --- package.json | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index cfc9274a1f..df8cacff10 100644 --- a/package.json +++ b/package.json @@ -4,13 +4,12 @@ "description": "Scratch Blocks is a library for building creative computing interfaces.", "author": "Massachusetts Institute of Technology", "license": "Apache-2.0", - "homepage": "https://github.com/gonfunko/scratch-blocks#readme", + "homepage": "https://github.com/scratchfoundation/scratch-blocks#readme", "repository": { "type": "git", - "url": "https://github.com/gonfunko/scratch-blocks.git" + "url": "https://github.com/scratchfoundation/scratch-blocks.git" }, "main": "./dist/main.js", - "private": true, "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "build": "webpack --mode production", From 04c3fc590f2f97ad0ea313e8c53a9ebbbf40c6ef Mon Sep 17 00:00:00 2001 From: Christopher Willis-Ford <7019101+cwillisf@users.noreply.github.com> Date: Fri, 18 Oct 2024 10:56:39 -0700 Subject: [PATCH 108/130] docs: track un-fork finishing tasks --- TODO.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 TODO.md diff --git a/TODO.md b/TODO.md new file mode 100644 index 0000000000..bd779f4398 --- /dev/null +++ b/TODO.md @@ -0,0 +1,16 @@ +# To-Do list for scratch-blocks un-fork + +Before this un-forked version of `scratch-blocks` is fully ready for release, we need to: + +- [ ] Hook up i18n / l10n +- [ ] Fix or remove Husky +- [ ] Set up CI & CD +- [ ] Wait for Blockly v12 release, then update Blockly dependencies accordingly + +Things we need to do before we consider this project "done" but could wait until after the initial release: + +- [ ] Decide what we want to do about tests, then do it +- [ ] Pick linting rules, apply them, and enforce them +- [ ] Make sure the gh-pages setup is doing what we want, or remove it +- [ ] ??? +- [ ] Remove this TODO file once it's empty :) From b78a3e5e9a144585afcf774d6165303d2f9df321 Mon Sep 17 00:00:00 2001 From: Christopher Willis-Ford <7019101+cwillisf@users.noreply.github.com> Date: Fri, 18 Oct 2024 11:18:44 -0700 Subject: [PATCH 109/130] chore(deps): upgrade Blockly plugins for Blockly v11 compatibility --- package-lock.json | 34 ++++++++++++++++++---------------- package.json | 4 ++-- 2 files changed, 20 insertions(+), 18 deletions(-) diff --git a/package-lock.json b/package-lock.json index cf66bab374..cc2e49f2c2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,8 +9,8 @@ "version": "2.0.0", "license": "Apache-2.0", "dependencies": { - "@blockly/continuous-toolbox": "^5.0.15", - "@blockly/field-colour": "^4.0.2", + "@blockly/continuous-toolbox": "^6.0.9", + "@blockly/field-colour": "^5.0.9", "blockly": "^11.0.0" }, "devDependencies": { @@ -125,25 +125,27 @@ } }, "node_modules/@blockly/continuous-toolbox": { - "version": "5.0.17", - "resolved": "https://registry.npmjs.org/@blockly/continuous-toolbox/-/continuous-toolbox-5.0.17.tgz", - "integrity": "sha512-3JCSimCo5KEWvvN4qC66vs2L/WtJIHepoIfkPNcbvMwjwYxJ484UPK2LKdlyI1842mgFfcYM3nTERjfa+Q4rXA==", + "version": "6.0.9", + "resolved": "https://registry.npmjs.org/@blockly/continuous-toolbox/-/continuous-toolbox-6.0.9.tgz", + "integrity": "sha512-b7WrMeZwxOJJ35aJggJ8ndBt8yUzm2i+HsfmQ78Ti7+xHHlJ2+DMLWORKoDc9HYVtYwiwZzjbJd3LucFm7mE2w==", + "license": "Apache-2.0", "engines": { "node": ">=8.17.0" }, "peerDependencies": { - "blockly": "^10.0.0" + "blockly": "^11.0.0" } }, "node_modules/@blockly/field-colour": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@blockly/field-colour/-/field-colour-4.0.2.tgz", - "integrity": "sha512-3gQufdo+40uFHbHn6Kyyw1ZVbgQffC7Ko8erVD8BcQwPgnusYIMgrqjn86nv2vgCH2kwH1ilg6xJfkDdqc/asw==", + "version": "5.0.9", + "resolved": "https://registry.npmjs.org/@blockly/field-colour/-/field-colour-5.0.9.tgz", + "integrity": "sha512-ebj4oGwrqkcGKTYjLDHLQYilZ1qfmiPIfi3QVv/ROfSut4VPEf4JEnTmc/AJJrKQgzygdbz02QLZ2DBlVkoWNg==", + "license": "Apache-2.0", "engines": { "node": ">=8.0.0" }, "peerDependencies": { - "blockly": "^10.4.3" + "blockly": "^11.0.0" } }, "node_modules/@commitlint/cli": { @@ -7134,15 +7136,15 @@ } }, "@blockly/continuous-toolbox": { - "version": "5.0.17", - "resolved": "https://registry.npmjs.org/@blockly/continuous-toolbox/-/continuous-toolbox-5.0.17.tgz", - "integrity": "sha512-3JCSimCo5KEWvvN4qC66vs2L/WtJIHepoIfkPNcbvMwjwYxJ484UPK2LKdlyI1842mgFfcYM3nTERjfa+Q4rXA==", + "version": "6.0.9", + "resolved": "https://registry.npmjs.org/@blockly/continuous-toolbox/-/continuous-toolbox-6.0.9.tgz", + "integrity": "sha512-b7WrMeZwxOJJ35aJggJ8ndBt8yUzm2i+HsfmQ78Ti7+xHHlJ2+DMLWORKoDc9HYVtYwiwZzjbJd3LucFm7mE2w==", "requires": {} }, "@blockly/field-colour": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@blockly/field-colour/-/field-colour-4.0.2.tgz", - "integrity": "sha512-3gQufdo+40uFHbHn6Kyyw1ZVbgQffC7Ko8erVD8BcQwPgnusYIMgrqjn86nv2vgCH2kwH1ilg6xJfkDdqc/asw==", + "version": "5.0.9", + "resolved": "https://registry.npmjs.org/@blockly/field-colour/-/field-colour-5.0.9.tgz", + "integrity": "sha512-ebj4oGwrqkcGKTYjLDHLQYilZ1qfmiPIfi3QVv/ROfSut4VPEf4JEnTmc/AJJrKQgzygdbz02QLZ2DBlVkoWNg==", "requires": {} }, "@commitlint/cli": { diff --git a/package.json b/package.json index df8cacff10..ca1b206a72 100644 --- a/package.json +++ b/package.json @@ -28,8 +28,8 @@ "webpack-dev-server": "^4.11.1" }, "dependencies": { - "@blockly/continuous-toolbox": "^5.0.15", - "@blockly/field-colour": "^4.0.2", + "@blockly/continuous-toolbox": "^6.0.9", + "@blockly/field-colour": "^5.0.9", "blockly": "^11.0.0" } } From bc59c8d9aa3c03bd767503c39acd6f9a5d5cb162 Mon Sep 17 00:00:00 2001 From: Christopher Willis-Ford <7019101+cwillisf@users.noreply.github.com> Date: Fri, 18 Oct 2024 11:29:19 -0700 Subject: [PATCH 110/130] chore: add husky hook for commitlint --- .husky/commit-msg | 3 --- TODO.md | 2 +- package-lock.json | 23 +++++++++++++++++++++++ package.json | 4 +++- 4 files changed, 27 insertions(+), 5 deletions(-) diff --git a/.husky/commit-msg b/.husky/commit-msg index 80416c7b17..70bd3dd23d 100755 --- a/.husky/commit-msg +++ b/.husky/commit-msg @@ -1,4 +1 @@ -#!/usr/bin/env sh -. "$(dirname -- "$0")/_/husky.sh" - npx --no-install commitlint --edit "$1" diff --git a/TODO.md b/TODO.md index bd779f4398..6c0a21d57f 100644 --- a/TODO.md +++ b/TODO.md @@ -3,7 +3,7 @@ Before this un-forked version of `scratch-blocks` is fully ready for release, we need to: - [ ] Hook up i18n / l10n -- [ ] Fix or remove Husky +- [x] Fix or remove Husky - [ ] Set up CI & CD - [ ] Wait for Blockly v12 release, then update Blockly dependencies accordingly diff --git a/package-lock.json b/package-lock.json index cc2e49f2c2..5e1307b2d4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -17,6 +17,7 @@ "@commitlint/cli": "^17.8.1", "@commitlint/config-conventional": "^17.8.1", "eslint": "^4.19.1", + "husky": "9.1.6", "source-map-loader": "^4.0.1", "ts-loader": "^9.5.1", "typescript": "^5.6.3", @@ -3544,6 +3545,22 @@ "node": ">=10.17.0" } }, + "node_modules/husky": { + "version": "9.1.6", + "resolved": "https://registry.npmjs.org/husky/-/husky-9.1.6.tgz", + "integrity": "sha512-sqbjZKK7kf44hfdE94EoX8MZNk0n7HeW37O4YrVGCF4wzgQjp+akPAkfUK5LZ6KuR/6sqeAVuXHji+RzQgOn5A==", + "dev": true, + "license": "MIT", + "bin": { + "husky": "bin.js" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/typicode" + } + }, "node_modules/iconv-lite": { "version": "0.6.3", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", @@ -9858,6 +9875,12 @@ "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", "dev": true }, + "husky": { + "version": "9.1.6", + "resolved": "https://registry.npmjs.org/husky/-/husky-9.1.6.tgz", + "integrity": "sha512-sqbjZKK7kf44hfdE94EoX8MZNk0n7HeW37O4YrVGCF4wzgQjp+akPAkfUK5LZ6KuR/6sqeAVuXHji+RzQgOn5A==", + "dev": true + }, "iconv-lite": { "version": "0.6.3", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", diff --git a/package.json b/package.json index ca1b206a72..878c0eb160 100644 --- a/package.json +++ b/package.json @@ -11,15 +11,17 @@ }, "main": "./dist/main.js", "scripts": { - "test": "echo \"Error: no test specified\" && exit 1", "build": "webpack --mode production", + "prepare": "husky || true", "start": "webpack serve --open --mode development", + "test": "echo \"Error: no test specified\" && exit 1", "test:lint": "eslint ." }, "devDependencies": { "@commitlint/cli": "^17.8.1", "@commitlint/config-conventional": "^17.8.1", "eslint": "^4.19.1", + "husky": "9.1.6", "source-map-loader": "^4.0.1", "ts-loader": "^9.5.1", "typescript": "^5.6.3", From 96b5e51d6b362f09c6ac27b3a447ec6005032f03 Mon Sep 17 00:00:00 2001 From: Christopher Willis-Ford <7019101+cwillisf@users.noreply.github.com> Date: Fri, 18 Oct 2024 11:31:17 -0700 Subject: [PATCH 111/130] chore: add commitizen config --- package.json | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/package.json b/package.json index 878c0eb160..260c546ba3 100644 --- a/package.json +++ b/package.json @@ -33,5 +33,10 @@ "@blockly/continuous-toolbox": "^6.0.9", "@blockly/field-colour": "^5.0.9", "blockly": "^11.0.0" + }, + "config": { + "commitizen": { + "path": "cz-conventional-changelog" + } } } From 768d025ab9029af6b42756e7352a490247fe1c5b Mon Sep 17 00:00:00 2001 From: Christopher Willis-Ford <7019101+cwillisf@users.noreply.github.com> Date: Fri, 18 Oct 2024 12:12:44 -0700 Subject: [PATCH 112/130] chore: re-add semantic-release and Scratch config for it --- package-lock.json | 31774 +++++++++++++++++++++++++++++++++----------- package.json | 2 + 2 files changed, 23799 insertions(+), 7977 deletions(-) diff --git a/package-lock.json b/package-lock.json index 5e1307b2d4..d52883236b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -18,6 +18,8 @@ "@commitlint/config-conventional": "^17.8.1", "eslint": "^4.19.1", "husky": "9.1.6", + "scratch-semantic-release-config": "1.0.16", + "semantic-release": "22.0.12", "source-map-loader": "^4.0.1", "ts-loader": "^9.5.1", "typescript": "^5.6.3", @@ -149,6 +151,16 @@ "blockly": "^11.0.0" } }, + "node_modules/@colors/colors": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", + "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", + "dev": true, + "optional": true, + "engines": { + "node": ">=0.1.90" + } + }, "node_modules/@commitlint/cli": { "version": "17.8.1", "resolved": "https://registry.npmjs.org/@commitlint/cli/-/cli-17.8.1.tgz", @@ -579,2389 +591,2361 @@ "integrity": "sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A==", "dev": true }, - "node_modules/@tsconfig/node10": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz", - "integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==", - "dev": true - }, - "node_modules/@tsconfig/node12": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", - "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", - "dev": true - }, - "node_modules/@tsconfig/node14": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", - "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", - "dev": true + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } }, - "node_modules/@tsconfig/node16": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", - "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", - "dev": true + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "engines": { + "node": ">= 8" + } }, - "node_modules/@types/body-parser": { - "version": "1.19.5", - "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz", - "integrity": "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==", + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", "dev": true, "dependencies": { - "@types/connect": "*", - "@types/node": "*" + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" } }, - "node_modules/@types/bonjour": { - "version": "3.5.13", - "resolved": "https://registry.npmjs.org/@types/bonjour/-/bonjour-3.5.13.tgz", - "integrity": "sha512-z9fJ5Im06zvUL548KvYNecEVlA7cVDkGUi6kZusb04mpyEFKCIZJvloCcmpmLaIahDpOQGHaHmG6imtPMmPXGQ==", + "node_modules/@octokit/auth-token": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-4.0.0.tgz", + "integrity": "sha512-tY/msAuJo6ARbK6SPIxZrPBms3xPbfwBrulZe0Wtr/DIY9lje2HeV1uoebShn6mx7SjCHif6EjMvoREj+gZ+SA==", "dev": true, - "dependencies": { - "@types/node": "*" + "engines": { + "node": ">= 18" } }, - "node_modules/@types/connect": { - "version": "3.4.38", - "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", - "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", + "node_modules/@octokit/core": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@octokit/core/-/core-5.2.0.tgz", + "integrity": "sha512-1LFfa/qnMQvEOAdzlQymH0ulepxbxnCYAKJZfMci/5XJyIHWgEYnDmgnKakbTh7CH2tFQ5O60oYDvns4i9RAIg==", "dev": true, "dependencies": { - "@types/node": "*" + "@octokit/auth-token": "^4.0.0", + "@octokit/graphql": "^7.1.0", + "@octokit/request": "^8.3.1", + "@octokit/request-error": "^5.1.0", + "@octokit/types": "^13.0.0", + "before-after-hook": "^2.2.0", + "universal-user-agent": "^6.0.0" + }, + "engines": { + "node": ">= 18" } }, - "node_modules/@types/connect-history-api-fallback": { - "version": "1.5.4", - "resolved": "https://registry.npmjs.org/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.5.4.tgz", - "integrity": "sha512-n6Cr2xS1h4uAulPRdlw6Jl6s1oG8KrVilPN2yUITEs+K48EzMJJ3W1xy8K5eWuFvjp3R74AOIGSmp2UfBJ8HFw==", + "node_modules/@octokit/endpoint": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-9.0.5.tgz", + "integrity": "sha512-ekqR4/+PCLkEBF6qgj8WqJfvDq65RH85OAgrtnVp1mSxaXF03u2xW/hUdweGS5654IlC0wkNYC18Z50tSYTAFw==", "dev": true, "dependencies": { - "@types/express-serve-static-core": "*", - "@types/node": "*" + "@octokit/types": "^13.1.0", + "universal-user-agent": "^6.0.0" + }, + "engines": { + "node": ">= 18" } }, - "node_modules/@types/eslint": { - "version": "8.56.0", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.0.tgz", - "integrity": "sha512-FlsN0p4FhuYRjIxpbdXovvHQhtlG05O1GG/RNWvdAxTboR438IOTwmrY/vLA+Xfgg06BTkP045M3vpFwTMv1dg==", + "node_modules/@octokit/graphql": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-7.1.0.tgz", + "integrity": "sha512-r+oZUH7aMFui1ypZnAvZmn0KSqAUgE1/tUXIWaqUCa1758ts/Jio84GZuzsvUkme98kv0WFY8//n0J1Z+vsIsQ==", "dev": true, "dependencies": { - "@types/estree": "*", - "@types/json-schema": "*" + "@octokit/request": "^8.3.0", + "@octokit/types": "^13.0.0", + "universal-user-agent": "^6.0.0" + }, + "engines": { + "node": ">= 18" } }, - "node_modules/@types/eslint-scope": { - "version": "3.7.7", - "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz", - "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==", + "node_modules/@octokit/openapi-types": { + "version": "22.2.0", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-22.2.0.tgz", + "integrity": "sha512-QBhVjcUa9W7Wwhm6DBFu6ZZ+1/t/oYxqc2tp81Pi41YNuJinbFRx8B133qVOrAaBbF7D/m0Et6f9/pZt9Rc+tg==", + "dev": true + }, + "node_modules/@octokit/plugin-paginate-rest": { + "version": "9.2.1", + "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-9.2.1.tgz", + "integrity": "sha512-wfGhE/TAkXZRLjksFXuDZdmGnJQHvtU/joFQdweXUgzo1XwvBCD4o4+75NtFfjfLK5IwLf9vHTfSiU3sLRYpRw==", "dev": true, "dependencies": { - "@types/eslint": "*", - "@types/estree": "*" + "@octokit/types": "^12.6.0" + }, + "engines": { + "node": ">= 18" + }, + "peerDependencies": { + "@octokit/core": "5" } }, - "node_modules/@types/estree": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", - "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", + "node_modules/@octokit/plugin-paginate-rest/node_modules/@octokit/openapi-types": { + "version": "20.0.0", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-20.0.0.tgz", + "integrity": "sha512-EtqRBEjp1dL/15V7WiX5LJMIxxkdiGJnabzYx5Apx4FkQIFgAfKumXeYAqqJCj1s+BMX4cPFIFC4OLCR6stlnA==", "dev": true }, - "node_modules/@types/express": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz", - "integrity": "sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==", + "node_modules/@octokit/plugin-paginate-rest/node_modules/@octokit/types": { + "version": "12.6.0", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-12.6.0.tgz", + "integrity": "sha512-1rhSOfRa6H9w4YwK0yrf5faDaDTb+yLyBUKOCV4xtCDB5VmIPqd/v9yr9o6SAzOAlRxMiRiCic6JVM1/kunVkw==", "dev": true, "dependencies": { - "@types/body-parser": "*", - "@types/express-serve-static-core": "^4.17.33", - "@types/qs": "*", - "@types/serve-static": "*" + "@octokit/openapi-types": "^20.0.0" } }, - "node_modules/@types/express-serve-static-core": { - "version": "4.17.41", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.41.tgz", - "integrity": "sha512-OaJ7XLaelTgrvlZD8/aa0vvvxZdUmlCn6MtWeB7TkiKW70BQLc9XEPpDLPdbo52ZhXUCrznlWdCHWxJWtdyajA==", + "node_modules/@octokit/plugin-retry": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/@octokit/plugin-retry/-/plugin-retry-6.0.1.tgz", + "integrity": "sha512-SKs+Tz9oj0g4p28qkZwl/topGcb0k0qPNX/i7vBKmDsjoeqnVfFUquqrE/O9oJY7+oLzdCtkiWSXLpLjvl6uog==", "dev": true, "dependencies": { - "@types/node": "*", - "@types/qs": "*", - "@types/range-parser": "*", - "@types/send": "*" + "@octokit/request-error": "^5.0.0", + "@octokit/types": "^12.0.0", + "bottleneck": "^2.15.3" + }, + "engines": { + "node": ">= 18" + }, + "peerDependencies": { + "@octokit/core": ">=5" } }, - "node_modules/@types/http-errors": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz", - "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==", + "node_modules/@octokit/plugin-retry/node_modules/@octokit/openapi-types": { + "version": "20.0.0", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-20.0.0.tgz", + "integrity": "sha512-EtqRBEjp1dL/15V7WiX5LJMIxxkdiGJnabzYx5Apx4FkQIFgAfKumXeYAqqJCj1s+BMX4cPFIFC4OLCR6stlnA==", "dev": true }, - "node_modules/@types/http-proxy": { - "version": "1.17.14", - "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.14.tgz", - "integrity": "sha512-SSrD0c1OQzlFX7pGu1eXxSEjemej64aaNPRhhVYUGqXh0BtldAAx37MG8btcumvpgKyZp1F5Gn3JkktdxiFv6w==", + "node_modules/@octokit/plugin-retry/node_modules/@octokit/types": { + "version": "12.6.0", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-12.6.0.tgz", + "integrity": "sha512-1rhSOfRa6H9w4YwK0yrf5faDaDTb+yLyBUKOCV4xtCDB5VmIPqd/v9yr9o6SAzOAlRxMiRiCic6JVM1/kunVkw==", "dev": true, "dependencies": { - "@types/node": "*" + "@octokit/openapi-types": "^20.0.0" } }, - "node_modules/@types/json-schema": { - "version": "7.0.15", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", - "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", - "dev": true - }, - "node_modules/@types/mime": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", - "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==", - "dev": true + "node_modules/@octokit/plugin-throttling": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/@octokit/plugin-throttling/-/plugin-throttling-8.2.0.tgz", + "integrity": "sha512-nOpWtLayKFpgqmgD0y3GqXafMFuKcA4tRPZIfu7BArd2lEZeb1988nhWhwx4aZWmjDmUfdgVf7W+Tt4AmvRmMQ==", + "dev": true, + "dependencies": { + "@octokit/types": "^12.2.0", + "bottleneck": "^2.15.3" + }, + "engines": { + "node": ">= 18" + }, + "peerDependencies": { + "@octokit/core": "^5.0.0" + } }, - "node_modules/@types/minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-hov8bUuiLiyFPGyFPE1lwWhmzYbirOXQNNo40+y3zow8aFVTeyn3VWL0VFFfdNddA8S4Vf0Tc062rzyNr7Paag==", + "node_modules/@octokit/plugin-throttling/node_modules/@octokit/openapi-types": { + "version": "20.0.0", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-20.0.0.tgz", + "integrity": "sha512-EtqRBEjp1dL/15V7WiX5LJMIxxkdiGJnabzYx5Apx4FkQIFgAfKumXeYAqqJCj1s+BMX4cPFIFC4OLCR6stlnA==", "dev": true }, - "node_modules/@types/node": { - "version": "20.10.5", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.10.5.tgz", - "integrity": "sha512-nNPsNE65wjMxEKI93yOP+NPGGBJz/PoN3kZsVLee0XMiJolxSekEVD8wRwBUBqkwc7UWop0edW50yrCQW4CyRw==", + "node_modules/@octokit/plugin-throttling/node_modules/@octokit/types": { + "version": "12.6.0", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-12.6.0.tgz", + "integrity": "sha512-1rhSOfRa6H9w4YwK0yrf5faDaDTb+yLyBUKOCV4xtCDB5VmIPqd/v9yr9o6SAzOAlRxMiRiCic6JVM1/kunVkw==", "dev": true, "dependencies": { - "undici-types": "~5.26.4" + "@octokit/openapi-types": "^20.0.0" } }, - "node_modules/@types/node-forge": { - "version": "1.3.10", - "resolved": "https://registry.npmjs.org/@types/node-forge/-/node-forge-1.3.10.tgz", - "integrity": "sha512-y6PJDYN4xYBxwd22l+OVH35N+1fCYWiuC3aiP2SlXVE6Lo7SS+rSx9r89hLxrP4pn6n1lBGhHJ12pj3F3Mpttw==", + "node_modules/@octokit/request": { + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/@octokit/request/-/request-8.4.0.tgz", + "integrity": "sha512-9Bb014e+m2TgBeEJGEbdplMVWwPmL1FPtggHQRkV+WVsMggPtEkLKPlcVYm/o8xKLkpJ7B+6N8WfQMtDLX2Dpw==", "dev": true, "dependencies": { - "@types/node": "*" + "@octokit/endpoint": "^9.0.1", + "@octokit/request-error": "^5.1.0", + "@octokit/types": "^13.1.0", + "universal-user-agent": "^6.0.0" + }, + "engines": { + "node": ">= 18" } }, - "node_modules/@types/normalize-package-data": { - "version": "2.4.4", - "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.4.tgz", - "integrity": "sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==", - "dev": true + "node_modules/@octokit/request-error": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-5.1.0.tgz", + "integrity": "sha512-GETXfE05J0+7H2STzekpKObFe765O5dlAKUTLNGeH+x47z7JjXHfsHKo5z21D/o/IOZTUEI6nyWyR+bZVP/n5Q==", + "dev": true, + "dependencies": { + "@octokit/types": "^13.1.0", + "deprecation": "^2.0.0", + "once": "^1.4.0" + }, + "engines": { + "node": ">= 18" + } }, - "node_modules/@types/qs": { - "version": "6.9.10", - "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.10.tgz", - "integrity": "sha512-3Gnx08Ns1sEoCrWssEgTSJs/rsT2vhGP+Ja9cnnk9k4ALxinORlQneLXFeFKOTJMOeZUFD1s7w+w2AphTpvzZw==", + "node_modules/@octokit/tsconfig": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@octokit/tsconfig/-/tsconfig-1.0.2.tgz", + "integrity": "sha512-I0vDR0rdtP8p2lGMzvsJzbhdOWy405HcGovrspJ8RRibHnyRgggUSNO5AIox5LmqiwmatHKYsvj6VGFHkqS7lA==", "dev": true }, - "node_modules/@types/range-parser": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", - "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==", - "dev": true + "node_modules/@octokit/types": { + "version": "13.6.1", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.6.1.tgz", + "integrity": "sha512-PHZE9Z+kWXb23Ndik8MKPirBPziOc0D2/3KH1P+6jK5nGWe96kadZuE4jev2/Jq7FvIfTlT2Ltg8Fv2x1v0a5g==", + "dev": true, + "dependencies": { + "@octokit/openapi-types": "^22.2.0" + } }, - "node_modules/@types/retry": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.0.tgz", - "integrity": "sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==", - "dev": true + "node_modules/@pnpm/config.env-replace": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@pnpm/config.env-replace/-/config.env-replace-1.1.0.tgz", + "integrity": "sha512-htyl8TWnKL7K/ESFa1oW2UB5lVDxuF5DpM7tBi6Hu2LNL3mWkIzNLG6N4zoCUP1lCKNxWy/3iu8mS8MvToGd6w==", + "dev": true, + "engines": { + "node": ">=12.22.0" + } }, - "node_modules/@types/send": { - "version": "0.17.4", - "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz", - "integrity": "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==", + "node_modules/@pnpm/network.ca-file": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@pnpm/network.ca-file/-/network.ca-file-1.0.2.tgz", + "integrity": "sha512-YcPQ8a0jwYU9bTdJDpXjMi7Brhkr1mXsXrUJvjqM2mQDgkRiz8jFaQGOdaLxgjtUfQgZhKy/O3cG/YwmgKaxLA==", "dev": true, "dependencies": { - "@types/mime": "^1", - "@types/node": "*" + "graceful-fs": "4.2.10" + }, + "engines": { + "node": ">=12.22.0" } }, - "node_modules/@types/serve-index": { - "version": "1.9.4", - "resolved": "https://registry.npmjs.org/@types/serve-index/-/serve-index-1.9.4.tgz", - "integrity": "sha512-qLpGZ/c2fhSs5gnYsQxtDEq3Oy8SXPClIXkW5ghvAvsNuVSA8k+gCONcUCS/UjLEYvYps+e8uBtfgXgvhwfNug==", + "node_modules/@pnpm/network.ca-file/node_modules/graceful-fs": { + "version": "4.2.10", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", + "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", + "dev": true + }, + "node_modules/@pnpm/npm-conf": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/@pnpm/npm-conf/-/npm-conf-2.3.1.tgz", + "integrity": "sha512-c83qWb22rNRuB0UaVCI0uRPNRr8Z0FWnEIvT47jiHAmOIUHbBOg5XvV7pM5x+rKn9HRpjxquDbXYSXr3fAKFcw==", "dev": true, "dependencies": { - "@types/express": "*" + "@pnpm/config.env-replace": "^1.1.0", + "@pnpm/network.ca-file": "^1.0.1", + "config-chain": "^1.1.11" + }, + "engines": { + "node": ">=12" } }, - "node_modules/@types/serve-static": { - "version": "1.15.5", - "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.5.tgz", - "integrity": "sha512-PDRk21MnK70hja/YF8AHfC7yIsiQHn1rcXx7ijCFBX/k+XQJhQT/gw3xekXKJvx+5SXaMMS8oqQy09Mzvz2TuQ==", + "node_modules/@semantic-release/changelog": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/@semantic-release/changelog/-/changelog-6.0.3.tgz", + "integrity": "sha512-dZuR5qByyfe3Y03TpmCvAxCyTnp7r5XwtHRf/8vD9EAn4ZWbavUX8adMtXYzE86EVh0gyLA7lm5yW4IV30XUag==", "dev": true, "dependencies": { - "@types/http-errors": "*", - "@types/mime": "*", - "@types/node": "*" + "@semantic-release/error": "^3.0.0", + "aggregate-error": "^3.0.0", + "fs-extra": "^11.0.0", + "lodash": "^4.17.4" + }, + "engines": { + "node": ">=14.17" + }, + "peerDependencies": { + "semantic-release": ">=18.0.0" } }, - "node_modules/@types/sockjs": { - "version": "0.3.36", - "resolved": "https://registry.npmjs.org/@types/sockjs/-/sockjs-0.3.36.tgz", - "integrity": "sha512-MK9V6NzAS1+Ud7JV9lJLFqW85VbC9dq3LmwZCuBe4wBDgKC0Kj/jd8Xl+nSviU+Qc3+m7umHHyHg//2KSa0a0Q==", + "node_modules/@semantic-release/changelog/node_modules/@semantic-release/error": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@semantic-release/error/-/error-3.0.0.tgz", + "integrity": "sha512-5hiM4Un+tpl4cKw3lV4UgzJj+SmfNIDCLLw0TepzQxz9ZGV5ixnqkzIVF+3tp0ZHgcMKE+VNGHJjEeyFG2dcSw==", "dev": true, - "dependencies": { - "@types/node": "*" + "engines": { + "node": ">=14.17" } }, - "node_modules/@types/ws": { - "version": "8.5.10", - "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.10.tgz", - "integrity": "sha512-vmQSUcfalpIq0R9q7uTo2lXs6eGIpt9wtnLdMv9LVpIjCA/+ufZRozlVoVelIYixx1ugCBKDhn89vnsEGOCx9A==", + "node_modules/@semantic-release/changelog/node_modules/aggregate-error": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", + "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", "dev": true, "dependencies": { - "@types/node": "*" + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + }, + "engines": { + "node": ">=8" } }, - "node_modules/@webassemblyjs/ast": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.6.tgz", - "integrity": "sha512-IN1xI7PwOvLPgjcf180gC1bqn3q/QaOCwYUahIOhbYUu8KA/3tw2RT/T0Gidi1l7Hhj5D/INhJxiICObqpMu4Q==", + "node_modules/@semantic-release/changelog/node_modules/clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", "dev": true, - "dependencies": { - "@webassemblyjs/helper-numbers": "1.11.6", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6" + "engines": { + "node": ">=6" } }, - "node_modules/@webassemblyjs/floating-point-hex-parser": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz", - "integrity": "sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==", - "dev": true - }, - "node_modules/@webassemblyjs/helper-api-error": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz", - "integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==", - "dev": true - }, - "node_modules/@webassemblyjs/helper-buffer": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.6.tgz", - "integrity": "sha512-z3nFzdcp1mb8nEOFFk8DrYLpHvhKC3grJD2ardfKOzmbmJvEf/tPIqCY+sNcwZIY8ZD7IkB2l7/pqhUhqm7hLA==", - "dev": true - }, - "node_modules/@webassemblyjs/helper-numbers": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz", - "integrity": "sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==", + "node_modules/@semantic-release/commit-analyzer": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/@semantic-release/commit-analyzer/-/commit-analyzer-11.1.0.tgz", + "integrity": "sha512-cXNTbv3nXR2hlzHjAMgbuiQVtvWHTlwwISt60B+4NZv01y/QRY7p2HcJm8Eh2StzcTJoNnflvKjHH/cjFS7d5g==", "dev": true, "dependencies": { - "@webassemblyjs/floating-point-hex-parser": "1.11.6", - "@webassemblyjs/helper-api-error": "1.11.6", - "@xtuc/long": "4.2.2" + "conventional-changelog-angular": "^7.0.0", + "conventional-commits-filter": "^4.0.0", + "conventional-commits-parser": "^5.0.0", + "debug": "^4.0.0", + "import-from-esm": "^1.0.3", + "lodash-es": "^4.17.21", + "micromatch": "^4.0.2" + }, + "engines": { + "node": "^18.17 || >=20.6.1" + }, + "peerDependencies": { + "semantic-release": ">=20.1.0" } }, - "node_modules/@webassemblyjs/helper-wasm-bytecode": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz", - "integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==", - "dev": true - }, - "node_modules/@webassemblyjs/helper-wasm-section": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.6.tgz", - "integrity": "sha512-LPpZbSOwTpEC2cgn4hTydySy1Ke+XEu+ETXuoyvuyezHO3Kjdu90KK95Sh9xTbmjrCsUwvWwCOQQNta37VrS9g==", + "node_modules/@semantic-release/commit-analyzer/node_modules/conventional-changelog-angular": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-7.0.0.tgz", + "integrity": "sha512-ROjNchA9LgfNMTTFSIWPzebCwOGFdgkEq45EnvvrmSLvCtAw0HSmrCs7/ty+wAeYUZyNay0YMUNYFTRL72PkBQ==", "dev": true, "dependencies": { - "@webassemblyjs/ast": "1.11.6", - "@webassemblyjs/helper-buffer": "1.11.6", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/wasm-gen": "1.11.6" + "compare-func": "^2.0.0" + }, + "engines": { + "node": ">=16" } }, - "node_modules/@webassemblyjs/ieee754": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz", - "integrity": "sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==", + "node_modules/@semantic-release/commit-analyzer/node_modules/conventional-commits-parser": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-5.0.0.tgz", + "integrity": "sha512-ZPMl0ZJbw74iS9LuX9YIAiW8pfM5p3yh2o/NbXHbkFuZzY5jvdi5jFycEOkmBW5H5I7nA+D6f3UcsCLP2vvSEA==", "dev": true, "dependencies": { - "@xtuc/ieee754": "^1.2.0" + "is-text-path": "^2.0.0", + "JSONStream": "^1.3.5", + "meow": "^12.0.1", + "split2": "^4.0.0" + }, + "bin": { + "conventional-commits-parser": "cli.mjs" + }, + "engines": { + "node": ">=16" } }, - "node_modules/@webassemblyjs/leb128": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.6.tgz", - "integrity": "sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==", + "node_modules/@semantic-release/commit-analyzer/node_modules/is-text-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-text-path/-/is-text-path-2.0.0.tgz", + "integrity": "sha512-+oDTluR6WEjdXEJMnC2z6A4FRwFoYuvShVVEGsS7ewc0UTi2QtAKMDJuL4BDEVt+5T7MjFo12RP8ghOM75oKJw==", "dev": true, "dependencies": { - "@xtuc/long": "4.2.2" + "text-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" } }, - "node_modules/@webassemblyjs/utf8": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.6.tgz", - "integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==", - "dev": true - }, - "node_modules/@webassemblyjs/wasm-edit": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.6.tgz", - "integrity": "sha512-Ybn2I6fnfIGuCR+Faaz7YcvtBKxvoLV3Lebn1tM4o/IAJzmi9AWYIPWpyBfU8cC+JxAO57bk4+zdsTjJR+VTOw==", + "node_modules/@semantic-release/commit-analyzer/node_modules/meow": { + "version": "12.1.1", + "resolved": "https://registry.npmjs.org/meow/-/meow-12.1.1.tgz", + "integrity": "sha512-BhXM0Au22RwUneMPwSCnyhTOizdWoIEPU9sp0Aqa1PnDMR5Wv2FGXYDjuzJEIX+Eo2Rb8xuYe5jrnm5QowQFkw==", "dev": true, - "dependencies": { - "@webassemblyjs/ast": "1.11.6", - "@webassemblyjs/helper-buffer": "1.11.6", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/helper-wasm-section": "1.11.6", - "@webassemblyjs/wasm-gen": "1.11.6", - "@webassemblyjs/wasm-opt": "1.11.6", - "@webassemblyjs/wasm-parser": "1.11.6", - "@webassemblyjs/wast-printer": "1.11.6" + "engines": { + "node": ">=16.10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@webassemblyjs/wasm-gen": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.6.tgz", - "integrity": "sha512-3XOqkZP/y6B4F0PBAXvI1/bky7GryoogUtfwExeP/v7Nzwo1QLcq5oQmpKlftZLbT+ERUOAZVQjuNVak6UXjPA==", + "node_modules/@semantic-release/commit-analyzer/node_modules/split2": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", + "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==", "dev": true, - "dependencies": { - "@webassemblyjs/ast": "1.11.6", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/ieee754": "1.11.6", - "@webassemblyjs/leb128": "1.11.6", - "@webassemblyjs/utf8": "1.11.6" + "engines": { + "node": ">= 10.x" } }, - "node_modules/@webassemblyjs/wasm-opt": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.6.tgz", - "integrity": "sha512-cOrKuLRE7PCe6AsOVl7WasYf3wbSo4CeOk6PkrjS7g57MFfVUF9u6ysQBBODX0LdgSvQqRiGz3CXvIDKcPNy4g==", + "node_modules/@semantic-release/commit-analyzer/node_modules/text-extensions": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/text-extensions/-/text-extensions-2.4.0.tgz", + "integrity": "sha512-te/NtwBwfiNRLf9Ijqx3T0nlqZiQ2XrrtBvu+cLL8ZRrGkO0NHTug8MYFKyoSrv/sHTaSKfilUkizV6XhxMJ3g==", "dev": true, - "dependencies": { - "@webassemblyjs/ast": "1.11.6", - "@webassemblyjs/helper-buffer": "1.11.6", - "@webassemblyjs/wasm-gen": "1.11.6", - "@webassemblyjs/wasm-parser": "1.11.6" + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@webassemblyjs/wasm-parser": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.6.tgz", - "integrity": "sha512-6ZwPeGzMJM3Dqp3hCsLgESxBGtT/OeCvCZ4TA1JUPYgmhAx38tTPR9JaKy0S5H3evQpO/h2uWs2j6Yc/fjkpTQ==", + "node_modules/@semantic-release/error": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@semantic-release/error/-/error-4.0.0.tgz", + "integrity": "sha512-mgdxrHTLOjOddRVYIYDo0fR3/v61GNN1YGkfbrjuIKg/uMgCd+Qzo3UAXJ+woLQQpos4pl5Esuw5A7AoNlzjUQ==", "dev": true, - "dependencies": { - "@webassemblyjs/ast": "1.11.6", - "@webassemblyjs/helper-api-error": "1.11.6", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/ieee754": "1.11.6", - "@webassemblyjs/leb128": "1.11.6", - "@webassemblyjs/utf8": "1.11.6" + "engines": { + "node": ">=18" } }, - "node_modules/@webassemblyjs/wast-printer": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.6.tgz", - "integrity": "sha512-JM7AhRcE+yW2GWYaKeHL5vt4xqee5N2WcezptmgyhNS+ScggqcT1OtXykhAb13Sn5Yas0j2uv9tHgrjwvzAP4A==", + "node_modules/@semantic-release/git": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/@semantic-release/git/-/git-10.0.1.tgz", + "integrity": "sha512-eWrx5KguUcU2wUPaO6sfvZI0wPafUKAMNC18aXY4EnNcrZL86dEmpNVnC9uMpGZkmZJ9EfCVJBQx4pV4EMGT1w==", "dev": true, "dependencies": { - "@webassemblyjs/ast": "1.11.6", - "@xtuc/long": "4.2.2" + "@semantic-release/error": "^3.0.0", + "aggregate-error": "^3.0.0", + "debug": "^4.0.0", + "dir-glob": "^3.0.0", + "execa": "^5.0.0", + "lodash": "^4.17.4", + "micromatch": "^4.0.0", + "p-reduce": "^2.0.0" + }, + "engines": { + "node": ">=14.17" + }, + "peerDependencies": { + "semantic-release": ">=18.0.0" } }, - "node_modules/@webpack-cli/configtest": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-1.2.0.tgz", - "integrity": "sha512-4FB8Tj6xyVkyqjj1OaTqCjXYULB9FMkqQ8yGrZjRDrYh0nOE+7Lhs45WioWQQMV+ceFlE368Ukhe6xdvJM9Egg==", + "node_modules/@semantic-release/git/node_modules/@semantic-release/error": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@semantic-release/error/-/error-3.0.0.tgz", + "integrity": "sha512-5hiM4Un+tpl4cKw3lV4UgzJj+SmfNIDCLLw0TepzQxz9ZGV5ixnqkzIVF+3tp0ZHgcMKE+VNGHJjEeyFG2dcSw==", "dev": true, - "peerDependencies": { - "webpack": "4.x.x || 5.x.x", - "webpack-cli": "4.x.x" + "engines": { + "node": ">=14.17" } }, - "node_modules/@webpack-cli/info": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-1.5.0.tgz", - "integrity": "sha512-e8tSXZpw2hPl2uMJY6fsMswaok5FdlGNRTktvFk2sD8RjH0hE2+XistawJx1vmKteh4NmGmNUrp+Tb2w+udPcQ==", + "node_modules/@semantic-release/git/node_modules/aggregate-error": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", + "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", "dev": true, "dependencies": { - "envinfo": "^7.7.3" + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" }, - "peerDependencies": { - "webpack-cli": "4.x.x" + "engines": { + "node": ">=8" } }, - "node_modules/@webpack-cli/serve": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-1.7.0.tgz", - "integrity": "sha512-oxnCNGj88fL+xzV+dacXs44HcDwf1ovs3AuEzvP7mqXw7fQntqIhQ1BRmynh4qEKQSSSRSWVyXRjmTbZIX9V2Q==", + "node_modules/@semantic-release/git/node_modules/clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", "dev": true, - "peerDependencies": { - "webpack-cli": "4.x.x" - }, - "peerDependenciesMeta": { - "webpack-dev-server": { - "optional": true - } + "engines": { + "node": ">=6" } }, - "node_modules/@xtuc/ieee754": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", - "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", - "dev": true - }, - "node_modules/@xtuc/long": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", - "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", - "dev": true - }, - "node_modules/abab": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz", - "integrity": "sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==", - "deprecated": "Use your platform's native atob() and btoa() methods instead", - "dev": true + "node_modules/@semantic-release/git/node_modules/p-reduce": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-reduce/-/p-reduce-2.1.0.tgz", + "integrity": "sha512-2USApvnsutq8uoxZBGbbWM0JIYLiEMJ9RlaN7fAzVNb9OZN0SHjjTTfIcb667XynS5Y1VhwDJVDa72TnPzAYWw==", + "dev": true, + "engines": { + "node": ">=8" + } }, - "node_modules/accepts": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", - "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "node_modules/@semantic-release/github": { + "version": "9.2.6", + "resolved": "https://registry.npmjs.org/@semantic-release/github/-/github-9.2.6.tgz", + "integrity": "sha512-shi+Lrf6exeNZF+sBhK+P011LSbhmIAoUEgEY6SsxF8irJ+J2stwI5jkyDQ+4gzYyDImzV6LCKdYB9FXnQRWKA==", "dev": true, "dependencies": { - "mime-types": "~2.1.34", - "negotiator": "0.6.3" + "@octokit/core": "^5.0.0", + "@octokit/plugin-paginate-rest": "^9.0.0", + "@octokit/plugin-retry": "^6.0.0", + "@octokit/plugin-throttling": "^8.0.0", + "@semantic-release/error": "^4.0.0", + "aggregate-error": "^5.0.0", + "debug": "^4.3.4", + "dir-glob": "^3.0.1", + "globby": "^14.0.0", + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.0", + "issue-parser": "^6.0.0", + "lodash-es": "^4.17.21", + "mime": "^4.0.0", + "p-filter": "^4.0.0", + "url-join": "^5.0.0" }, "engines": { - "node": ">= 0.6" + "node": ">=18" + }, + "peerDependencies": { + "semantic-release": ">=20.1.0" } }, - "node_modules/acorn": { - "version": "8.11.2", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.2.tgz", - "integrity": "sha512-nc0Axzp/0FILLEVsm4fNwLCwMttvhEI263QtVPQcbpfZZ3ts0hLsZGOpE6czNlid7CJ9MlyH8reXkpsf3YUY4w==", + "node_modules/@semantic-release/github/node_modules/mime": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/mime/-/mime-4.0.4.tgz", + "integrity": "sha512-v8yqInVjhXyqP6+Kw4fV3ZzeMRqEW6FotRsKXjRS5VMTNIuXsdRoAvklpoRgSqXm6o9VNH4/C0mgedko9DdLsQ==", "dev": true, + "funding": [ + "https://github.com/sponsors/broofa" + ], "bin": { - "acorn": "bin/acorn" + "mime": "bin/cli.js" }, "engines": { - "node": ">=0.4.0" + "node": ">=16" } }, - "node_modules/acorn-import-assertions": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz", - "integrity": "sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==", + "node_modules/@semantic-release/npm": { + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/@semantic-release/npm/-/npm-11.0.3.tgz", + "integrity": "sha512-KUsozQGhRBAnoVg4UMZj9ep436VEGwT536/jwSqB7vcEfA6oncCUU7UIYTRdLx7GvTtqn0kBjnkfLVkcnBa2YQ==", "dev": true, + "dependencies": { + "@semantic-release/error": "^4.0.0", + "aggregate-error": "^5.0.0", + "execa": "^8.0.0", + "fs-extra": "^11.0.0", + "lodash-es": "^4.17.21", + "nerf-dart": "^1.0.0", + "normalize-url": "^8.0.0", + "npm": "^10.5.0", + "rc": "^1.2.8", + "read-pkg": "^9.0.0", + "registry-auth-token": "^5.0.0", + "semver": "^7.1.2", + "tempy": "^3.0.0" + }, + "engines": { + "node": "^18.17 || >=20" + }, "peerDependencies": { - "acorn": "^8" + "semantic-release": ">=20.1.0" } }, - "node_modules/acorn-jsx": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz", - "integrity": "sha512-AU7pnZkguthwBjKgCg6998ByQNIMjbuDQZ8bb78QAFZwPfmKia8AIzgY/gWgqCjnht8JLdXmB4YxA0KaV60ncQ==", + "node_modules/@semantic-release/npm/node_modules/execa": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", + "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==", "dev": true, "dependencies": { - "acorn": "^3.0.4" - } - }, - "node_modules/acorn-jsx/node_modules/acorn": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz", - "integrity": "sha512-OLUyIIZ7mF5oaAUT1w0TFqQS81q3saT46x8t7ukpPjMNk+nbs4ZHhs7ToV8EWnLYLepjETXd4XaCE4uxkMeqUw==", - "dev": true, - "bin": { - "acorn": "bin/acorn" + "cross-spawn": "^7.0.3", + "get-stream": "^8.0.1", + "human-signals": "^5.0.0", + "is-stream": "^3.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^5.1.0", + "onetime": "^6.0.0", + "signal-exit": "^4.1.0", + "strip-final-newline": "^3.0.0" }, "engines": { - "node": ">=0.4.0" + "node": ">=16.17" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" } }, - "node_modules/acorn-walk": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.2.tgz", - "integrity": "sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==", + "node_modules/@semantic-release/npm/node_modules/get-stream": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", + "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==", "dev": true, "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/agent-base": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz", - "integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==", - "dependencies": { - "debug": "^4.3.4" + "node": ">=16" }, - "engines": { - "node": ">= 14" + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "node_modules/@semantic-release/npm/node_modules/hosted-git-info": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-7.0.2.tgz", + "integrity": "sha512-puUZAUKT5m8Zzvs72XWy3HtvVbTWljRE66cP60bxJzAqf2DgICo7lYTY2IHUmLnNpjYvw5bvmoHvPc0QO2a62w==", "dev": true, "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" + "lru-cache": "^10.0.1" }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" + "engines": { + "node": "^16.14.0 || >=18.0.0" } }, - "node_modules/ajv-formats": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", - "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", + "node_modules/@semantic-release/npm/node_modules/human-signals": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz", + "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==", "dev": true, - "dependencies": { - "ajv": "^8.0.0" - }, - "peerDependencies": { - "ajv": "^8.0.0" - }, - "peerDependenciesMeta": { - "ajv": { - "optional": true - } + "engines": { + "node": ">=16.17.0" } }, - "node_modules/ajv-formats/node_modules/ajv": { - "version": "8.12.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", - "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "node_modules/@semantic-release/npm/node_modules/is-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", + "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" }, "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/ajv-formats/node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "node_modules/@semantic-release/npm/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", "dev": true }, - "node_modules/ajv-keywords": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", - "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "node_modules/@semantic-release/npm/node_modules/mimic-fn": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", + "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", "dev": true, - "peerDependencies": { - "ajv": "^6.9.1" + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/ansi-escapes": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz", - "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==", + "node_modules/@semantic-release/npm/node_modules/normalize-package-data": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-6.0.2.tgz", + "integrity": "sha512-V6gygoYb/5EmNI+MEGrWkC+e6+Rr7mTmfHrxDbLzxQogBkgzo76rkok0Am6thgSF7Mv2nLOajAJj5vDJZEFn7g==", "dev": true, + "dependencies": { + "hosted-git-info": "^7.0.0", + "semver": "^7.3.5", + "validate-npm-package-license": "^3.0.4" + }, "engines": { - "node": ">=4" + "node": "^16.14.0 || >=18.0.0" } }, - "node_modules/ansi-html-community": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/ansi-html-community/-/ansi-html-community-0.0.8.tgz", - "integrity": "sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw==", + "node_modules/@semantic-release/npm/node_modules/npm-run-path": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.3.0.tgz", + "integrity": "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==", "dev": true, - "engines": [ - "node >= 0.8.0" - ], - "bin": { - "ansi-html": "bin/ansi-html" + "dependencies": { + "path-key": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "node_modules/@semantic-release/npm/node_modules/onetime": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", + "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", "dev": true, + "dependencies": { + "mimic-fn": "^4.0.0" + }, "engines": { - "node": ">=8" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "node_modules/@semantic-release/npm/node_modules/parse-json": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-8.1.0.tgz", + "integrity": "sha512-rum1bPifK5SSar35Z6EKZuYPJx85pkNaFrxBK3mwdfSJ1/WKbYrjoW/zTPSjRRamfmVX1ACBIdFAO0VRErW/EA==", "dev": true, "dependencies": { - "color-convert": "^2.0.1" + "@babel/code-frame": "^7.22.13", + "index-to-position": "^0.1.2", + "type-fest": "^4.7.1" }, "engines": { - "node": ">=8" + "node": ">=18" }, "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/anymatch": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", - "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "node_modules/@semantic-release/npm/node_modules/path-key": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", + "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@semantic-release/npm/node_modules/read-pkg": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-9.0.1.tgz", + "integrity": "sha512-9viLL4/n1BJUCT1NXVTdS1jtm80yDEgR5T4yCelII49Mbj0v1rZdKqj7zCiYdbB0CuCgdrvHcNogAKTFPBocFA==", "dev": true, "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" + "@types/normalize-package-data": "^2.4.3", + "normalize-package-data": "^6.0.0", + "parse-json": "^8.0.0", + "type-fest": "^4.6.0", + "unicorn-magic": "^0.1.0" }, "engines": { - "node": ">= 8" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/arg": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", - "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", - "dev": true - }, - "node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true - }, - "node_modules/array-flatten": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-2.1.2.tgz", - "integrity": "sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ==", - "dev": true - }, - "node_modules/array-ify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/array-ify/-/array-ify-1.0.0.tgz", - "integrity": "sha512-c5AMf34bKdvPhQ7tBGhqkgKNUzMr4WUs+WDtC2ZUGOUncbxKMTvqxYctiseW3+L4bA8ec+GcZ6/A/FW4m8ukng==", - "dev": true - }, - "node_modules/arrify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==", + "node_modules/@semantic-release/npm/node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", "dev": true, "engines": { - "node": ">=0.10.0" + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + "node_modules/@semantic-release/npm/node_modules/strip-final-newline": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", + "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, - "node_modules/babel-code-frame": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", - "integrity": "sha512-XqYMR2dfdGMW+hd0IUZ2PwK+fGeFkOxZJ0wY+JaQAHzt1Zx8LcvpiZD2NiGkEG8qx0CfkAOr5xt76d1e8vG90g==", + "node_modules/@semantic-release/npm/node_modules/type-fest": { + "version": "4.26.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.26.1.tgz", + "integrity": "sha512-yOGpmOAL7CkKe/91I5O3gPICmJNLJ1G4zFYVAsRHg7M64biSnPtRj0WNQt++bRkjYOqjWXrhnUw1utzmVErAdg==", "dev": true, - "dependencies": { - "chalk": "^1.1.3", - "esutils": "^2.0.2", - "js-tokens": "^3.0.2" + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/babel-code-frame/node_modules/ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", + "node_modules/@semantic-release/release-notes-generator": { + "version": "12.1.0", + "resolved": "https://registry.npmjs.org/@semantic-release/release-notes-generator/-/release-notes-generator-12.1.0.tgz", + "integrity": "sha512-g6M9AjUKAZUZnxaJZnouNBeDNTCUrJ5Ltj+VJ60gJeDaRRahcHsry9HW8yKrnKkKNkx5lbWiEP1FPMqVNQz8Kg==", "dev": true, + "dependencies": { + "conventional-changelog-angular": "^7.0.0", + "conventional-changelog-writer": "^7.0.0", + "conventional-commits-filter": "^4.0.0", + "conventional-commits-parser": "^5.0.0", + "debug": "^4.0.0", + "get-stream": "^7.0.0", + "import-from-esm": "^1.0.3", + "into-stream": "^7.0.0", + "lodash-es": "^4.17.21", + "read-pkg-up": "^11.0.0" + }, "engines": { - "node": ">=0.10.0" + "node": "^18.17 || >=20.6.1" + }, + "peerDependencies": { + "semantic-release": ">=20.1.0" } }, - "node_modules/babel-code-frame/node_modules/ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha512-kmCevFghRiWM7HB5zTPULl4r9bVFSWjz62MhqizDGUrq2NWuNMQyuv4tHHoKJHs69M/MF64lEcHdYIocrdWQYA==", + "node_modules/@semantic-release/release-notes-generator/node_modules/conventional-changelog-angular": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-7.0.0.tgz", + "integrity": "sha512-ROjNchA9LgfNMTTFSIWPzebCwOGFdgkEq45EnvvrmSLvCtAw0HSmrCs7/ty+wAeYUZyNay0YMUNYFTRL72PkBQ==", "dev": true, + "dependencies": { + "compare-func": "^2.0.0" + }, "engines": { - "node": ">=0.10.0" + "node": ">=16" } }, - "node_modules/babel-code-frame/node_modules/chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha512-U3lRVLMSlsCfjqYPbLyVv11M9CPW4I728d6TCKMAOJueEeB9/8o+eSsMnxPJD+Q+K909sdESg7C+tIkoH6on1A==", + "node_modules/@semantic-release/release-notes-generator/node_modules/conventional-commits-parser": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-5.0.0.tgz", + "integrity": "sha512-ZPMl0ZJbw74iS9LuX9YIAiW8pfM5p3yh2o/NbXHbkFuZzY5jvdi5jFycEOkmBW5H5I7nA+D6f3UcsCLP2vvSEA==", "dev": true, "dependencies": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" + "is-text-path": "^2.0.0", + "JSONStream": "^1.3.5", + "meow": "^12.0.1", + "split2": "^4.0.0" + }, + "bin": { + "conventional-commits-parser": "cli.mjs" }, "engines": { - "node": ">=0.10.0" + "node": ">=16" } }, - "node_modules/babel-code-frame/node_modules/js-tokens": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", - "integrity": "sha512-RjTcuD4xjtthQkaWH7dFlH85L+QaVtSoOyGdZ3g6HFhS9dFNDfLyqgm2NFe2X6cQpeFmt0452FJjFG5UameExg==", - "dev": true + "node_modules/@semantic-release/release-notes-generator/node_modules/get-stream": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-7.0.1.tgz", + "integrity": "sha512-3M8C1EOFN6r8AMUhwUAACIoXZJEOufDU5+0gFFN5uNs6XYOralD2Pqkl7m046va6x77FwposWXbAhPPIOus7mQ==", + "dev": true, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, - "node_modules/babel-code-frame/node_modules/strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==", + "node_modules/@semantic-release/release-notes-generator/node_modules/hosted-git-info": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-7.0.2.tgz", + "integrity": "sha512-puUZAUKT5m8Zzvs72XWy3HtvVbTWljRE66cP60bxJzAqf2DgICo7lYTY2IHUmLnNpjYvw5bvmoHvPc0QO2a62w==", "dev": true, "dependencies": { - "ansi-regex": "^2.0.0" + "lru-cache": "^10.0.1" }, "engines": { - "node": ">=0.10.0" + "node": "^16.14.0 || >=18.0.0" } }, - "node_modules/babel-code-frame/node_modules/supports-color": { + "node_modules/@semantic-release/release-notes-generator/node_modules/is-text-path": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha512-KKNVtd6pCYgPIKU4cp2733HWYCpplQhddZLBUryaAHou723x+FRzQ5Df824Fj+IyyuiQTRoub4SnIFfIcrp70g==", + "resolved": "https://registry.npmjs.org/is-text-path/-/is-text-path-2.0.0.tgz", + "integrity": "sha512-+oDTluR6WEjdXEJMnC2z6A4FRwFoYuvShVVEGsS7ewc0UTi2QtAKMDJuL4BDEVt+5T7MjFo12RP8ghOM75oKJw==", "dev": true, + "dependencies": { + "text-extensions": "^2.0.0" + }, "engines": { - "node": ">=0.8.0" + "node": ">=8" } }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true - }, - "node_modules/batch": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", - "integrity": "sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==", + "node_modules/@semantic-release/release-notes-generator/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", "dev": true }, - "node_modules/binary-extensions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", - "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "node_modules/@semantic-release/release-notes-generator/node_modules/meow": { + "version": "12.1.1", + "resolved": "https://registry.npmjs.org/meow/-/meow-12.1.1.tgz", + "integrity": "sha512-BhXM0Au22RwUneMPwSCnyhTOizdWoIEPU9sp0Aqa1PnDMR5Wv2FGXYDjuzJEIX+Eo2Rb8xuYe5jrnm5QowQFkw==", "dev": true, "engines": { - "node": ">=8" + "node": ">=16.10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/blockly": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/blockly/-/blockly-11.0.0.tgz", - "integrity": "sha512-6Ie7HuZWZLaETIVKFEP4FPDz267Pubn6+weQNZvXzqnkOYp9sKPSsPue8QIMCV9Qb5F4wYhqivgiDcZJcE1UlQ==", + "node_modules/@semantic-release/release-notes-generator/node_modules/normalize-package-data": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-6.0.2.tgz", + "integrity": "sha512-V6gygoYb/5EmNI+MEGrWkC+e6+Rr7mTmfHrxDbLzxQogBkgzo76rkok0Am6thgSF7Mv2nLOajAJj5vDJZEFn7g==", + "dev": true, "dependencies": { - "jsdom": "23.0.0" + "hosted-git-info": "^7.0.0", + "semver": "^7.3.5", + "validate-npm-package-license": "^3.0.4" }, "engines": { - "node": ">=18" + "node": "^16.14.0 || >=18.0.0" } }, - "node_modules/body-parser": { - "version": "1.20.1", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", - "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", + "node_modules/@semantic-release/release-notes-generator/node_modules/parse-json": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-8.1.0.tgz", + "integrity": "sha512-rum1bPifK5SSar35Z6EKZuYPJx85pkNaFrxBK3mwdfSJ1/WKbYrjoW/zTPSjRRamfmVX1ACBIdFAO0VRErW/EA==", "dev": true, "dependencies": { - "bytes": "3.1.2", - "content-type": "~1.0.4", - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "on-finished": "2.4.1", - "qs": "6.11.0", - "raw-body": "2.5.1", - "type-is": "~1.6.18", - "unpipe": "1.0.0" + "@babel/code-frame": "^7.22.13", + "index-to-position": "^0.1.2", + "type-fest": "^4.7.1" }, "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/body-parser/node_modules/bytes": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "node_modules/@semantic-release/release-notes-generator/node_modules/read-pkg": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-9.0.1.tgz", + "integrity": "sha512-9viLL4/n1BJUCT1NXVTdS1jtm80yDEgR5T4yCelII49Mbj0v1rZdKqj7zCiYdbB0CuCgdrvHcNogAKTFPBocFA==", "dev": true, + "dependencies": { + "@types/normalize-package-data": "^2.4.3", + "normalize-package-data": "^6.0.0", + "parse-json": "^8.0.0", + "type-fest": "^4.6.0", + "unicorn-magic": "^0.1.0" + }, "engines": { - "node": ">= 0.8" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/body-parser/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "node_modules/@semantic-release/release-notes-generator/node_modules/read-pkg-up": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-11.0.0.tgz", + "integrity": "sha512-LOVbvF1Q0SZdjClSefZ0Nz5z8u+tIE7mV5NibzmE9VYmDe9CaBbAVtz1veOSZbofrdsilxuDAYnFenukZVp8/Q==", + "deprecated": "Renamed to read-package-up", "dev": true, "dependencies": { - "ms": "2.0.0" + "find-up-simple": "^1.0.0", + "read-pkg": "^9.0.0", + "type-fest": "^4.6.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/body-parser/node_modules/iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "node_modules/@semantic-release/release-notes-generator/node_modules/split2": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", + "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==", "dev": true, - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3" - }, "engines": { - "node": ">=0.10.0" + "node": ">= 10.x" } }, - "node_modules/body-parser/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true - }, - "node_modules/bonjour-service": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/bonjour-service/-/bonjour-service-1.1.1.tgz", - "integrity": "sha512-Z/5lQRMOG9k7W+FkeGTNjh7htqn/2LMnfOvBZ8pynNZCM9MwkQkI3zeI4oz09uWdcgmgHugVvBqxGg4VQJ5PCg==", + "node_modules/@semantic-release/release-notes-generator/node_modules/text-extensions": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/text-extensions/-/text-extensions-2.4.0.tgz", + "integrity": "sha512-te/NtwBwfiNRLf9Ijqx3T0nlqZiQ2XrrtBvu+cLL8ZRrGkO0NHTug8MYFKyoSrv/sHTaSKfilUkizV6XhxMJ3g==", "dev": true, - "dependencies": { - "array-flatten": "^2.1.2", - "dns-equal": "^1.0.0", - "fast-deep-equal": "^3.1.3", - "multicast-dns": "^7.2.5" + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "node_modules/@semantic-release/release-notes-generator/node_modules/type-fest": { + "version": "4.26.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.26.1.tgz", + "integrity": "sha512-yOGpmOAL7CkKe/91I5O3gPICmJNLJ1G4zFYVAsRHg7M64biSnPtRj0WNQt++bRkjYOqjWXrhnUw1utzmVErAdg==", "dev": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "node_modules/@sindresorhus/is": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz", + "integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==", "dev": true, - "dependencies": { - "fill-range": "^7.0.1" - }, "engines": { - "node": ">=8" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/is?sponsor=1" } }, - "node_modules/browserslist": { - "version": "4.22.2", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.2.tgz", - "integrity": "sha512-0UgcrvQmBDvZHFGdYUehrCNIazki7/lUP3kkoi/r3YB2amZbFM9J43ZRkJTXBUZK4gmx56+Sqk9+Vs9mwZx9+A==", + "node_modules/@sindresorhus/merge-streams": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/merge-streams/-/merge-streams-2.3.0.tgz", + "integrity": "sha512-LtoMMhxAlorcGhmFYI+LhPgbPZCkgP6ra1YL604EeF6U98pLlQ3iWIGMdWSC+vWmPBWBNgmDBAhnAobLROJmwg==", "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "dependencies": { - "caniuse-lite": "^1.0.30001565", - "electron-to-chromium": "^1.4.601", - "node-releases": "^2.0.14", - "update-browserslist-db": "^1.0.13" - }, - "bin": { - "browserslist": "cli.js" - }, "engines": { - "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "node_modules/@tsconfig/node10": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz", + "integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==", "dev": true }, - "node_modules/bytes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", - "integrity": "sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==", - "dev": true, - "engines": { - "node": ">= 0.8" - } + "node_modules/@tsconfig/node12": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", + "dev": true }, - "node_modules/call-bind": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.5.tgz", - "integrity": "sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ==", + "node_modules/@tsconfig/node14": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", + "dev": true + }, + "node_modules/@tsconfig/node16": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", + "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", + "dev": true + }, + "node_modules/@types/body-parser": { + "version": "1.19.5", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz", + "integrity": "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==", "dev": true, "dependencies": { - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.1", - "set-function-length": "^1.1.1" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "@types/connect": "*", + "@types/node": "*" } }, - "node_modules/caller-path": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz", - "integrity": "sha512-UJiE1otjXPF5/x+T3zTnSFiTOEmJoGTD9HmBoxnCUwho61a2eSNn/VwtwuIBDAo2SEOv1AJ7ARI5gCmohFLu/g==", + "node_modules/@types/bonjour": { + "version": "3.5.13", + "resolved": "https://registry.npmjs.org/@types/bonjour/-/bonjour-3.5.13.tgz", + "integrity": "sha512-z9fJ5Im06zvUL548KvYNecEVlA7cVDkGUi6kZusb04mpyEFKCIZJvloCcmpmLaIahDpOQGHaHmG6imtPMmPXGQ==", "dev": true, "dependencies": { - "callsites": "^0.2.0" - }, - "engines": { - "node": ">=0.10.0" + "@types/node": "*" } }, - "node_modules/caller-path/node_modules/callsites": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz", - "integrity": "sha512-Zv4Dns9IbXXmPkgRRUjAaJQgfN4xX5p6+RQFhWUqscdvvK2xK/ZL8b3IXIJsj+4sD+f24NwnWy2BY8AJ82JB0A==", + "node_modules/@types/connect": { + "version": "3.4.38", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", + "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", "dev": true, - "engines": { - "node": ">=0.10.0" + "dependencies": { + "@types/node": "*" } }, - "node_modules/callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "node_modules/@types/connect-history-api-fallback": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.5.4.tgz", + "integrity": "sha512-n6Cr2xS1h4uAulPRdlw6Jl6s1oG8KrVilPN2yUITEs+K48EzMJJ3W1xy8K5eWuFvjp3R74AOIGSmp2UfBJ8HFw==", "dev": true, - "engines": { - "node": ">=6" + "dependencies": { + "@types/express-serve-static-core": "*", + "@types/node": "*" } }, - "node_modules/camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "node_modules/@types/eslint": { + "version": "8.56.0", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.0.tgz", + "integrity": "sha512-FlsN0p4FhuYRjIxpbdXovvHQhtlG05O1GG/RNWvdAxTboR438IOTwmrY/vLA+Xfgg06BTkP045M3vpFwTMv1dg==", "dev": true, - "engines": { - "node": ">=6" + "dependencies": { + "@types/estree": "*", + "@types/json-schema": "*" } }, - "node_modules/camelcase-keys": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-6.2.2.tgz", - "integrity": "sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==", + "node_modules/@types/eslint-scope": { + "version": "3.7.7", + "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz", + "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==", "dev": true, "dependencies": { - "camelcase": "^5.3.1", - "map-obj": "^4.0.0", - "quick-lru": "^4.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "@types/eslint": "*", + "@types/estree": "*" } }, - "node_modules/caniuse-lite": { - "version": "1.0.30001570", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001570.tgz", - "integrity": "sha512-+3e0ASu4sw1SWaoCtvPeyXp+5PsjigkSt8OXZbF9StH5pQWbxEjLAZE3n8Aup5udop1uRiKA7a4utUk/uoSpUw==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/caniuse-lite" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ] + "node_modules/@types/estree": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", + "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", + "dev": true }, - "node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "node_modules/@types/express": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz", + "integrity": "sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==", "dev": true, "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "@types/body-parser": "*", + "@types/express-serve-static-core": "^4.17.33", + "@types/qs": "*", + "@types/serve-static": "*" } }, - "node_modules/chalk/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "node_modules/@types/express-serve-static-core": { + "version": "4.17.41", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.41.tgz", + "integrity": "sha512-OaJ7XLaelTgrvlZD8/aa0vvvxZdUmlCn6MtWeB7TkiKW70BQLc9XEPpDLPdbo52ZhXUCrznlWdCHWxJWtdyajA==", "dev": true, "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*", + "@types/send": "*" } }, - "node_modules/chardet": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.4.2.tgz", - "integrity": "sha512-j/Toj7f1z98Hh2cYo2BVr85EpIRWqUi7rtRSGxh/cqUjqrnJe9l9UE7IUGd2vQ2p+kSHLkSzObQPZPLUC6TQwg==", + "node_modules/@types/http-errors": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz", + "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==", "dev": true }, - "node_modules/chokidar": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", - "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "node_modules/@types/http-proxy": { + "version": "1.17.14", + "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.14.tgz", + "integrity": "sha512-SSrD0c1OQzlFX7pGu1eXxSEjemej64aaNPRhhVYUGqXh0BtldAAx37MG8btcumvpgKyZp1F5Gn3JkktdxiFv6w==", "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - ], "dependencies": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" - }, - "engines": { - "node": ">= 8.10.0" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" + "@types/node": "*" } }, - "node_modules/chrome-trace-event": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", - "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==", - "dev": true, - "engines": { - "node": ">=6.0" - } + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true }, - "node_modules/circular-json": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz", - "integrity": "sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A==", - "deprecated": "CircularJSON is in maintenance only, flatted is its successor.", + "node_modules/@types/mime": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", + "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==", "dev": true }, - "node_modules/cli-cursor": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", - "integrity": "sha512-8lgKz8LmCRYZZQDpRyT2m5rKJ08TnU4tR9FFFW2rxpxR1FzWi4PQ/NfyODchAatHaUgnSPVcx/R5w6NuTBzFiw==", + "node_modules/@types/minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-hov8bUuiLiyFPGyFPE1lwWhmzYbirOXQNNo40+y3zow8aFVTeyn3VWL0VFFfdNddA8S4Vf0Tc062rzyNr7Paag==", + "dev": true + }, + "node_modules/@types/node": { + "version": "20.10.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.10.5.tgz", + "integrity": "sha512-nNPsNE65wjMxEKI93yOP+NPGGBJz/PoN3kZsVLee0XMiJolxSekEVD8wRwBUBqkwc7UWop0edW50yrCQW4CyRw==", "dev": true, "dependencies": { - "restore-cursor": "^2.0.0" - }, - "engines": { - "node": ">=4" + "undici-types": "~5.26.4" } }, - "node_modules/cli-width": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.1.tgz", - "integrity": "sha512-GRMWDxpOB6Dgk2E5Uo+3eEBvtOOlimMmpbFiKuLFnQzYDavtLFY3K5ona41jgN/WdRZtG7utuVSVTL4HbZHGkw==", + "node_modules/@types/node-forge": { + "version": "1.3.10", + "resolved": "https://registry.npmjs.org/@types/node-forge/-/node-forge-1.3.10.tgz", + "integrity": "sha512-y6PJDYN4xYBxwd22l+OVH35N+1fCYWiuC3aiP2SlXVE6Lo7SS+rSx9r89hLxrP4pn6n1lBGhHJ12pj3F3Mpttw==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/normalize-package-data": { + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.4.tgz", + "integrity": "sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==", "dev": true }, - "node_modules/cliui": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", - "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "node_modules/@types/qs": { + "version": "6.9.10", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.10.tgz", + "integrity": "sha512-3Gnx08Ns1sEoCrWssEgTSJs/rsT2vhGP+Ja9cnnk9k4ALxinORlQneLXFeFKOTJMOeZUFD1s7w+w2AphTpvzZw==", + "dev": true + }, + "node_modules/@types/range-parser": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", + "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==", + "dev": true + }, + "node_modules/@types/retry": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.0.tgz", + "integrity": "sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==", + "dev": true + }, + "node_modules/@types/send": { + "version": "0.17.4", + "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz", + "integrity": "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==", "dev": true, "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.1", - "wrap-ansi": "^7.0.0" - }, - "engines": { - "node": ">=12" + "@types/mime": "^1", + "@types/node": "*" } }, - "node_modules/clone-deep": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", - "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", + "node_modules/@types/serve-index": { + "version": "1.9.4", + "resolved": "https://registry.npmjs.org/@types/serve-index/-/serve-index-1.9.4.tgz", + "integrity": "sha512-qLpGZ/c2fhSs5gnYsQxtDEq3Oy8SXPClIXkW5ghvAvsNuVSA8k+gCONcUCS/UjLEYvYps+e8uBtfgXgvhwfNug==", "dev": true, "dependencies": { - "is-plain-object": "^2.0.4", - "kind-of": "^6.0.2", - "shallow-clone": "^3.0.0" - }, - "engines": { - "node": ">=6" + "@types/express": "*" } }, - "node_modules/co": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", - "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", + "node_modules/@types/serve-static": { + "version": "1.15.5", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.5.tgz", + "integrity": "sha512-PDRk21MnK70hja/YF8AHfC7yIsiQHn1rcXx7ijCFBX/k+XQJhQT/gw3xekXKJvx+5SXaMMS8oqQy09Mzvz2TuQ==", "dev": true, - "engines": { - "iojs": ">= 1.0.0", - "node": ">= 0.12.0" + "dependencies": { + "@types/http-errors": "*", + "@types/mime": "*", + "@types/node": "*" } }, - "node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "node_modules/@types/sockjs": { + "version": "0.3.36", + "resolved": "https://registry.npmjs.org/@types/sockjs/-/sockjs-0.3.36.tgz", + "integrity": "sha512-MK9V6NzAS1+Ud7JV9lJLFqW85VbC9dq3LmwZCuBe4wBDgKC0Kj/jd8Xl+nSviU+Qc3+m7umHHyHg//2KSa0a0Q==", "dev": true, "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" + "@types/node": "*" } }, - "node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/colorette": { - "version": "2.0.20", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", - "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", - "dev": true + "node_modules/@types/ws": { + "version": "8.5.10", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.10.tgz", + "integrity": "sha512-vmQSUcfalpIq0R9q7uTo2lXs6eGIpt9wtnLdMv9LVpIjCA/+ufZRozlVoVelIYixx1ugCBKDhn89vnsEGOCx9A==", + "dev": true, + "dependencies": { + "@types/node": "*" + } }, - "node_modules/combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "node_modules/@webassemblyjs/ast": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.6.tgz", + "integrity": "sha512-IN1xI7PwOvLPgjcf180gC1bqn3q/QaOCwYUahIOhbYUu8KA/3tw2RT/T0Gidi1l7Hhj5D/INhJxiICObqpMu4Q==", + "dev": true, "dependencies": { - "delayed-stream": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" + "@webassemblyjs/helper-numbers": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6" } }, - "node_modules/commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "node_modules/@webassemblyjs/floating-point-hex-parser": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz", + "integrity": "sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==", "dev": true }, - "node_modules/compare-func": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/compare-func/-/compare-func-2.0.0.tgz", - "integrity": "sha512-zHig5N+tPWARooBnb0Zx1MFcdfpyJrfTJ3Y5L+IFvUm8rM74hHz66z0gw0x4tijh5CorKkKUCnW82R2vmpeCRA==", + "node_modules/@webassemblyjs/helper-api-error": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz", + "integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==", + "dev": true + }, + "node_modules/@webassemblyjs/helper-buffer": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.6.tgz", + "integrity": "sha512-z3nFzdcp1mb8nEOFFk8DrYLpHvhKC3grJD2ardfKOzmbmJvEf/tPIqCY+sNcwZIY8ZD7IkB2l7/pqhUhqm7hLA==", + "dev": true + }, + "node_modules/@webassemblyjs/helper-numbers": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz", + "integrity": "sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==", "dev": true, "dependencies": { - "array-ify": "^1.0.0", - "dot-prop": "^5.1.0" + "@webassemblyjs/floating-point-hex-parser": "1.11.6", + "@webassemblyjs/helper-api-error": "1.11.6", + "@xtuc/long": "4.2.2" } }, - "node_modules/compressible": { - "version": "2.0.18", - "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", - "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", + "node_modules/@webassemblyjs/helper-wasm-bytecode": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz", + "integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==", + "dev": true + }, + "node_modules/@webassemblyjs/helper-wasm-section": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.6.tgz", + "integrity": "sha512-LPpZbSOwTpEC2cgn4hTydySy1Ke+XEu+ETXuoyvuyezHO3Kjdu90KK95Sh9xTbmjrCsUwvWwCOQQNta37VrS9g==", "dev": true, "dependencies": { - "mime-db": ">= 1.43.0 < 2" - }, - "engines": { - "node": ">= 0.6" + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-buffer": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/wasm-gen": "1.11.6" } }, - "node_modules/compression": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz", - "integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==", + "node_modules/@webassemblyjs/ieee754": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz", + "integrity": "sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==", "dev": true, "dependencies": { - "accepts": "~1.3.5", - "bytes": "3.0.0", - "compressible": "~2.0.16", - "debug": "2.6.9", - "on-headers": "~1.0.2", - "safe-buffer": "5.1.2", - "vary": "~1.1.2" - }, - "engines": { - "node": ">= 0.8.0" + "@xtuc/ieee754": "^1.2.0" } }, - "node_modules/compression/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "node_modules/@webassemblyjs/leb128": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.6.tgz", + "integrity": "sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==", "dev": true, "dependencies": { - "ms": "2.0.0" + "@xtuc/long": "4.2.2" } }, - "node_modules/compression/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true - }, - "node_modules/compression/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "node_modules/@webassemblyjs/utf8": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.6.tgz", + "integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==", "dev": true }, - "node_modules/concat-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", - "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "node_modules/@webassemblyjs/wasm-edit": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.6.tgz", + "integrity": "sha512-Ybn2I6fnfIGuCR+Faaz7YcvtBKxvoLV3Lebn1tM4o/IAJzmi9AWYIPWpyBfU8cC+JxAO57bk4+zdsTjJR+VTOw==", "dev": true, - "engines": [ - "node >= 0.8" - ], "dependencies": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-buffer": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/helper-wasm-section": "1.11.6", + "@webassemblyjs/wasm-gen": "1.11.6", + "@webassemblyjs/wasm-opt": "1.11.6", + "@webassemblyjs/wasm-parser": "1.11.6", + "@webassemblyjs/wast-printer": "1.11.6" } }, - "node_modules/concat-stream/node_modules/readable-stream": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", - "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "node_modules/@webassemblyjs/wasm-gen": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.6.tgz", + "integrity": "sha512-3XOqkZP/y6B4F0PBAXvI1/bky7GryoogUtfwExeP/v7Nzwo1QLcq5oQmpKlftZLbT+ERUOAZVQjuNVak6UXjPA==", "dev": true, "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/ieee754": "1.11.6", + "@webassemblyjs/leb128": "1.11.6", + "@webassemblyjs/utf8": "1.11.6" } }, - "node_modules/concat-stream/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "node_modules/concat-stream/node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "node_modules/@webassemblyjs/wasm-opt": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.6.tgz", + "integrity": "sha512-cOrKuLRE7PCe6AsOVl7WasYf3wbSo4CeOk6PkrjS7g57MFfVUF9u6ysQBBODX0LdgSvQqRiGz3CXvIDKcPNy4g==", "dev": true, "dependencies": { - "safe-buffer": "~5.1.0" + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-buffer": "1.11.6", + "@webassemblyjs/wasm-gen": "1.11.6", + "@webassemblyjs/wasm-parser": "1.11.6" } }, - "node_modules/connect-history-api-fallback": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-2.0.0.tgz", - "integrity": "sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA==", + "node_modules/@webassemblyjs/wasm-parser": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.6.tgz", + "integrity": "sha512-6ZwPeGzMJM3Dqp3hCsLgESxBGtT/OeCvCZ4TA1JUPYgmhAx38tTPR9JaKy0S5H3evQpO/h2uWs2j6Yc/fjkpTQ==", "dev": true, - "engines": { - "node": ">=0.8" + "dependencies": { + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-api-error": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/ieee754": "1.11.6", + "@webassemblyjs/leb128": "1.11.6", + "@webassemblyjs/utf8": "1.11.6" } }, - "node_modules/content-disposition": { - "version": "0.5.4", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", - "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "node_modules/@webassemblyjs/wast-printer": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.6.tgz", + "integrity": "sha512-JM7AhRcE+yW2GWYaKeHL5vt4xqee5N2WcezptmgyhNS+ScggqcT1OtXykhAb13Sn5Yas0j2uv9tHgrjwvzAP4A==", "dev": true, "dependencies": { - "safe-buffer": "5.2.1" - }, - "engines": { - "node": ">= 0.6" + "@webassemblyjs/ast": "1.11.6", + "@xtuc/long": "4.2.2" } }, - "node_modules/content-type": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", - "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "node_modules/@webpack-cli/configtest": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-1.2.0.tgz", + "integrity": "sha512-4FB8Tj6xyVkyqjj1OaTqCjXYULB9FMkqQ8yGrZjRDrYh0nOE+7Lhs45WioWQQMV+ceFlE368Ukhe6xdvJM9Egg==", "dev": true, - "engines": { - "node": ">= 0.6" + "peerDependencies": { + "webpack": "4.x.x || 5.x.x", + "webpack-cli": "4.x.x" } }, - "node_modules/conventional-changelog-angular": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-6.0.0.tgz", - "integrity": "sha512-6qLgrBF4gueoC7AFVHu51nHL9pF9FRjXrH+ceVf7WmAfH3gs+gEYOkvxhjMPjZu57I4AGUGoNTY8V7Hrgf1uqg==", + "node_modules/@webpack-cli/info": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-1.5.0.tgz", + "integrity": "sha512-e8tSXZpw2hPl2uMJY6fsMswaok5FdlGNRTktvFk2sD8RjH0hE2+XistawJx1vmKteh4NmGmNUrp+Tb2w+udPcQ==", "dev": true, "dependencies": { - "compare-func": "^2.0.0" + "envinfo": "^7.7.3" }, - "engines": { - "node": ">=14" + "peerDependencies": { + "webpack-cli": "4.x.x" } }, - "node_modules/conventional-changelog-conventionalcommits": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/conventional-changelog-conventionalcommits/-/conventional-changelog-conventionalcommits-6.1.0.tgz", - "integrity": "sha512-3cS3GEtR78zTfMzk0AizXKKIdN4OvSh7ibNz6/DPbhWWQu7LqE/8+/GqSodV+sywUR2gpJAdP/1JFf4XtN7Zpw==", - "dev": true, - "dependencies": { - "compare-func": "^2.0.0" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/conventional-commits-parser": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-4.0.0.tgz", - "integrity": "sha512-WRv5j1FsVM5FISJkoYMR6tPk07fkKT0UodruX4je86V4owk451yjXAKzKAPOs9l7y59E2viHUS9eQ+dfUA9NSg==", + "node_modules/@webpack-cli/serve": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-1.7.0.tgz", + "integrity": "sha512-oxnCNGj88fL+xzV+dacXs44HcDwf1ovs3AuEzvP7mqXw7fQntqIhQ1BRmynh4qEKQSSSRSWVyXRjmTbZIX9V2Q==", "dev": true, - "dependencies": { - "is-text-path": "^1.0.1", - "JSONStream": "^1.3.5", - "meow": "^8.1.2", - "split2": "^3.2.2" - }, - "bin": { - "conventional-commits-parser": "cli.js" + "peerDependencies": { + "webpack-cli": "4.x.x" }, - "engines": { - "node": ">=14" + "peerDependenciesMeta": { + "webpack-dev-server": { + "optional": true + } } }, - "node_modules/cookie": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", - "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", - "dev": true, - "engines": { - "node": ">= 0.6" - } + "node_modules/@xtuc/ieee754": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", + "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", + "dev": true }, - "node_modules/cookie-signature": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", + "node_modules/@xtuc/long": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", + "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", "dev": true }, - "node_modules/core-util-is": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", - "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", + "node_modules/abab": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz", + "integrity": "sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==", + "deprecated": "Use your platform's native atob() and btoa() methods instead", "dev": true }, - "node_modules/cosmiconfig": { - "version": "8.3.6", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.3.6.tgz", - "integrity": "sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==", + "node_modules/accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", "dev": true, "dependencies": { - "import-fresh": "^3.3.0", - "js-yaml": "^4.1.0", - "parse-json": "^5.2.0", - "path-type": "^4.0.0" + "mime-types": "~2.1.34", + "negotiator": "0.6.3" }, "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/d-fischer" - }, - "peerDependencies": { - "typescript": ">=4.9.5" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "node": ">= 0.6" } }, - "node_modules/cosmiconfig-typescript-loader": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/cosmiconfig-typescript-loader/-/cosmiconfig-typescript-loader-4.4.0.tgz", - "integrity": "sha512-BabizFdC3wBHhbI4kJh0VkQP9GkBfoHPydD0COMce1nJ1kJAB3F2TmJ/I7diULBKtmEWSwEbuN/KDtgnmUUVmw==", + "node_modules/acorn": { + "version": "8.11.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.2.tgz", + "integrity": "sha512-nc0Axzp/0FILLEVsm4fNwLCwMttvhEI263QtVPQcbpfZZ3ts0hLsZGOpE6czNlid7CJ9MlyH8reXkpsf3YUY4w==", "dev": true, - "engines": { - "node": ">=v14.21.3" + "bin": { + "acorn": "bin/acorn" }, - "peerDependencies": { - "@types/node": "*", - "cosmiconfig": ">=7", - "ts-node": ">=10", - "typescript": ">=4" + "engines": { + "node": ">=0.4.0" } }, - "node_modules/create-require": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", - "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", - "dev": true - }, - "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "node_modules/acorn-import-assertions": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz", + "integrity": "sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==", "dev": true, - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" + "peerDependencies": { + "acorn": "^8" } }, - "node_modules/cssstyle": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-3.0.0.tgz", - "integrity": "sha512-N4u2ABATi3Qplzf0hWbVCdjenim8F3ojEXpBDF5hBpjzW182MjNGLqfmQ0SkSPeQ+V86ZXgeH8aXj6kayd4jgg==", + "node_modules/acorn-jsx": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz", + "integrity": "sha512-AU7pnZkguthwBjKgCg6998ByQNIMjbuDQZ8bb78QAFZwPfmKia8AIzgY/gWgqCjnht8JLdXmB4YxA0KaV60ncQ==", + "dev": true, "dependencies": { - "rrweb-cssom": "^0.6.0" - }, - "engines": { - "node": ">=14" + "acorn": "^3.0.4" } }, - "node_modules/dargs": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/dargs/-/dargs-7.0.0.tgz", - "integrity": "sha512-2iy1EkLdlBzQGvbweYRFxmFath8+K7+AKB0TlhHWkNuH+TmovaMH/Wp7V7R4u7f4SnX3OgLsU9t1NI9ioDnUpg==", + "node_modules/acorn-jsx/node_modules/acorn": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz", + "integrity": "sha512-OLUyIIZ7mF5oaAUT1w0TFqQS81q3saT46x8t7ukpPjMNk+nbs4ZHhs7ToV8EWnLYLepjETXd4XaCE4uxkMeqUw==", "dev": true, + "bin": { + "acorn": "bin/acorn" + }, "engines": { - "node": ">=8" + "node": ">=0.4.0" } }, - "node_modules/data-urls": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-5.0.0.tgz", - "integrity": "sha512-ZYP5VBHshaDAiVZxjbRVcFJpc+4xGgT0bK3vzy1HLN8jTO975HEbuYzZJcHoQEY5K1a0z8YayJkyVETa08eNTg==", - "dependencies": { - "whatwg-mimetype": "^4.0.0", - "whatwg-url": "^14.0.0" - }, + "node_modules/acorn-walk": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.2.tgz", + "integrity": "sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==", + "dev": true, "engines": { - "node": ">=18" + "node": ">=0.4.0" } }, - "node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "node_modules/agent-base": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz", + "integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==", "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" + "debug": "^4.3.4" }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", - "dev": true, "engines": { - "node": ">=0.10.0" + "node": ">= 14" } }, - "node_modules/decamelize-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.1.tgz", - "integrity": "sha512-WiPxgEirIV0/eIOMcnFBA3/IJZAZqKnwAwWyvvdi4lsr1WCN22nhdf/3db3DoZcUjTV2SqfzIwNyp6y2xs3nmg==", + "node_modules/aggregate-error": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-5.0.0.tgz", + "integrity": "sha512-gOsf2YwSlleG6IjRYG2A7k0HmBMEo6qVNk9Bp/EaLgAJT5ngH6PXbqa4ItvnEwCm/velL5jAnQgsHsWnjhGmvw==", "dev": true, "dependencies": { - "decamelize": "^1.1.0", - "map-obj": "^1.0.0" + "clean-stack": "^5.2.0", + "indent-string": "^5.0.0" }, "engines": { - "node": ">=0.10.0" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/decamelize-keys/node_modules/map-obj": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", - "integrity": "sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==", + "node_modules/aggregate-error/node_modules/indent-string": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-5.0.0.tgz", + "integrity": "sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==", "dev": true, "engines": { - "node": ">=0.10.0" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/decimal.js": { - "version": "10.4.3", - "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.3.tgz", - "integrity": "sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==" - }, - "node_modules/deep-is": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "dev": true - }, - "node_modules/default-gateway": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-6.0.3.tgz", - "integrity": "sha512-fwSOJsbbNzZ/CUFpqFBqYfYNLj1NbMPm8MMCIzHjC83iSJRBEGmDUxU+WP661BaBQImeC2yHwXtz+P/O9o+XEg==", + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, "dependencies": { - "execa": "^5.0.0" + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" }, - "engines": { - "node": ">= 10" + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/define-data-property": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.1.tgz", - "integrity": "sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==", + "node_modules/ajv-formats": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", + "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", "dev": true, "dependencies": { - "get-intrinsic": "^1.2.1", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.0" + "ajv": "^8.0.0" }, - "engines": { - "node": ">= 0.4" + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } } }, - "node_modules/define-lazy-prop": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", - "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==", + "node_modules/ajv-formats/node_modules/ajv": { + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", + "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", "dev": true, - "engines": { - "node": ">=8" + "dependencies": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/delayed-stream": { + "node_modules/ajv-formats/node_modules/json-schema-traverse": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", - "engines": { - "node": ">=0.4.0" - } + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true }, - "node_modules/depd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", - "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "node_modules/ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", "dev": true, - "engines": { - "node": ">= 0.8" + "peerDependencies": { + "ajv": "^6.9.1" } }, - "node_modules/destroy": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", - "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "node_modules/ansi-escapes": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz", + "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==", "dev": true, "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" + "node": ">=4" } }, - "node_modules/detect-node": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", - "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==", - "dev": true - }, - "node_modules/diff": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "node_modules/ansi-html-community": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/ansi-html-community/-/ansi-html-community-0.0.8.tgz", + "integrity": "sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw==", "dev": true, - "engines": { - "node": ">=0.3.1" + "engines": [ + "node >= 0.8.0" + ], + "bin": { + "ansi-html": "bin/ansi-html" } }, - "node_modules/dns-equal": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/dns-equal/-/dns-equal-1.0.0.tgz", - "integrity": "sha512-z+paD6YUQsk+AbGCEM4PrOXSss5gd66QfcVBFTKR/HpFL9jCqikS94HYwKww6fQyO7IxrIIyUu+g0Ka9tUS2Cg==", - "dev": true - }, - "node_modules/dns-packet": { - "version": "5.6.1", - "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-5.6.1.tgz", - "integrity": "sha512-l4gcSouhcgIKRvyy99RNVOgxXiicE+2jZoNmaNmZ6JXiGajBOJAesk1OBlJuM5k2c+eudGdLxDqXuPCKIj6kpw==", + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "dev": true, - "dependencies": { - "@leichtgewicht/ip-codec": "^2.0.1" - }, "engines": { - "node": ">=6" + "node": ">=8" } }, - "node_modules/doctrine": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "dependencies": { - "esutils": "^2.0.2" + "color-convert": "^2.0.1" }, "engines": { - "node": ">=0.10.0" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/dot-prop": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", - "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==", + "node_modules/ansicolors": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/ansicolors/-/ansicolors-0.3.2.tgz", + "integrity": "sha512-QXu7BPrP29VllRxH8GwB7x5iX5qWKAAMLqKQGWTeLWVlNHNOpVMJ91dsxQAIWXpjuW5wqvxu3Jd/nRjrJ+0pqg==", + "dev": true + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", "dev": true, "dependencies": { - "is-obj": "^2.0.0" + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" }, "engines": { - "node": ">=8" + "node": ">= 8" } }, - "node_modules/ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", + "node_modules/arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", "dev": true }, - "node_modules/electron-to-chromium": { - "version": "1.4.615", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.615.tgz", - "integrity": "sha512-/bKPPcgZVUziECqDc+0HkT87+0zhaWSZHNXqF8FLd2lQcptpmUFwoCSWjCdOng9Gdq+afKArPdEg/0ZW461Eng==", + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", "dev": true }, - "node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "node_modules/argv-formatter": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/argv-formatter/-/argv-formatter-1.0.0.tgz", + "integrity": "sha512-F2+Hkm9xFaRg+GkaNnbwXNDV5O6pnCFEmqyhvfC/Ic5LbgOWjJh3L+mN/s91rxVL3znE7DYVpW0GJFT+4YBgWw==", + "dev": true, + "license": "MIT" + }, + "node_modules/array-flatten": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-2.1.2.tgz", + "integrity": "sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ==", "dev": true }, - "node_modules/encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "node_modules/array-ify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array-ify/-/array-ify-1.0.0.tgz", + "integrity": "sha512-c5AMf34bKdvPhQ7tBGhqkgKNUzMr4WUs+WDtC2ZUGOUncbxKMTvqxYctiseW3+L4bA8ec+GcZ6/A/FW4m8ukng==", + "dev": true + }, + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", "dev": true, "engines": { - "node": ">= 0.8" + "node": ">=8" } }, - "node_modules/enhanced-resolve": { - "version": "5.15.0", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.15.0.tgz", - "integrity": "sha512-LXYT42KJ7lpIKECr2mAXIaMldcNCh/7E0KBKOu4KSfkHmP+mZmSs+8V5gBAqisWBy0OO4W5Oyys0GO1Y8KtdKg==", + "node_modules/arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==", "dev": true, - "dependencies": { - "graceful-fs": "^4.2.4", - "tapable": "^2.2.0" - }, "engines": { - "node": ">=10.13.0" + "node": ">=0.10.0" } }, - "node_modules/entities": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", - "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", - "engines": { - "node": ">=0.12" - }, - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" }, - "node_modules/envinfo": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.11.0.tgz", - "integrity": "sha512-G9/6xF1FPbIw0TtalAMaVPpiq2aDEuKLXM314jPVAO9r2fo2a4BLqMNkmRS7O/xPPZ+COAhGIz3ETvHEV3eUcg==", + "node_modules/babel-code-frame": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", + "integrity": "sha512-XqYMR2dfdGMW+hd0IUZ2PwK+fGeFkOxZJ0wY+JaQAHzt1Zx8LcvpiZD2NiGkEG8qx0CfkAOr5xt76d1e8vG90g==", "dev": true, - "bin": { - "envinfo": "dist/cli.js" - }, - "engines": { - "node": ">=4" + "dependencies": { + "chalk": "^1.1.3", + "esutils": "^2.0.2", + "js-tokens": "^3.0.2" } }, - "node_modules/error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "node_modules/babel-code-frame/node_modules/ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", "dev": true, - "dependencies": { - "is-arrayish": "^0.2.1" + "engines": { + "node": ">=0.10.0" } }, - "node_modules/es-module-lexer": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.4.1.tgz", - "integrity": "sha512-cXLGjP0c4T3flZJKQSuziYoq7MlT+rnvfZjfp7h+I7K9BNX54kP9nyWvdbwjQ4u1iWbOL4u96fgeZLToQlZC7w==", - "dev": true - }, - "node_modules/escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "node_modules/babel-code-frame/node_modules/ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha512-kmCevFghRiWM7HB5zTPULl4r9bVFSWjz62MhqizDGUrq2NWuNMQyuv4tHHoKJHs69M/MF64lEcHdYIocrdWQYA==", "dev": true, "engines": { - "node": ">=6" + "node": ">=0.10.0" } }, - "node_modules/escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", - "dev": true - }, - "node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/eslint": { - "version": "4.19.1", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-4.19.1.tgz", - "integrity": "sha512-bT3/1x1EbZB7phzYu7vCr1v3ONuzDtX8WjuM9c0iYxe+cq+pwcKEoQjl7zd3RpC6YOLgnSy3cTN58M2jcoPDIQ==", + "node_modules/babel-code-frame/node_modules/chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha512-U3lRVLMSlsCfjqYPbLyVv11M9CPW4I728d6TCKMAOJueEeB9/8o+eSsMnxPJD+Q+K909sdESg7C+tIkoH6on1A==", "dev": true, "dependencies": { - "ajv": "^5.3.0", - "babel-code-frame": "^6.22.0", - "chalk": "^2.1.0", - "concat-stream": "^1.6.0", - "cross-spawn": "^5.1.0", - "debug": "^3.1.0", - "doctrine": "^2.1.0", - "eslint-scope": "^3.7.1", - "eslint-visitor-keys": "^1.0.0", - "espree": "^3.5.4", - "esquery": "^1.0.0", - "esutils": "^2.0.2", - "file-entry-cache": "^2.0.0", - "functional-red-black-tree": "^1.0.1", - "glob": "^7.1.2", - "globals": "^11.0.1", - "ignore": "^3.3.3", - "imurmurhash": "^0.1.4", - "inquirer": "^3.0.6", - "is-resolvable": "^1.0.0", - "js-yaml": "^3.9.1", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.3.0", - "lodash": "^4.17.4", - "minimatch": "^3.0.2", - "mkdirp": "^0.5.1", - "natural-compare": "^1.4.0", - "optionator": "^0.8.2", - "path-is-inside": "^1.0.2", - "pluralize": "^7.0.0", - "progress": "^2.0.0", - "regexpp": "^1.0.1", - "require-uncached": "^1.0.3", - "semver": "^5.3.0", - "strip-ansi": "^4.0.0", - "strip-json-comments": "~2.0.1", - "table": "4.0.2", - "text-table": "~0.2.0" - }, - "bin": { - "eslint": "bin/eslint.js" + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" }, "engines": { - "node": ">=4" + "node": ">=0.10.0" } }, - "node_modules/eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "node_modules/babel-code-frame/node_modules/js-tokens": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", + "integrity": "sha512-RjTcuD4xjtthQkaWH7dFlH85L+QaVtSoOyGdZ3g6HFhS9dFNDfLyqgm2NFe2X6cQpeFmt0452FJjFG5UameExg==", + "dev": true + }, + "node_modules/babel-code-frame/node_modules/strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==", "dev": true, "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" + "ansi-regex": "^2.0.0" }, "engines": { - "node": ">=8.0.0" + "node": ">=0.10.0" } }, - "node_modules/eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "node_modules/babel-code-frame/node_modules/supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha512-KKNVtd6pCYgPIKU4cp2733HWYCpplQhddZLBUryaAHou723x+FRzQ5Df824Fj+IyyuiQTRoub4SnIFfIcrp70g==", "dev": true, "engines": { - "node": ">=4" + "node": ">=0.8.0" } }, - "node_modules/eslint/node_modules/ajv": { - "version": "5.5.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz", - "integrity": "sha512-Ajr4IcMXq/2QmMkEmSvxqfLN5zGmJ92gHXAeOXq1OekoH2rfDNsgdDoL2f7QaRCy7G/E6TpxBVdRuNraMztGHw==", + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "node_modules/batch": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", + "integrity": "sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==", + "dev": true + }, + "node_modules/before-after-hook": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.3.tgz", + "integrity": "sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ==", + "dev": true + }, + "node_modules/binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", "dev": true, - "dependencies": { - "co": "^4.6.0", - "fast-deep-equal": "^1.0.0", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.3.0" + "engines": { + "node": ">=8" } }, - "node_modules/eslint/node_modules/ansi-regex": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz", - "integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==", - "dev": true, + "node_modules/blockly": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/blockly/-/blockly-11.0.0.tgz", + "integrity": "sha512-6Ie7HuZWZLaETIVKFEP4FPDz267Pubn6+weQNZvXzqnkOYp9sKPSsPue8QIMCV9Qb5F4wYhqivgiDcZJcE1UlQ==", + "dependencies": { + "jsdom": "23.0.0" + }, "engines": { - "node": ">=4" + "node": ">=18" } }, - "node_modules/eslint/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "node_modules/body-parser": { + "version": "1.20.1", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", + "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", "dev": true, "dependencies": { - "color-convert": "^1.9.0" + "bytes": "3.1.2", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.11.0", + "raw-body": "2.5.1", + "type-is": "~1.6.18", + "unpipe": "1.0.0" }, "engines": { - "node": ">=4" + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" } }, - "node_modules/eslint/node_modules/argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "node_modules/body-parser/node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", "dev": true, - "dependencies": { - "sprintf-js": "~1.0.2" + "engines": { + "node": ">= 0.8" } }, - "node_modules/eslint/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "node_modules/body-parser/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" + "ms": "2.0.0" } }, - "node_modules/eslint/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "node_modules/body-parser/node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", "dev": true, "dependencies": { - "color-name": "1.1.3" + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" } }, - "node_modules/eslint/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "node_modules/body-parser/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", "dev": true }, - "node_modules/eslint/node_modules/cross-spawn": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", - "integrity": "sha512-pTgQJ5KC0d2hcY8eyL1IzlBPYjTkyH72XRZPnLyKus2mBfNjQs3klqbJU2VILqZryAZUt9JOb3h/mWMy23/f5A==", + "node_modules/bonjour-service": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/bonjour-service/-/bonjour-service-1.1.1.tgz", + "integrity": "sha512-Z/5lQRMOG9k7W+FkeGTNjh7htqn/2LMnfOvBZ8pynNZCM9MwkQkI3zeI4oz09uWdcgmgHugVvBqxGg4VQJ5PCg==", "dev": true, "dependencies": { - "lru-cache": "^4.0.1", - "shebang-command": "^1.2.0", - "which": "^1.2.9" + "array-flatten": "^2.1.2", + "dns-equal": "^1.0.0", + "fast-deep-equal": "^3.1.3", + "multicast-dns": "^7.2.5" } }, - "node_modules/eslint/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "node_modules/bottleneck": { + "version": "2.19.5", + "resolved": "https://registry.npmjs.org/bottleneck/-/bottleneck-2.19.5.tgz", + "integrity": "sha512-VHiNCbI1lKdl44tGrhNfU3lup0Tj/ZBMJB5/2ZbNXRCPuRCO7ed2mgcK4r17y+KB2EfuYuRaVlwNbAeaWGSpbw==", + "dev": true + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, "dependencies": { - "ms": "^2.1.1" + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" } }, - "node_modules/eslint/node_modules/eslint-scope": { - "version": "3.7.3", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-3.7.3.tgz", - "integrity": "sha512-W+B0SvF4gamyCTmUc+uITPY0989iXVfKvhwtmJocTaYoc/3khEHmEmvfY/Gn9HA9VV75jrQECsHizkNw1b68FA==", + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", "dev": true, "dependencies": { - "esrecurse": "^4.1.0", - "estraverse": "^4.1.1" + "fill-range": "^7.0.1" }, "engines": { - "node": ">=4.0.0" + "node": ">=8" } }, - "node_modules/eslint/node_modules/fast-deep-equal": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz", - "integrity": "sha512-fueX787WZKCV0Is4/T2cyAdM4+x1S3MXXOAhavE1ys/W42SHAPacLTQhucja22QBYrfGw50M2sRiXPtTGv9Ymw==", - "dev": true - }, - "node_modules/eslint/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/eslint/node_modules/js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "node_modules/browserslist": { + "version": "4.22.2", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.2.tgz", + "integrity": "sha512-0UgcrvQmBDvZHFGdYUehrCNIazki7/lUP3kkoi/r3YB2amZbFM9J43ZRkJTXBUZK4gmx56+Sqk9+Vs9mwZx9+A==", "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" + "caniuse-lite": "^1.0.30001565", + "electron-to-chromium": "^1.4.601", + "node-releases": "^2.0.14", + "update-browserslist-db": "^1.0.13" }, "bin": { - "js-yaml": "bin/js-yaml.js" + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" } }, - "node_modules/eslint/node_modules/json-schema-traverse": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz", - "integrity": "sha512-4JD/Ivzg7PoW8NzdrBSr3UFwC9mHgvI7Z6z3QGBsSHgKaRTUDmyZAAKJo2UbG1kUVfS9WS8bi36N49U1xw43DA==", + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", "dev": true }, - "node_modules/eslint/node_modules/lru-cache": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", - "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", + "node_modules/bytes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", + "integrity": "sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==", "dev": true, - "dependencies": { - "pseudomap": "^1.0.2", - "yallist": "^2.1.2" + "engines": { + "node": ">= 0.8" } }, - "node_modules/eslint/node_modules/semver": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "node_modules/call-bind": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.5.tgz", + "integrity": "sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ==", "dev": true, - "bin": { - "semver": "bin/semver" + "dependencies": { + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.1", + "set-function-length": "^1.1.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/eslint/node_modules/shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==", + "node_modules/caller-path": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz", + "integrity": "sha512-UJiE1otjXPF5/x+T3zTnSFiTOEmJoGTD9HmBoxnCUwho61a2eSNn/VwtwuIBDAo2SEOv1AJ7ARI5gCmohFLu/g==", "dev": true, "dependencies": { - "shebang-regex": "^1.0.0" + "callsites": "^0.2.0" }, "engines": { "node": ">=0.10.0" } }, - "node_modules/eslint/node_modules/shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==", + "node_modules/caller-path/node_modules/callsites": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz", + "integrity": "sha512-Zv4Dns9IbXXmPkgRRUjAaJQgfN4xX5p6+RQFhWUqscdvvK2xK/ZL8b3IXIJsj+4sD+f24NwnWy2BY8AJ82JB0A==", "dev": true, "engines": { "node": ">=0.10.0" } }, - "node_modules/eslint/node_modules/strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==", + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", "dev": true, - "dependencies": { - "ansi-regex": "^3.0.0" - }, "engines": { - "node": ">=4" + "node": ">=6" } }, - "node_modules/eslint/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", "dev": true, - "dependencies": { - "has-flag": "^3.0.0" - }, "engines": { - "node": ">=4" + "node": ">=6" } }, - "node_modules/eslint/node_modules/which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "node_modules/camelcase-keys": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-6.2.2.tgz", + "integrity": "sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==", "dev": true, "dependencies": { - "isexe": "^2.0.0" + "camelcase": "^5.3.1", + "map-obj": "^4.0.0", + "quick-lru": "^4.0.1" }, - "bin": { - "which": "bin/which" + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/eslint/node_modules/yallist": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", - "integrity": "sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==", - "dev": true + "node_modules/caniuse-lite": { + "version": "1.0.30001570", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001570.tgz", + "integrity": "sha512-+3e0ASu4sw1SWaoCtvPeyXp+5PsjigkSt8OXZbF9StH5pQWbxEjLAZE3n8Aup5udop1uRiKA7a4utUk/uoSpUw==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ] }, - "node_modules/espree": { - "version": "3.5.4", - "resolved": "https://registry.npmjs.org/espree/-/espree-3.5.4.tgz", - "integrity": "sha512-yAcIQxtmMiB/jL32dzEp2enBeidsB7xWPLNiw3IIkpVds1P+h7qF9YwJq1yUNzp2OKXgAprs4F61ih66UsoD1A==", + "node_modules/cardinal": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/cardinal/-/cardinal-2.1.1.tgz", + "integrity": "sha512-JSr5eOgoEymtYHBjNWyjrMqet9Am2miJhlfKNdqLp6zoeAh0KN5dRAcxlecj5mAJrmQomgiOBj35xHLrFjqBpw==", "dev": true, "dependencies": { - "acorn": "^5.5.0", - "acorn-jsx": "^3.0.0" + "ansicolors": "~0.3.2", + "redeyed": "~2.1.0" }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/espree/node_modules/acorn": { - "version": "5.7.4", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.4.tgz", - "integrity": "sha512-1D++VG7BhrtvQpNbBzovKNc1FLGGEE/oGe7b9xJm/RFHMBeUaUGpluV9RLjZa47YFdPcDAenEYuq9pQPcMdLJg==", - "dev": true, "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" + "cdl": "bin/cdl.js" } }, - "node_modules/esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, - "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" }, "engines": { - "node": ">=4" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/esquery": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", - "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", + "node_modules/chalk/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, "dependencies": { - "estraverse": "^5.1.0" + "has-flag": "^4.0.0" }, "engines": { - "node": ">=0.10" + "node": ">=8" } }, - "node_modules/esquery/node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "node_modules/char-regex": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", + "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", "dev": true, "engines": { - "node": ">=4.0" + "node": ">=10" } }, - "node_modules/esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "node_modules/chardet": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.4.2.tgz", + "integrity": "sha512-j/Toj7f1z98Hh2cYo2BVr85EpIRWqUi7rtRSGxh/cqUjqrnJe9l9UE7IUGd2vQ2p+kSHLkSzObQPZPLUC6TQwg==", + "dev": true + }, + "node_modules/chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], "dependencies": { - "estraverse": "^5.2.0" + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" }, "engines": { - "node": ">=4.0" + "node": ">= 8.10.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" } }, - "node_modules/esrecurse/node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "node_modules/chrome-trace-event": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", + "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==", "dev": true, "engines": { - "node": ">=4.0" + "node": ">=6.0" } }, - "node_modules/estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true, - "engines": { - "node": ">=4.0" - } + "node_modules/circular-json": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz", + "integrity": "sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A==", + "deprecated": "CircularJSON is in maintenance only, flatted is its successor.", + "dev": true }, - "node_modules/esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "node_modules/clean-stack": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-5.2.0.tgz", + "integrity": "sha512-TyUIUJgdFnCISzG5zu3291TAsE77ddchd0bepon1VVQrKLGKFED4iXFEDQ24mIPdPBbyE16PK3F8MYE1CmcBEQ==", "dev": true, + "dependencies": { + "escape-string-regexp": "5.0.0" + }, "engines": { - "node": ">=0.10.0" + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/etag": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "node_modules/clean-stack/node_modules/escape-string-regexp": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", + "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", "dev": true, "engines": { - "node": ">= 0.6" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/eventemitter3": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", - "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", - "dev": true - }, - "node_modules/events": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", - "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "node_modules/cli-cursor": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", + "integrity": "sha512-8lgKz8LmCRYZZQDpRyT2m5rKJ08TnU4tR9FFFW2rxpxR1FzWi4PQ/NfyODchAatHaUgnSPVcx/R5w6NuTBzFiw==", "dev": true, + "dependencies": { + "restore-cursor": "^2.0.0" + }, "engines": { - "node": ">=0.8.x" + "node": ">=4" } }, - "node_modules/execa": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", - "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "node_modules/cli-table3": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.5.tgz", + "integrity": "sha512-+W/5efTR7y5HRD7gACw9yQjqMVvEMLBHmboM/kPWam+H+Hmyrgjh6YncVKK122YZkXrLudzTuAukUw9FnMf7IQ==", "dev": true, "dependencies": { - "cross-spawn": "^7.0.3", - "get-stream": "^6.0.0", - "human-signals": "^2.1.0", - "is-stream": "^2.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.1", - "onetime": "^5.1.2", - "signal-exit": "^3.0.3", - "strip-final-newline": "^2.0.0" + "string-width": "^4.2.0" }, "engines": { - "node": ">=10" + "node": "10.* || >= 12.*" }, - "funding": { - "url": "https://github.com/sindresorhus/execa?sponsor=1" + "optionalDependencies": { + "@colors/colors": "1.5.0" } }, - "node_modules/express": { - "version": "4.18.2", - "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", - "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", + "node_modules/cli-width": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.1.tgz", + "integrity": "sha512-GRMWDxpOB6Dgk2E5Uo+3eEBvtOOlimMmpbFiKuLFnQzYDavtLFY3K5ona41jgN/WdRZtG7utuVSVTL4HbZHGkw==", + "dev": true + }, + "node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", "dev": true, "dependencies": { - "accepts": "~1.3.8", - "array-flatten": "1.1.1", - "body-parser": "1.20.1", - "content-disposition": "0.5.4", - "content-type": "~1.0.4", - "cookie": "0.5.0", - "cookie-signature": "1.0.6", - "debug": "2.6.9", - "depd": "2.0.0", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "finalhandler": "1.2.0", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "merge-descriptors": "1.0.1", - "methods": "~1.1.2", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "path-to-regexp": "0.1.7", - "proxy-addr": "~2.0.7", - "qs": "6.11.0", - "range-parser": "~1.2.1", - "safe-buffer": "5.2.1", - "send": "0.18.0", - "serve-static": "1.15.0", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "type-is": "~1.6.18", - "utils-merge": "1.0.1", - "vary": "~1.1.2" + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" }, "engines": { - "node": ">= 0.10.0" + "node": ">=12" } }, - "node_modules/express/node_modules/array-flatten": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", - "dev": true - }, - "node_modules/express/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "node_modules/clone-deep": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", + "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", "dev": true, "dependencies": { - "ms": "2.0.0" + "is-plain-object": "^2.0.4", + "kind-of": "^6.0.2", + "shallow-clone": "^3.0.0" + }, + "engines": { + "node": ">=6" } }, - "node_modules/express/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true - }, - "node_modules/external-editor": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-2.2.0.tgz", - "integrity": "sha512-bSn6gvGxKt+b7+6TKEv1ZycHleA7aHhRHyAqJyp5pbUFuYYNIzpZnQDk7AsYckyWdEnTeAnay0aCy2aV6iTk9A==", + "node_modules/co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", "dev": true, - "dependencies": { - "chardet": "^0.4.0", - "iconv-lite": "^0.4.17", - "tmp": "^0.0.33" - }, "engines": { - "node": ">=0.12" + "iojs": ">= 1.0.0", + "node": ">= 0.12.0" } }, - "node_modules/external-editor/node_modules/iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, "dependencies": { - "safer-buffer": ">= 2.1.2 < 3" + "color-name": "~1.1.4" }, "engines": { - "node": ">=0.10.0" + "node": ">=7.0.0" } }, - "node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true - }, - "node_modules/fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, - "node_modules/fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "node_modules/colorette": { + "version": "2.0.20", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", + "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", "dev": true }, - "node_modules/fastest-levenshtein": { - "version": "1.0.16", - "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz", - "integrity": "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==", - "dev": true, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dependencies": { + "delayed-stream": "~1.0.0" + }, "engines": { - "node": ">= 4.9.1" + "node": ">= 0.8" } }, - "node_modules/faye-websocket": { - "version": "0.11.4", - "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz", - "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==", + "node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true + }, + "node_modules/compare-func": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/compare-func/-/compare-func-2.0.0.tgz", + "integrity": "sha512-zHig5N+tPWARooBnb0Zx1MFcdfpyJrfTJ3Y5L+IFvUm8rM74hHz66z0gw0x4tijh5CorKkKUCnW82R2vmpeCRA==", "dev": true, "dependencies": { - "websocket-driver": ">=0.5.1" - }, - "engines": { - "node": ">=0.8.0" + "array-ify": "^1.0.0", + "dot-prop": "^5.1.0" } }, - "node_modules/figures": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", - "integrity": "sha512-Oa2M9atig69ZkfwiApY8F2Yy+tzMbazyvqv21R0NsSC8floSOC09BbT1ITWAdoMGQvJ/aZnR1KMwdx9tvHnTNA==", + "node_modules/compressible": { + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", + "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", "dev": true, "dependencies": { - "escape-string-regexp": "^1.0.5" + "mime-db": ">= 1.43.0 < 2" }, "engines": { - "node": ">=4" + "node": ">= 0.6" } }, - "node_modules/file-entry-cache": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-2.0.0.tgz", - "integrity": "sha512-uXP/zGzxxFvFfcZGgBIwotm+Tdc55ddPAzF7iHshP4YGaXMww7rSF9peD9D1sui5ebONg5UobsZv+FfgEpGv/w==", - "dev": true, - "dependencies": { - "flat-cache": "^1.2.1", - "object-assign": "^4.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, - "dependencies": { - "to-regex-range": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/finalhandler": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", - "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", + "node_modules/compression": { + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz", + "integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==", "dev": true, "dependencies": { + "accepts": "~1.3.5", + "bytes": "3.0.0", + "compressible": "~2.0.16", "debug": "2.6.9", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "statuses": "2.0.1", - "unpipe": "~1.0.0" + "on-headers": "~1.0.2", + "safe-buffer": "5.1.2", + "vary": "~1.1.2" }, "engines": { - "node": ">= 0.8" + "node": ">= 0.8.0" } }, - "node_modules/finalhandler/node_modules/debug": { + "node_modules/compression/node_modules/debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", @@ -2970,1688 +2954,1647 @@ "ms": "2.0.0" } }, - "node_modules/finalhandler/node_modules/ms": { + "node_modules/compression/node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", "dev": true }, - "node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "node_modules/compression/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true + }, + "node_modules/concat-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", + "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", "dev": true, + "engines": [ + "node >= 0.8" + ], "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=8" + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" } }, - "node_modules/flat": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", - "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "node_modules/concat-stream/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", "dev": true, - "bin": { - "flat": "cli.js" + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" } }, - "node_modules/flat-cache": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.3.4.tgz", - "integrity": "sha512-VwyB3Lkgacfik2vhqR4uv2rvebqmDvFu4jlN/C1RzWoJEo8I7z4Q404oiqYCkq41mni8EzQnm95emU9seckwtg==", + "node_modules/concat-stream/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "node_modules/concat-stream/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "dev": true, "dependencies": { - "circular-json": "^0.3.1", - "graceful-fs": "^4.1.2", - "rimraf": "~2.6.2", - "write": "^0.2.1" - }, - "engines": { - "node": ">=0.10.0" + "safe-buffer": "~5.1.0" } }, - "node_modules/flat-cache/node_modules/rimraf": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", - "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", + "node_modules/config-chain": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.13.tgz", + "integrity": "sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==", "dev": true, "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" + "ini": "^1.3.4", + "proto-list": "~1.2.1" } }, - "node_modules/follow-redirects": { - "version": "1.15.3", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.3.tgz", - "integrity": "sha512-1VzOtuEM8pC9SFU1E+8KfTjZyMztRsgEfwQl44z8A25uy13jSzTj6dyK2Df52iV0vgHCfBwLhDWevLn95w5v6Q==", + "node_modules/connect-history-api-fallback": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-2.0.0.tgz", + "integrity": "sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA==", "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/RubenVerborgh" - } - ], "engines": { - "node": ">=4.0" - }, - "peerDependenciesMeta": { - "debug": { - "optional": true - } + "node": ">=0.8" } }, - "node_modules/form-data": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", - "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "node_modules/content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "dev": true, "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" + "safe-buffer": "5.2.1" }, "engines": { - "node": ">= 6" + "node": ">= 0.6" } }, - "node_modules/forwarded": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", - "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "node_modules/content-type": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", "dev": true, "engines": { "node": ">= 0.6" } }, - "node_modules/fresh": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "node_modules/conventional-changelog-angular": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-6.0.0.tgz", + "integrity": "sha512-6qLgrBF4gueoC7AFVHu51nHL9pF9FRjXrH+ceVf7WmAfH3gs+gEYOkvxhjMPjZu57I4AGUGoNTY8V7Hrgf1uqg==", "dev": true, + "dependencies": { + "compare-func": "^2.0.0" + }, "engines": { - "node": ">= 0.6" + "node": ">=14" } }, - "node_modules/fs-extra": { - "version": "11.2.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz", - "integrity": "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==", + "node_modules/conventional-changelog-conventionalcommits": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/conventional-changelog-conventionalcommits/-/conventional-changelog-conventionalcommits-6.1.0.tgz", + "integrity": "sha512-3cS3GEtR78zTfMzk0AizXKKIdN4OvSh7ibNz6/DPbhWWQu7LqE/8+/GqSodV+sywUR2gpJAdP/1JFf4XtN7Zpw==", "dev": true, "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" + "compare-func": "^2.0.0" }, "engines": { - "node": ">=14.14" + "node": ">=14" } }, - "node_modules/fs-extra/node_modules/universalify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", - "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "node_modules/conventional-changelog-writer": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/conventional-changelog-writer/-/conventional-changelog-writer-7.0.1.tgz", + "integrity": "sha512-Uo+R9neH3r/foIvQ0MKcsXkX642hdm9odUp7TqgFS7BsalTcjzRlIfWZrZR1gbxOozKucaKt5KAbjW8J8xRSmA==", "dev": true, + "dependencies": { + "conventional-commits-filter": "^4.0.0", + "handlebars": "^4.7.7", + "json-stringify-safe": "^5.0.1", + "meow": "^12.0.1", + "semver": "^7.5.2", + "split2": "^4.0.0" + }, + "bin": { + "conventional-changelog-writer": "cli.mjs" + }, "engines": { - "node": ">= 10.0.0" + "node": ">=16" } }, - "node_modules/fs-monkey": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.0.5.tgz", - "integrity": "sha512-8uMbBjrhzW76TYgEV27Y5E//W2f/lTFmx78P2w19FZSxarhI/798APGQyuGCwmkNxgwGRhrLfvWyLBvNtuOmew==", - "dev": true - }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true - }, - "node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "node_modules/conventional-changelog-writer/node_modules/meow": { + "version": "12.1.1", + "resolved": "https://registry.npmjs.org/meow/-/meow-12.1.1.tgz", + "integrity": "sha512-BhXM0Au22RwUneMPwSCnyhTOizdWoIEPU9sp0Aqa1PnDMR5Wv2FGXYDjuzJEIX+Eo2Rb8xuYe5jrnm5QowQFkw==", "dev": true, - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + "node": ">=16.10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/function-bind": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", - "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "node_modules/conventional-changelog-writer/node_modules/split2": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", + "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==", "dev": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "engines": { + "node": ">= 10.x" } }, - "node_modules/functional-red-black-tree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==", - "dev": true - }, - "node_modules/get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "node_modules/conventional-commits-filter": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/conventional-commits-filter/-/conventional-commits-filter-4.0.0.tgz", + "integrity": "sha512-rnpnibcSOdFcdclpFwWa+pPlZJhXE7l+XK04zxhbWrhgpR96h33QLz8hITTXbcYICxVr3HZFtbtUAQ+4LdBo9A==", "dev": true, "engines": { - "node": "6.* || 8.* || >= 10.*" + "node": ">=16" } }, - "node_modules/get-intrinsic": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.2.tgz", - "integrity": "sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA==", + "node_modules/conventional-commits-parser": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-4.0.0.tgz", + "integrity": "sha512-WRv5j1FsVM5FISJkoYMR6tPk07fkKT0UodruX4je86V4owk451yjXAKzKAPOs9l7y59E2viHUS9eQ+dfUA9NSg==", "dev": true, "dependencies": { - "function-bind": "^1.1.2", - "has-proto": "^1.0.1", - "has-symbols": "^1.0.3", - "hasown": "^2.0.0" + "is-text-path": "^1.0.1", + "JSONStream": "^1.3.5", + "meow": "^8.1.2", + "split2": "^3.2.2" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "bin": { + "conventional-commits-parser": "cli.js" + }, + "engines": { + "node": ">=14" } }, - "node_modules/get-stream": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", - "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "node_modules/cookie": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", + "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", "dev": true, "engines": { - "node": ">=10" + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", + "dev": true + }, + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", + "dev": true + }, + "node_modules/cosmiconfig": { + "version": "8.3.6", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.3.6.tgz", + "integrity": "sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==", + "dev": true, + "dependencies": { + "import-fresh": "^3.3.0", + "js-yaml": "^4.1.0", + "parse-json": "^5.2.0", + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=14" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/d-fischer" + }, + "peerDependencies": { + "typescript": ">=4.9.5" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, - "node_modules/git-raw-commits": { - "version": "2.0.11", - "resolved": "https://registry.npmjs.org/git-raw-commits/-/git-raw-commits-2.0.11.tgz", - "integrity": "sha512-VnctFhw+xfj8Va1xtfEqCUD2XDrbAPSJx+hSrE5K7fGdjZruW7XV+QOrN7LF/RJyvspRiD2I0asWsxFp0ya26A==", + "node_modules/cosmiconfig-typescript-loader": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/cosmiconfig-typescript-loader/-/cosmiconfig-typescript-loader-4.4.0.tgz", + "integrity": "sha512-BabizFdC3wBHhbI4kJh0VkQP9GkBfoHPydD0COMce1nJ1kJAB3F2TmJ/I7diULBKtmEWSwEbuN/KDtgnmUUVmw==", "dev": true, - "dependencies": { - "dargs": "^7.0.0", - "lodash": "^4.17.15", - "meow": "^8.0.0", - "split2": "^3.0.0", - "through2": "^4.0.0" + "engines": { + "node": ">=v14.21.3" }, - "bin": { - "git-raw-commits": "cli.js" + "peerDependencies": { + "@types/node": "*", + "cosmiconfig": ">=7", + "ts-node": ">=10", + "typescript": ">=4" + } + }, + "node_modules/create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", + "dev": true + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" }, "engines": { - "node": ">=10" + "node": ">= 8" } }, - "node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "node_modules/crypto-random-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-4.0.0.tgz", + "integrity": "sha512-x8dy3RnvYdlUcPOjkEHqozhiwzKNSq7GcPuXFbnyMOCHxX8V3OgIg/pYuabl2sbUPfIJaeAQB7PMOK8DFIdoRA==", "dev": true, "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" + "type-fest": "^1.0.1" }, "engines": { - "node": "*" + "node": ">=12" }, "funding": { - "url": "https://github.com/sponsors/isaacs" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "node_modules/crypto-random-string/node_modules/type-fest": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-1.4.0.tgz", + "integrity": "sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==", "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cssstyle": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-3.0.0.tgz", + "integrity": "sha512-N4u2ABATi3Qplzf0hWbVCdjenim8F3ojEXpBDF5hBpjzW182MjNGLqfmQ0SkSPeQ+V86ZXgeH8aXj6kayd4jgg==", "dependencies": { - "is-glob": "^4.0.1" + "rrweb-cssom": "^0.6.0" }, "engines": { - "node": ">= 6" + "node": ">=14" } }, - "node_modules/glob-to-regexp": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", - "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", - "dev": true - }, - "node_modules/global-dirs": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-0.1.1.tgz", - "integrity": "sha512-NknMLn7F2J7aflwFOlGdNIuCDpN3VGoSoB+aap3KABFWbHVn1TCgFC+np23J8W2BiZbjfEw3BFBycSMv1AFblg==", + "node_modules/dargs": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/dargs/-/dargs-7.0.0.tgz", + "integrity": "sha512-2iy1EkLdlBzQGvbweYRFxmFath8+K7+AKB0TlhHWkNuH+TmovaMH/Wp7V7R4u7f4SnX3OgLsU9t1NI9ioDnUpg==", "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/data-urls": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-5.0.0.tgz", + "integrity": "sha512-ZYP5VBHshaDAiVZxjbRVcFJpc+4xGgT0bK3vzy1HLN8jTO975HEbuYzZJcHoQEY5K1a0z8YayJkyVETa08eNTg==", "dependencies": { - "ini": "^1.3.4" + "whatwg-mimetype": "^4.0.0", + "whatwg-url": "^14.0.0" }, "engines": { - "node": ">=4" + "node": ">=18" } }, - "node_modules/globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "node_modules/dateformat": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-3.0.3.tgz", + "integrity": "sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q==", "dev": true, "engines": { - "node": ">=4" + "node": "*" } }, - "node_modules/gopd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", - "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", - "dev": true, + "node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "dependencies": { - "get-intrinsic": "^1.1.3" + "ms": "2.1.2" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } } }, - "node_modules/graceful-fs": { - "version": "4.2.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", - "dev": true - }, - "node_modules/handle-thing": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz", - "integrity": "sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==", - "dev": true - }, - "node_modules/hard-rejection": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz", - "integrity": "sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==", + "node_modules/decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", "dev": true, "engines": { - "node": ">=6" + "node": ">=0.10.0" } }, - "node_modules/has-ansi": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", - "integrity": "sha512-C8vBJ8DwUCx19vhm7urhTuUsr4/IyP6l4VzNQDv+ryHQObW3TTTp9yB68WpYgRe2bbaGuZ/se74IqFeVnMnLZg==", + "node_modules/decamelize-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.1.tgz", + "integrity": "sha512-WiPxgEirIV0/eIOMcnFBA3/IJZAZqKnwAwWyvvdi4lsr1WCN22nhdf/3db3DoZcUjTV2SqfzIwNyp6y2xs3nmg==", "dev": true, "dependencies": { - "ansi-regex": "^2.0.0" + "decamelize": "^1.1.0", + "map-obj": "^1.0.0" }, "engines": { "node": ">=0.10.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/has-ansi/node_modules/ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", + "node_modules/decamelize-keys/node_modules/map-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", + "integrity": "sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==", "dev": true, "engines": { "node": ">=0.10.0" } }, - "node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "node_modules/decimal.js": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.3.tgz", + "integrity": "sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==" + }, + "node_modules/deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", "dev": true, "engines": { - "node": ">=8" + "node": ">=4.0.0" } }, - "node_modules/has-property-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz", - "integrity": "sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg==", + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true + }, + "node_modules/default-gateway": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-6.0.3.tgz", + "integrity": "sha512-fwSOJsbbNzZ/CUFpqFBqYfYNLj1NbMPm8MMCIzHjC83iSJRBEGmDUxU+WP661BaBQImeC2yHwXtz+P/O9o+XEg==", "dev": true, "dependencies": { - "get-intrinsic": "^1.2.2" + "execa": "^5.0.0" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "engines": { + "node": ">= 10" } }, - "node_modules/has-proto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", - "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", + "node_modules/define-data-property": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.1.tgz", + "integrity": "sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==", "dev": true, + "dependencies": { + "get-intrinsic": "^1.2.1", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.0" + }, "engines": { "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "node_modules/define-lazy-prop": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", + "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==", "dev": true, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=8" } }, - "node_modules/hasown": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz", - "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==", + "node_modules/del": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/del/-/del-6.1.1.tgz", + "integrity": "sha512-ua8BhapfP0JUJKC/zV9yHHDW/rDoDxP4Zhn3AkA6/xT6gY7jYXJiaeyBZznYVujhZZET+UgcbZiQ7sN3WqcImg==", "dev": true, "dependencies": { - "function-bind": "^1.1.2" + "globby": "^11.0.1", + "graceful-fs": "^4.2.4", + "is-glob": "^4.0.1", + "is-path-cwd": "^2.2.0", + "is-path-inside": "^3.0.2", + "p-map": "^4.0.0", + "rimraf": "^3.0.2", + "slash": "^3.0.0" }, "engines": { - "node": ">= 0.4" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/hosted-git-info": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz", - "integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==", + "node_modules/del/node_modules/aggregate-error": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", + "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", "dev": true, "dependencies": { - "lru-cache": "^6.0.0" + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" }, "engines": { - "node": ">=10" + "node": ">=8" } }, - "node_modules/hpack.js": { - "version": "2.1.6", - "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz", - "integrity": "sha512-zJxVehUdMGIKsRaNt7apO2Gqp0BdqW5yaiGHXXmbpvxgBYVZnAql+BJb4RO5ad2MgpbZKn5G6nMnegrH1FcNYQ==", + "node_modules/del/node_modules/clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", "dev": true, - "dependencies": { - "inherits": "^2.0.1", - "obuf": "^1.0.0", - "readable-stream": "^2.0.1", - "wbuf": "^1.1.0" + "engines": { + "node": ">=6" } }, - "node_modules/hpack.js/node_modules/readable-stream": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", - "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "node_modules/del/node_modules/globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", "dev": true, "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/hpack.js/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "node_modules/hpack.js/node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "node_modules/del/node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", "dev": true, - "dependencies": { - "safe-buffer": "~5.1.0" + "engines": { + "node": ">= 4" } }, - "node_modules/html-encoding-sniffer": { + "node_modules/del/node_modules/p-map": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-4.0.0.tgz", - "integrity": "sha512-Y22oTqIU4uuPgEemfz7NDJz6OeKf12Lsu+QC+s3BVpda64lTiMYCyGwg5ki4vFxkMwQdeZDl2adZoqUgdFuTgQ==", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", + "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", + "dev": true, "dependencies": { - "whatwg-encoding": "^3.1.1" + "aggregate-error": "^3.0.0" }, "engines": { - "node": ">=18" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/html-entities": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.4.0.tgz", - "integrity": "sha512-igBTJcNNNhvZFRtm8uA6xMY6xYleeDwn3PeBCkDz7tHttv4F2hsDI2aPgNERWzvRcNYHNT3ymRaQzllmXj4YsQ==", + "node_modules/del/node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/mdevils" - }, - { - "type": "patreon", - "url": "https://patreon.com/mdevils" - } - ] + "engines": { + "node": ">=8" + } }, - "node_modules/http-deceiver": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz", - "integrity": "sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw==", - "dev": true + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "engines": { + "node": ">=0.4.0" + } }, - "node_modules/http-errors": { + "node_modules/depd": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", - "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", "dev": true, - "dependencies": { - "depd": "2.0.0", - "inherits": "2.0.4", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "toidentifier": "1.0.1" - }, "engines": { "node": ">= 0.8" } }, - "node_modules/http-parser-js": { - "version": "0.5.8", - "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.8.tgz", - "integrity": "sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q==", + "node_modules/deprecation": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz", + "integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==", "dev": true }, - "node_modules/http-proxy": { - "version": "1.18.1", - "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", - "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", + "node_modules/destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", "dev": true, - "dependencies": { - "eventemitter3": "^4.0.0", - "follow-redirects": "^1.0.0", - "requires-port": "^1.0.0" - }, "engines": { - "node": ">=8.0.0" + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" } }, - "node_modules/http-proxy-agent": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", - "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", - "dependencies": { - "agent-base": "^7.1.0", - "debug": "^4.3.4" - }, + "node_modules/detect-node": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", + "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==", + "dev": true + }, + "node_modules/diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true, "engines": { - "node": ">= 14" + "node": ">=0.3.1" } }, - "node_modules/http-proxy-middleware": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.6.tgz", - "integrity": "sha512-ya/UeJ6HVBYxrgYotAZo1KvPWlgB48kUJLDePFeneHsVujFaW5WNj2NgWCAE//B1Dl02BIfYlpNgBy8Kf8Rjmw==", + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", "dev": true, "dependencies": { - "@types/http-proxy": "^1.17.8", - "http-proxy": "^1.18.1", - "is-glob": "^4.0.1", - "is-plain-obj": "^3.0.0", - "micromatch": "^4.0.2" + "path-type": "^4.0.0" }, "engines": { - "node": ">=12.0.0" - }, - "peerDependencies": { - "@types/express": "^4.17.13" - }, - "peerDependenciesMeta": { - "@types/express": { - "optional": true - } + "node": ">=8" } }, - "node_modules/https-proxy-agent": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.4.tgz", - "integrity": "sha512-wlwpilI7YdjSkWaQ/7omYBMTliDcmCN8OLihO6I9B86g06lMyAoqgoDpV0XqoaPOKj+0DIdAvnsWfyAAhmimcg==", + "node_modules/dns-equal": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/dns-equal/-/dns-equal-1.0.0.tgz", + "integrity": "sha512-z+paD6YUQsk+AbGCEM4PrOXSss5gd66QfcVBFTKR/HpFL9jCqikS94HYwKww6fQyO7IxrIIyUu+g0Ka9tUS2Cg==", + "dev": true + }, + "node_modules/dns-packet": { + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-5.6.1.tgz", + "integrity": "sha512-l4gcSouhcgIKRvyy99RNVOgxXiicE+2jZoNmaNmZ6JXiGajBOJAesk1OBlJuM5k2c+eudGdLxDqXuPCKIj6kpw==", + "dev": true, "dependencies": { - "agent-base": "^7.0.2", - "debug": "4" + "@leichtgewicht/ip-codec": "^2.0.1" }, "engines": { - "node": ">= 14" + "node": ">=6" } }, - "node_modules/human-signals": { + "node_modules/doctrine": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", - "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", "dev": true, - "engines": { - "node": ">=10.17.0" - } - }, - "node_modules/husky": { - "version": "9.1.6", - "resolved": "https://registry.npmjs.org/husky/-/husky-9.1.6.tgz", - "integrity": "sha512-sqbjZKK7kf44hfdE94EoX8MZNk0n7HeW37O4YrVGCF4wzgQjp+akPAkfUK5LZ6KuR/6sqeAVuXHji+RzQgOn5A==", - "dev": true, - "license": "MIT", - "bin": { - "husky": "bin.js" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/typicode" - } - }, - "node_modules/iconv-lite": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", - "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", "dependencies": { - "safer-buffer": ">= 2.1.2 < 3.0.0" + "esutils": "^2.0.2" }, "engines": { "node": ">=0.10.0" } }, - "node_modules/ignore": { - "version": "3.3.10", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.10.tgz", - "integrity": "sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug==", - "dev": true - }, - "node_modules/import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "node_modules/dot-prop": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", + "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==", "dev": true, "dependencies": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - }, - "engines": { - "node": ">=6" + "is-obj": "^2.0.0" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/import-fresh/node_modules/resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true, "engines": { - "node": ">=4" + "node": ">=8" } }, - "node_modules/import-local": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", - "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==", + "node_modules/duplexer2": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz", + "integrity": "sha512-asLFVfWWtJ90ZyOUHMqk7/S2w2guQKxUI2itj3d92ADHhxUSbCMGi1f1cBcJ7xM1To+pE/Khbwo1yuNbMEPKeA==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { - "pkg-dir": "^4.2.0", - "resolve-cwd": "^3.0.0" - }, - "bin": { - "import-local-fixture": "fixtures/cli.js" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "readable-stream": "^2.0.2" } }, - "node_modules/imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "node_modules/duplexer2/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", "dev": true, - "engines": { - "node": ">=0.8.19" + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" } }, - "node_modules/indent-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", - "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "node_modules/duplexer2/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", "dev": true, - "engines": { - "node": ">=8" - } + "license": "MIT" }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "node_modules/duplexer2/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "dev": true, + "license": "MIT", "dependencies": { - "once": "^1.3.0", - "wrappy": "1" + "safe-buffer": "~5.1.0" } }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", "dev": true }, - "node_modules/ini": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "node_modules/electron-to-chromium": { + "version": "1.4.615", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.615.tgz", + "integrity": "sha512-/bKPPcgZVUziECqDc+0HkT87+0zhaWSZHNXqF8FLd2lQcptpmUFwoCSWjCdOng9Gdq+afKArPdEg/0ZW461Eng==", "dev": true }, - "node_modules/inquirer": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-3.3.0.tgz", - "integrity": "sha512-h+xtnyk4EwKvFWHrUYsWErEVR+igKtLdchu+o0Z1RL7VU/jVMFbYir2bp6bAj8efFNxWqHX0dIss6fJQ+/+qeQ==", - "dev": true, - "dependencies": { - "ansi-escapes": "^3.0.0", - "chalk": "^2.0.0", - "cli-cursor": "^2.1.0", - "cli-width": "^2.0.0", - "external-editor": "^2.0.4", - "figures": "^2.0.0", - "lodash": "^4.3.0", - "mute-stream": "0.0.7", - "run-async": "^2.2.0", - "rx-lite": "^4.0.8", - "rx-lite-aggregates": "^4.0.8", - "string-width": "^2.1.0", - "strip-ansi": "^4.0.0", - "through": "^2.3.6" - } + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true }, - "node_modules/inquirer/node_modules/ansi-regex": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz", - "integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==", + "node_modules/emojilib": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/emojilib/-/emojilib-2.4.0.tgz", + "integrity": "sha512-5U0rVMU5Y2n2+ykNLQqMoqklN9ICBT/KsvC1Gz6vqHbz2AXXGkG+Pm5rMWk/8Vjrr/mY9985Hi8DYzn1F09Nyw==", + "dev": true + }, + "node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", "dev": true, "engines": { - "node": ">=4" + "node": ">= 0.8" } }, - "node_modules/inquirer/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "node_modules/enhanced-resolve": { + "version": "5.15.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.15.0.tgz", + "integrity": "sha512-LXYT42KJ7lpIKECr2mAXIaMldcNCh/7E0KBKOu4KSfkHmP+mZmSs+8V5gBAqisWBy0OO4W5Oyys0GO1Y8KtdKg==", "dev": true, "dependencies": { - "color-convert": "^1.9.0" + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" }, "engines": { - "node": ">=4" + "node": ">=10.13.0" } }, - "node_modules/inquirer/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/env-ci": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/env-ci/-/env-ci-10.0.0.tgz", + "integrity": "sha512-U4xcd/utDYFgMh0yWj07R1H6L5fwhVbmxBCpnL0DbVSDZVnsC82HONw0wxtxNkIAcua3KtbomQvIk5xFZGAQJw==", "dev": true, "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" + "execa": "^8.0.0", + "java-properties": "^1.0.2" }, "engines": { - "node": ">=4" + "node": "^18.17 || >=20.6.1" } }, - "node_modules/inquirer/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "node_modules/env-ci/node_modules/execa": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", + "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==", "dev": true, "dependencies": { - "color-name": "1.1.3" + "cross-spawn": "^7.0.3", + "get-stream": "^8.0.1", + "human-signals": "^5.0.0", + "is-stream": "^3.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^5.1.0", + "onetime": "^6.0.0", + "signal-exit": "^4.1.0", + "strip-final-newline": "^3.0.0" + }, + "engines": { + "node": ">=16.17" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" } }, - "node_modules/inquirer/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "node_modules/inquirer/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "node_modules/env-ci/node_modules/get-stream": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", + "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==", "dev": true, "engines": { - "node": ">=4" + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/inquirer/node_modules/is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", + "node_modules/env-ci/node_modules/human-signals": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz", + "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==", "dev": true, "engines": { - "node": ">=4" + "node": ">=16.17.0" } }, - "node_modules/inquirer/node_modules/string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "node_modules/env-ci/node_modules/is-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", + "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", "dev": true, - "dependencies": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - }, "engines": { - "node": ">=4" + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/inquirer/node_modules/strip-ansi": { + "node_modules/env-ci/node_modules/mimic-fn": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", + "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", "dev": true, - "dependencies": { - "ansi-regex": "^3.0.0" - }, "engines": { - "node": ">=4" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/inquirer/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "node_modules/env-ci/node_modules/npm-run-path": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.3.0.tgz", + "integrity": "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==", "dev": true, "dependencies": { - "has-flag": "^3.0.0" + "path-key": "^4.0.0" }, "engines": { - "node": ">=4" + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/interpret": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-2.2.0.tgz", - "integrity": "sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw==", + "node_modules/env-ci/node_modules/onetime": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", + "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", "dev": true, + "dependencies": { + "mimic-fn": "^4.0.0" + }, "engines": { - "node": ">= 0.10" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/ipaddr.js": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.1.0.tgz", - "integrity": "sha512-LlbxQ7xKzfBusov6UMi4MFpEg0m+mAm9xyNGEduwXMEDuf4WfzB/RZwMVYEd7IKGvh4IUkEXYxtAVu9T3OelJQ==", + "node_modules/env-ci/node_modules/path-key": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", + "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", "dev": true, "engines": { - "node": ">= 10" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", - "dev": true - }, - "node_modules/is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "node_modules/env-ci/node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", "dev": true, - "dependencies": { - "binary-extensions": "^2.0.0" - }, "engines": { - "node": ">=8" + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/is-core-module": { - "version": "2.13.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", - "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", + "node_modules/env-ci/node_modules/strip-final-newline": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", + "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", "dev": true, - "dependencies": { - "hasown": "^2.0.0" + "engines": { + "node": ">=12" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/is-docker": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", - "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", + "node_modules/envinfo": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.11.0.tgz", + "integrity": "sha512-G9/6xF1FPbIw0TtalAMaVPpiq2aDEuKLXM314jPVAO9r2fo2a4BLqMNkmRS7O/xPPZ+COAhGIz3ETvHEV3eUcg==", "dev": true, "bin": { - "is-docker": "cli.js" + "envinfo": "dist/cli.js" }, "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=4" } }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "node_modules/error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", "dev": true, - "engines": { - "node": ">=0.10.0" + "dependencies": { + "is-arrayish": "^0.2.1" } }, - "node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "node_modules/es-module-lexer": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.4.1.tgz", + "integrity": "sha512-cXLGjP0c4T3flZJKQSuziYoq7MlT+rnvfZjfp7h+I7K9BNX54kP9nyWvdbwjQ4u1iWbOL4u96fgeZLToQlZC7w==", + "dev": true + }, + "node_modules/escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", "dev": true, "engines": { - "node": ">=8" + "node": ">=6" } }, - "node_modules/is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", + "dev": true + }, + "node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", "dev": true, - "dependencies": { - "is-extglob": "^2.1.1" - }, "engines": { - "node": ">=0.10.0" + "node": ">=0.8.0" } }, - "node_modules/is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "node_modules/eslint": { + "version": "4.19.1", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-4.19.1.tgz", + "integrity": "sha512-bT3/1x1EbZB7phzYu7vCr1v3ONuzDtX8WjuM9c0iYxe+cq+pwcKEoQjl7zd3RpC6YOLgnSy3cTN58M2jcoPDIQ==", "dev": true, + "dependencies": { + "ajv": "^5.3.0", + "babel-code-frame": "^6.22.0", + "chalk": "^2.1.0", + "concat-stream": "^1.6.0", + "cross-spawn": "^5.1.0", + "debug": "^3.1.0", + "doctrine": "^2.1.0", + "eslint-scope": "^3.7.1", + "eslint-visitor-keys": "^1.0.0", + "espree": "^3.5.4", + "esquery": "^1.0.0", + "esutils": "^2.0.2", + "file-entry-cache": "^2.0.0", + "functional-red-black-tree": "^1.0.1", + "glob": "^7.1.2", + "globals": "^11.0.1", + "ignore": "^3.3.3", + "imurmurhash": "^0.1.4", + "inquirer": "^3.0.6", + "is-resolvable": "^1.0.0", + "js-yaml": "^3.9.1", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.3.0", + "lodash": "^4.17.4", + "minimatch": "^3.0.2", + "mkdirp": "^0.5.1", + "natural-compare": "^1.4.0", + "optionator": "^0.8.2", + "path-is-inside": "^1.0.2", + "pluralize": "^7.0.0", + "progress": "^2.0.0", + "regexpp": "^1.0.1", + "require-uncached": "^1.0.3", + "semver": "^5.3.0", + "strip-ansi": "^4.0.0", + "strip-json-comments": "~2.0.1", + "table": "4.0.2", + "text-table": "~0.2.0" + }, + "bin": { + "eslint": "bin/eslint.js" + }, "engines": { - "node": ">=0.12.0" + "node": ">=4" } }, - "node_modules/is-obj": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", - "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", + "node_modules/eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, "engines": { - "node": ">=8" + "node": ">=8.0.0" } }, - "node_modules/is-plain-obj": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-3.0.0.tgz", - "integrity": "sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==", + "node_modules/eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", "dev": true, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=4" } }, - "node_modules/is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "node_modules/eslint/node_modules/ajv": { + "version": "5.5.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz", + "integrity": "sha512-Ajr4IcMXq/2QmMkEmSvxqfLN5zGmJ92gHXAeOXq1OekoH2rfDNsgdDoL2f7QaRCy7G/E6TpxBVdRuNraMztGHw==", "dev": true, "dependencies": { - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" + "co": "^4.6.0", + "fast-deep-equal": "^1.0.0", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.3.0" } }, - "node_modules/is-potential-custom-element-name": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", - "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==" - }, - "node_modules/is-resolvable": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz", - "integrity": "sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==", - "dev": true - }, - "node_modules/is-stream": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "node_modules/eslint/node_modules/ansi-regex": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz", + "integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==", "dev": true, "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=4" } }, - "node_modules/is-text-path": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-text-path/-/is-text-path-1.0.1.tgz", - "integrity": "sha512-xFuJpne9oFz5qDaodwmmG08e3CawH/2ZV8Qqza1Ko7Sk8POWbkRdwIoAWVhqvq0XeUzANEhKo2n0IXUGBm7A/w==", + "node_modules/eslint/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dev": true, "dependencies": { - "text-extensions": "^1.0.0" + "color-convert": "^1.9.0" }, "engines": { - "node": ">=0.10.0" + "node": ">=4" } }, - "node_modules/is-wsl": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", - "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "node_modules/eslint/node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", "dev": true, "dependencies": { - "is-docker": "^2.0.0" - }, - "engines": { - "node": ">=8" + "sprintf-js": "~1.0.2" } }, - "node_modules/isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", - "dev": true - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true - }, - "node_modules/isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", + "node_modules/eslint/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, "engines": { - "node": ">=0.10.0" + "node": ">=4" } }, - "node_modules/jest-worker": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", - "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", + "node_modules/eslint/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", "dev": true, "dependencies": { - "@types/node": "*", - "merge-stream": "^2.0.0", - "supports-color": "^8.0.0" - }, - "engines": { - "node": ">= 10.13.0" + "color-name": "1.1.3" } }, - "node_modules/js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "node_modules/eslint/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", "dev": true }, - "node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "node_modules/eslint/node_modules/cross-spawn": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", + "integrity": "sha512-pTgQJ5KC0d2hcY8eyL1IzlBPYjTkyH72XRZPnLyKus2mBfNjQs3klqbJU2VILqZryAZUt9JOb3h/mWMy23/f5A==", "dev": true, "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" + "lru-cache": "^4.0.1", + "shebang-command": "^1.2.0", + "which": "^1.2.9" } }, - "node_modules/jsdom": { - "version": "23.0.0", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-23.0.0.tgz", - "integrity": "sha512-cbL/UCtohJguhFC7c2/hgW6BeZCNvP7URQGnx9tSJRYKCdnfbfWOrtuLTMfiB2VxKsx5wPHVsh/J0aBy9lIIhQ==", + "node_modules/eslint/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, "dependencies": { - "cssstyle": "^3.0.0", - "data-urls": "^5.0.0", - "decimal.js": "^10.4.3", - "form-data": "^4.0.0", - "html-encoding-sniffer": "^4.0.0", - "http-proxy-agent": "^7.0.0", - "https-proxy-agent": "^7.0.2", - "is-potential-custom-element-name": "^1.0.1", - "nwsapi": "^2.2.7", - "parse5": "^7.1.2", - "rrweb-cssom": "^0.6.0", - "saxes": "^6.0.0", - "symbol-tree": "^3.2.4", - "tough-cookie": "^4.1.3", - "w3c-xmlserializer": "^5.0.0", - "webidl-conversions": "^7.0.0", - "whatwg-encoding": "^3.1.1", - "whatwg-mimetype": "^4.0.0", - "whatwg-url": "^14.0.0", - "ws": "^8.14.2", - "xml-name-validator": "^5.0.0" + "ms": "^2.1.1" + } + }, + "node_modules/eslint/node_modules/eslint-scope": { + "version": "3.7.3", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-3.7.3.tgz", + "integrity": "sha512-W+B0SvF4gamyCTmUc+uITPY0989iXVfKvhwtmJocTaYoc/3khEHmEmvfY/Gn9HA9VV75jrQECsHizkNw1b68FA==", + "dev": true, + "dependencies": { + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" }, "engines": { - "node": ">=18" - }, - "peerDependencies": { - "canvas": "^3.0.0" - }, - "peerDependenciesMeta": { - "canvas": { - "optional": true - } + "node": ">=4.0.0" } }, - "node_modules/json-parse-even-better-errors": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", - "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", - "dev": true - }, - "node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "node_modules/eslint/node_modules/fast-deep-equal": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz", + "integrity": "sha512-fueX787WZKCV0Is4/T2cyAdM4+x1S3MXXOAhavE1ys/W42SHAPacLTQhucja22QBYrfGw50M2sRiXPtTGv9Ymw==", "dev": true }, - "node_modules/json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", - "dev": true + "node_modules/eslint/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "engines": { + "node": ">=4" + } }, - "node_modules/jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "node_modules/eslint/node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", "dev": true, "dependencies": { - "universalify": "^2.0.0" + "argparse": "^1.0.7", + "esprima": "^4.0.0" }, - "optionalDependencies": { - "graceful-fs": "^4.1.6" + "bin": { + "js-yaml": "bin/js-yaml.js" } }, - "node_modules/jsonfile/node_modules/universalify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", - "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "node_modules/eslint/node_modules/json-schema-traverse": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz", + "integrity": "sha512-4JD/Ivzg7PoW8NzdrBSr3UFwC9mHgvI7Z6z3QGBsSHgKaRTUDmyZAAKJo2UbG1kUVfS9WS8bi36N49U1xw43DA==", + "dev": true + }, + "node_modules/eslint/node_modules/lru-cache": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", + "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", "dev": true, - "engines": { - "node": ">= 10.0.0" + "dependencies": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" } }, - "node_modules/jsonparse": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", - "integrity": "sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==", + "node_modules/eslint/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", "dev": true, - "engines": [ - "node >= 0.2.0" - ] + "bin": { + "semver": "bin/semver" + } }, - "node_modules/JSONStream": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz", - "integrity": "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==", + "node_modules/eslint/node_modules/shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==", "dev": true, "dependencies": { - "jsonparse": "^1.2.0", - "through": ">=2.2.7 <3" - }, - "bin": { - "JSONStream": "bin.js" + "shebang-regex": "^1.0.0" }, "engines": { - "node": "*" + "node": ">=0.10.0" } }, - "node_modules/kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "node_modules/eslint/node_modules/shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==", "dev": true, "engines": { "node": ">=0.10.0" } }, - "node_modules/launch-editor": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.6.1.tgz", - "integrity": "sha512-eB/uXmFVpY4zezmGp5XtU21kwo7GBbKB+EQ+UZeWtGb9yAM5xt/Evk+lYH3eRNAtId+ej4u7TYPFZ07w4s7rRw==", + "node_modules/eslint/node_modules/strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==", "dev": true, "dependencies": { - "picocolors": "^1.0.0", - "shell-quote": "^1.8.1" + "ansi-regex": "^3.0.0" + }, + "engines": { + "node": ">=4" } }, - "node_modules/levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==", + "node_modules/eslint/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", "dev": true, "dependencies": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" + "has-flag": "^3.0.0" }, "engines": { - "node": ">= 0.8.0" + "node": ">=4" } }, - "node_modules/lines-and-columns": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", - "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", - "dev": true - }, - "node_modules/loader-runner": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", - "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==", - "dev": true, - "engines": { - "node": ">=6.11.5" - } - }, - "node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "node_modules/eslint/node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", "dev": true, "dependencies": { - "p-locate": "^4.1.0" + "isexe": "^2.0.0" }, - "engines": { - "node": ">=8" + "bin": { + "which": "bin/which" } }, - "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true - }, - "node_modules/lodash.camelcase": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", - "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==", - "dev": true - }, - "node_modules/lodash.isfunction": { - "version": "3.0.9", - "resolved": "https://registry.npmjs.org/lodash.isfunction/-/lodash.isfunction-3.0.9.tgz", - "integrity": "sha512-AirXNj15uRIMMPihnkInB4i3NHeb4iBtNg9WRWuK2o31S+ePwwNmDPaTL3o7dTJ+VXNZim7rFs4rxN4YU1oUJw==", - "dev": true - }, - "node_modules/lodash.isplainobject": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", - "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==", - "dev": true - }, - "node_modules/lodash.kebabcase": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/lodash.kebabcase/-/lodash.kebabcase-4.1.1.tgz", - "integrity": "sha512-N8XRTIMMqqDgSy4VLKPnJ/+hpGZN+PHQiJnSenYqPaVV/NCqEogTnAdZLQiGKhxX+JCs8waWq2t1XHWKOmlY8g==", - "dev": true - }, - "node_modules/lodash.merge": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true - }, - "node_modules/lodash.mergewith": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.mergewith/-/lodash.mergewith-4.6.2.tgz", - "integrity": "sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ==", - "dev": true - }, - "node_modules/lodash.snakecase": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/lodash.snakecase/-/lodash.snakecase-4.1.1.tgz", - "integrity": "sha512-QZ1d4xoBHYUeuouhEq3lk3Uq7ldgyFXGBhg04+oRLnIz8o9T65Eh+8YdroUwn846zchkA9yDsDl5CVVaV2nqYw==", - "dev": true - }, - "node_modules/lodash.startcase": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.startcase/-/lodash.startcase-4.4.0.tgz", - "integrity": "sha512-+WKqsK294HMSc2jEbNgpHpd0JfIBhp7rEV4aqXWqFr6AlXov+SlcgB1Fv01y2kGe3Gc8nMW7VA0SrGuSkRfIEg==", - "dev": true - }, - "node_modules/lodash.uniq": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", - "integrity": "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==", - "dev": true - }, - "node_modules/lodash.upperfirst": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/lodash.upperfirst/-/lodash.upperfirst-4.3.1.tgz", - "integrity": "sha512-sReKOYJIJf74dhJONhU4e0/shzi1trVbSWDOhKYE5XV2O+H7Sb2Dihwuc7xWxVl+DgFPyTqIN3zMfT9cq5iWDg==", + "node_modules/eslint/node_modules/yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==", "dev": true }, - "node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "node_modules/espree": { + "version": "3.5.4", + "resolved": "https://registry.npmjs.org/espree/-/espree-3.5.4.tgz", + "integrity": "sha512-yAcIQxtmMiB/jL32dzEp2enBeidsB7xWPLNiw3IIkpVds1P+h7qF9YwJq1yUNzp2OKXgAprs4F61ih66UsoD1A==", "dev": true, "dependencies": { - "yallist": "^4.0.0" + "acorn": "^5.5.0", + "acorn-jsx": "^3.0.0" }, "engines": { - "node": ">=10" + "node": ">=0.10.0" } }, - "node_modules/make-error": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", - "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", - "dev": true - }, - "node_modules/map-obj": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.3.0.tgz", - "integrity": "sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==", + "node_modules/espree/node_modules/acorn": { + "version": "5.7.4", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.4.tgz", + "integrity": "sha512-1D++VG7BhrtvQpNbBzovKNc1FLGGEE/oGe7b9xJm/RFHMBeUaUGpluV9RLjZa47YFdPcDAenEYuq9pQPcMdLJg==", "dev": true, - "engines": { - "node": ">=8" + "bin": { + "acorn": "bin/acorn" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/media-typer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", - "dev": true, "engines": { - "node": ">= 0.6" + "node": ">=0.4.0" } }, - "node_modules/memfs": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.5.3.tgz", - "integrity": "sha512-UERzLsxzllchadvbPs5aolHh65ISpKpM+ccLbOJ8/vvpBKmAWf+la7dXFy7Mr0ySHbdHrFv5kGFCUHHe6GFEmw==", + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", "dev": true, - "dependencies": { - "fs-monkey": "^1.0.4" + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" }, "engines": { - "node": ">= 4.0.0" + "node": ">=4" } }, - "node_modules/meow": { - "version": "8.1.2", - "resolved": "https://registry.npmjs.org/meow/-/meow-8.1.2.tgz", - "integrity": "sha512-r85E3NdZ+mpYk1C6RjPFEMSE+s1iZMuHtsHAqY0DT3jZczl0diWUZ8g6oU7h0M9cD2EL+PzaYghhCLzR0ZNn5Q==", + "node_modules/esquery": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", + "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", "dev": true, "dependencies": { - "@types/minimist": "^1.2.0", - "camelcase-keys": "^6.2.2", - "decamelize-keys": "^1.1.0", - "hard-rejection": "^2.1.0", - "minimist-options": "4.1.0", - "normalize-package-data": "^3.0.0", - "read-pkg-up": "^7.0.1", - "redent": "^3.0.0", - "trim-newlines": "^3.0.0", - "type-fest": "^0.18.0", - "yargs-parser": "^20.2.3" + "estraverse": "^5.1.0" }, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=0.10" } }, - "node_modules/merge-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==", - "dev": true - }, - "node_modules/merge-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", - "dev": true - }, - "node_modules/methods": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", + "node_modules/esquery/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true, "engines": { - "node": ">= 0.6" + "node": ">=4.0" } }, - "node_modules/micromatch": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", - "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", "dev": true, "dependencies": { - "braces": "^3.0.2", - "picomatch": "^2.3.1" + "estraverse": "^5.2.0" }, "engines": { - "node": ">=8.6" + "node": ">=4.0" } }, - "node_modules/mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "node_modules/esrecurse/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true, - "bin": { - "mime": "cli.js" - }, "engines": { - "node": ">=4" + "node": ">=4.0" } }, - "node_modules/mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true, "engines": { - "node": ">= 0.6" + "node": ">=4.0" } }, - "node_modules/mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "dependencies": { - "mime-db": "1.52.0" - }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, "engines": { - "node": ">= 0.6" + "node": ">=0.10.0" } }, - "node_modules/mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/min-indent": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", - "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", "dev": true, "engines": { - "node": ">=4" + "node": ">= 0.6" } }, - "node_modules/minimalistic-assert": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", + "node_modules/eventemitter3": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", "dev": true }, - "node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "node_modules/events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, "engines": { - "node": "*" + "node": ">=0.8.x" } }, - "node_modules/minimist": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "node_modules/execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", "dev": true, + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sindresorhus/execa?sponsor=1" } }, - "node_modules/minimist-options": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-4.1.0.tgz", - "integrity": "sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==", + "node_modules/express": { + "version": "4.18.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", + "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", "dev": true, "dependencies": { - "arrify": "^1.0.1", - "is-plain-obj": "^1.1.0", - "kind-of": "^6.0.3" + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "1.20.1", + "content-disposition": "0.5.4", + "content-type": "~1.0.4", + "cookie": "0.5.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "2.0.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "1.2.0", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.7", + "qs": "6.11.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "0.18.0", + "serve-static": "1.15.0", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" }, "engines": { - "node": ">= 6" + "node": ">= 0.10.0" } }, - "node_modules/minimist-options/node_modules/is-plain-obj": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", - "integrity": "sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==", + "node_modules/express/node_modules/array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", + "dev": true + }, + "node_modules/express/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, - "engines": { - "node": ">=0.10.0" + "dependencies": { + "ms": "2.0.0" } }, - "node_modules/mkdirp": { - "version": "0.5.6", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", - "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "node_modules/express/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + }, + "node_modules/external-editor": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-2.2.0.tgz", + "integrity": "sha512-bSn6gvGxKt+b7+6TKEv1ZycHleA7aHhRHyAqJyp5pbUFuYYNIzpZnQDk7AsYckyWdEnTeAnay0aCy2aV6iTk9A==", "dev": true, "dependencies": { - "minimist": "^1.2.6" + "chardet": "^0.4.0", + "iconv-lite": "^0.4.17", + "tmp": "^0.0.33" }, - "bin": { - "mkdirp": "bin/cmd.js" + "engines": { + "node": ">=0.12" } }, - "node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "node_modules/multicast-dns": { - "version": "7.2.5", - "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-7.2.5.tgz", - "integrity": "sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg==", + "node_modules/external-editor/node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", "dev": true, "dependencies": { - "dns-packet": "^5.2.2", - "thunky": "^1.0.2" + "safer-buffer": ">= 2.1.2 < 3" }, - "bin": { - "multicast-dns": "cli.js" + "engines": { + "node": ">=0.10.0" } }, - "node_modules/mute-stream": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", - "integrity": "sha512-r65nCZhrbXXb6dXOACihYApHw2Q6pV0M3V0PSxd74N0+D8nzAdEAITq2oAjA1jVnKI+tGvEBUpqiMh0+rW6zDQ==", - "dev": true - }, - "node_modules/natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", "dev": true }, - "node_modules/negotiator": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", - "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "node_modules/fast-glob": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", + "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", "dev": true, + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, "engines": { - "node": ">= 0.6" + "node": ">=8.6.0" } }, - "node_modules/neo-async": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", - "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", "dev": true }, - "node_modules/node-forge": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz", - "integrity": "sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==", + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true + }, + "node_modules/fastest-levenshtein": { + "version": "1.0.16", + "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz", + "integrity": "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==", "dev": true, "engines": { - "node": ">= 6.13.0" + "node": ">= 4.9.1" } }, - "node_modules/node-releases": { - "version": "2.0.14", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", - "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==", - "dev": true + "node_modules/fastq": { + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", + "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", + "dev": true, + "dependencies": { + "reusify": "^1.0.4" + } }, - "node_modules/normalize-package-data": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.3.tgz", - "integrity": "sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==", + "node_modules/faye-websocket": { + "version": "0.11.4", + "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz", + "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==", "dev": true, "dependencies": { - "hosted-git-info": "^4.0.1", - "is-core-module": "^2.5.0", - "semver": "^7.3.4", - "validate-npm-package-license": "^3.0.1" + "websocket-driver": ">=0.5.1" }, "engines": { - "node": ">=10" + "node": ">=0.8.0" } }, - "node_modules/normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "node_modules/figures": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", + "integrity": "sha512-Oa2M9atig69ZkfwiApY8F2Yy+tzMbazyvqv21R0NsSC8floSOC09BbT1ITWAdoMGQvJ/aZnR1KMwdx9tvHnTNA==", "dev": true, + "dependencies": { + "escape-string-regexp": "^1.0.5" + }, "engines": { - "node": ">=0.10.0" + "node": ">=4" } }, - "node_modules/npm-run-path": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", - "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "node_modules/file-entry-cache": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-2.0.0.tgz", + "integrity": "sha512-uXP/zGzxxFvFfcZGgBIwotm+Tdc55ddPAzF7iHshP4YGaXMww7rSF9peD9D1sui5ebONg5UobsZv+FfgEpGv/w==", "dev": true, "dependencies": { - "path-key": "^3.0.0" + "flat-cache": "^1.2.1", + "object-assign": "^4.0.1" }, - "engines": { - "node": ">=8" - } - }, - "node_modules/nwsapi": { - "version": "2.2.9", - "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.9.tgz", - "integrity": "sha512-2f3F0SEEer8bBu0dsNCFF50N0cTThV1nWFYcEYFZttdW0lDAoybv9cQoK7X7/68Z89S7FoRrVjP1LPX4XRf9vg==" - }, - "node_modules/object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "dev": true, "engines": { "node": ">=0.10.0" } }, - "node_modules/object-inspect": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", - "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", - "dev": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/obuf": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", - "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==", - "dev": true - }, - "node_modules/on-finished": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", - "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", "dev": true, "dependencies": { - "ee-first": "1.1.1" + "to-regex-range": "^5.0.1" }, "engines": { - "node": ">= 0.8" + "node": ">=8" } }, - "node_modules/on-headers": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", - "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", + "node_modules/finalhandler": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", + "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", "dev": true, + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "statuses": "2.0.1", + "unpipe": "~1.0.0" + }, "engines": { "node": ">= 0.8" } }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "node_modules/finalhandler/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, "dependencies": { - "wrappy": "1" + "ms": "2.0.0" } }, - "node_modules/onetime": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "node_modules/finalhandler/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + }, + "node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", "dev": true, "dependencies": { - "mimic-fn": "^2.1.0" + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" }, "engines": { - "node": ">=6" + "node": ">=8" + } + }, + "node_modules/find-up-simple": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/find-up-simple/-/find-up-simple-1.0.0.tgz", + "integrity": "sha512-q7Us7kcjj2VMePAa02hDAF6d+MzsdsAWEwYyOpwUtlerRBkOEPBCRZrAV4XfcSN8fHAgaD0hP7miwoay6DCprw==", + "dev": true, + "engines": { + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/open": { - "version": "8.4.2", - "resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz", - "integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==", + "node_modules/find-versions": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/find-versions/-/find-versions-5.1.0.tgz", + "integrity": "sha512-+iwzCJ7C5v5KgcBuueqVoNiHVoQpwiUK5XFLjf0affFTep+Wcw93tPvmb8tqujDNmzhBDPddnWV/qgWSXgq+Hg==", "dev": true, "dependencies": { - "define-lazy-prop": "^2.0.0", - "is-docker": "^2.1.1", - "is-wsl": "^2.2.0" + "semver-regex": "^4.0.5" }, "engines": { "node": ">=12" @@ -4660,1678 +4603,1775 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/optionator": { - "version": "0.8.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", - "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", + "node_modules/flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", "dev": true, - "dependencies": { - "deep-is": "~0.1.3", - "fast-levenshtein": "~2.0.6", - "levn": "~0.3.0", - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2", - "word-wrap": "~1.2.3" - }, - "engines": { - "node": ">= 0.8.0" + "bin": { + "flat": "cli.js" } }, - "node_modules/os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", + "node_modules/flat-cache": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.3.4.tgz", + "integrity": "sha512-VwyB3Lkgacfik2vhqR4uv2rvebqmDvFu4jlN/C1RzWoJEo8I7z4Q404oiqYCkq41mni8EzQnm95emU9seckwtg==", "dev": true, + "dependencies": { + "circular-json": "^0.3.1", + "graceful-fs": "^4.1.2", + "rimraf": "~2.6.2", + "write": "^0.2.1" + }, "engines": { "node": ">=0.10.0" } }, - "node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "node_modules/flat-cache/node_modules/rimraf": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", + "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", "dev": true, "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" + "glob": "^7.1.3" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "bin": { + "rimraf": "bin.js" } }, - "node_modules/p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "node_modules/follow-redirects": { + "version": "1.15.3", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.3.tgz", + "integrity": "sha512-1VzOtuEM8pC9SFU1E+8KfTjZyMztRsgEfwQl44z8A25uy13jSzTj6dyK2Df52iV0vgHCfBwLhDWevLn95w5v6Q==", "dev": true, - "dependencies": { - "p-limit": "^2.2.0" - }, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], "engines": { - "node": ">=8" + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } } }, - "node_modules/p-retry": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-4.6.2.tgz", - "integrity": "sha512-312Id396EbJdvRONlngUx0NydfrIQ5lsYu0znKVUzVvArzEIt08V1qhtyESbGVd1FGX7UKtiFp5uwKZdM8wIuQ==", - "dev": true, + "node_modules/form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", "dependencies": { - "@types/retry": "0.12.0", - "retry": "^0.13.1" + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" }, "engines": { - "node": ">=8" + "node": ">= 6" } }, - "node_modules/p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "node_modules/forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", "dev": true, "engines": { - "node": ">=6" + "node": ">= 0.6" } }, - "node_modules/parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", "dev": true, - "dependencies": { - "callsites": "^3.0.0" - }, "engines": { - "node": ">=6" + "node": ">= 0.6" } }, - "node_modules/parse-json": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", - "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "node_modules/from2": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", + "integrity": "sha512-OMcX/4IC/uqEPVgGeyfN22LJk6AZrMkRZHxcHBMBvHScDGgwTm2GT2Wkgtocyd3JfZffjj2kYUDXXII0Fk9W0g==", "dev": true, "dependencies": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-even-better-errors": "^2.3.0", - "lines-and-columns": "^1.1.6" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "inherits": "^2.0.1", + "readable-stream": "^2.0.0" } }, - "node_modules/parse5": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz", - "integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==", + "node_modules/from2/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dev": true, "dependencies": { - "entities": "^4.4.0" - }, - "funding": { - "url": "https://github.com/inikulin/parse5?sponsor=1" + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" } }, - "node_modules/parseurl": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", - "dev": true, - "engines": { - "node": ">= 0.8" - } + "node_modules/from2/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true }, - "node_modules/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "node_modules/from2/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "dev": true, - "engines": { - "node": ">=8" + "dependencies": { + "safe-buffer": "~5.1.0" } }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "node_modules/fs-extra": { + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz", + "integrity": "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==", "dev": true, + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, "engines": { - "node": ">=0.10.0" + "node": ">=14.14" } }, - "node_modules/path-is-inside": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", - "integrity": "sha512-DUWJr3+ULp4zXmol/SZkFf3JGsS9/SIv+Y3Rt93/UjPpDpklB5f1er4O3POIbUuUJ3FXgqte2Q7SrU6zAqwk8w==", - "dev": true - }, - "node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "node_modules/fs-extra/node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", "dev": true, "engines": { - "node": ">=8" + "node": ">= 10.0.0" } }, - "node_modules/path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "node_modules/fs-monkey": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.0.5.tgz", + "integrity": "sha512-8uMbBjrhzW76TYgEV27Y5E//W2f/lTFmx78P2w19FZSxarhI/798APGQyuGCwmkNxgwGRhrLfvWyLBvNtuOmew==", "dev": true }, - "node_modules/path-to-regexp": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==", + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", "dev": true }, - "node_modules/path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], "engines": { - "node": ">=8" + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, - "node_modules/picocolors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==", "dev": true }, - "node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", "dev": true, "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" + "node": "6.* || 8.* || >= 10.*" } }, - "node_modules/pkg-dir": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", - "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "node_modules/get-intrinsic": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.2.tgz", + "integrity": "sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA==", "dev": true, "dependencies": { - "find-up": "^4.0.0" + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" }, - "engines": { - "node": ">=8" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/pluralize": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-7.0.0.tgz", - "integrity": "sha512-ARhBOdzS3e41FbkW/XWrTEtukqqLoK5+Z/4UeDaLuSW+39JPeFgs4gCGqsrJHVZX0fUrx//4OF0K1CUGwlIFow==", + "node_modules/get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", "dev": true, "engines": { - "node": ">=4" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/prelude-ls": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==", + "node_modules/git-log-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/git-log-parser/-/git-log-parser-1.2.1.tgz", + "integrity": "sha512-PI+sPDvHXNPl5WNOErAK05s3j0lgwUzMN6o8cyQrDaKfT3qd7TmNJKeXX+SknI5I0QhG5fVPAEwSY4tRGDtYoQ==", "dev": true, - "engines": { - "node": ">= 0.8.0" + "license": "MIT", + "dependencies": { + "argv-formatter": "~1.0.0", + "spawn-error-forwarder": "~1.0.0", + "split2": "~1.0.0", + "stream-combiner2": "~1.1.1", + "through2": "~2.0.0", + "traverse": "0.6.8" } }, - "node_modules/process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true - }, - "node_modules/progress": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "node_modules/git-log-parser/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", "dev": true, - "engines": { - "node": ">=0.4.0" + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" } }, - "node_modules/proxy-addr": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", - "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "node_modules/git-log-parser/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true, + "license": "MIT" + }, + "node_modules/git-log-parser/node_modules/split2": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/split2/-/split2-1.0.0.tgz", + "integrity": "sha512-NKywug4u4pX/AZBB1FCPzZ6/7O+Xhz1qMVbzTvvKvikjO99oPN87SkK08mEY9P63/5lWjK+wgOOgApnTg5r6qg==", "dev": true, + "license": "ISC", "dependencies": { - "forwarded": "0.2.0", - "ipaddr.js": "1.9.1" - }, - "engines": { - "node": ">= 0.10" + "through2": "~2.0.0" } }, - "node_modules/proxy-addr/node_modules/ipaddr.js": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", - "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "node_modules/git-log-parser/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "dev": true, - "engines": { - "node": ">= 0.10" + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.1.0" } }, - "node_modules/pseudomap": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", - "integrity": "sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==", - "dev": true - }, - "node_modules/psl": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", - "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==" + "node_modules/git-log-parser/node_modules/through2": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", + "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" + } }, - "node_modules/punycode": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", - "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "node_modules/git-raw-commits": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/git-raw-commits/-/git-raw-commits-2.0.11.tgz", + "integrity": "sha512-VnctFhw+xfj8Va1xtfEqCUD2XDrbAPSJx+hSrE5K7fGdjZruW7XV+QOrN7LF/RJyvspRiD2I0asWsxFp0ya26A==", + "dev": true, + "dependencies": { + "dargs": "^7.0.0", + "lodash": "^4.17.15", + "meow": "^8.0.0", + "split2": "^3.0.0", + "through2": "^4.0.0" + }, + "bin": { + "git-raw-commits": "cli.js" + }, "engines": { - "node": ">=6" + "node": ">=10" } }, - "node_modules/qs": { - "version": "6.11.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", - "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", "dev": true, "dependencies": { - "side-channel": "^1.0.4" + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" }, "engines": { - "node": ">=0.6" + "node": "*" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/querystringify": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", - "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==" - }, - "node_modules/quick-lru": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz", - "integrity": "sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==", + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, "engines": { - "node": ">=8" + "node": ">= 6" } }, - "node_modules/randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "node_modules/glob-to-regexp": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", + "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", + "dev": true + }, + "node_modules/global-dirs": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-0.1.1.tgz", + "integrity": "sha512-NknMLn7F2J7aflwFOlGdNIuCDpN3VGoSoB+aap3KABFWbHVn1TCgFC+np23J8W2BiZbjfEw3BFBycSMv1AFblg==", "dev": true, "dependencies": { - "safe-buffer": "^5.1.0" + "ini": "^1.3.4" + }, + "engines": { + "node": ">=4" } }, - "node_modules/range-parser": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", "dev": true, "engines": { - "node": ">= 0.6" + "node": ">=4" } }, - "node_modules/raw-body": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", - "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", + "node_modules/globby": { + "version": "14.0.2", + "resolved": "https://registry.npmjs.org/globby/-/globby-14.0.2.tgz", + "integrity": "sha512-s3Fq41ZVh7vbbe2PN3nrW7yC7U7MFVc5c98/iTl9c2GawNMKx/J648KQRW6WKkuU8GIbbh2IXfIRQjOZnXcTnw==", "dev": true, "dependencies": { - "bytes": "3.1.2", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" + "@sindresorhus/merge-streams": "^2.1.0", + "fast-glob": "^3.3.2", + "ignore": "^5.2.4", + "path-type": "^5.0.0", + "slash": "^5.1.0", + "unicorn-magic": "^0.1.0" }, "engines": { - "node": ">= 0.8" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/raw-body/node_modules/bytes": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "node_modules/globby/node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", "dev": true, "engines": { - "node": ">= 0.8" + "node": ">= 4" } }, - "node_modules/raw-body/node_modules/iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "node_modules/globby/node_modules/path-type": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-5.0.0.tgz", + "integrity": "sha512-5HviZNaZcfqP95rwpv+1HDgUamezbqdSYTyzjTvwtJSnIH+3vnbmWsItli8OFEndS984VT55M3jduxZbX351gg==", "dev": true, - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3" - }, "engines": { - "node": ">=0.10.0" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/read-pkg": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", - "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "node_modules/gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", "dev": true, "dependencies": { - "@types/normalize-package-data": "^2.4.0", - "normalize-package-data": "^2.5.0", - "parse-json": "^5.0.0", - "type-fest": "^0.6.0" + "get-intrinsic": "^1.1.3" }, - "engines": { - "node": ">=8" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/read-pkg-up": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", - "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true + }, + "node_modules/handle-thing": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz", + "integrity": "sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==", + "dev": true + }, + "node_modules/handlebars": { + "version": "4.7.8", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.8.tgz", + "integrity": "sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==", "dev": true, "dependencies": { - "find-up": "^4.1.0", - "read-pkg": "^5.2.0", - "type-fest": "^0.8.1" + "minimist": "^1.2.5", + "neo-async": "^2.6.2", + "source-map": "^0.6.1", + "wordwrap": "^1.0.0" + }, + "bin": { + "handlebars": "bin/handlebars" }, "engines": { - "node": ">=8" + "node": ">=0.4.7" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "optionalDependencies": { + "uglify-js": "^3.1.4" } }, - "node_modules/read-pkg-up/node_modules/type-fest": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", - "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "node_modules/hard-rejection": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz", + "integrity": "sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==", "dev": true, "engines": { - "node": ">=8" + "node": ">=6" } }, - "node_modules/read-pkg/node_modules/hosted-git-info": { - "version": "2.8.9", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", - "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", - "dev": true - }, - "node_modules/read-pkg/node_modules/normalize-package-data": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", - "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "node_modules/has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha512-C8vBJ8DwUCx19vhm7urhTuUsr4/IyP6l4VzNQDv+ryHQObW3TTTp9yB68WpYgRe2bbaGuZ/se74IqFeVnMnLZg==", "dev": true, "dependencies": { - "hosted-git-info": "^2.1.4", - "resolve": "^1.10.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" + "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" } }, - "node_modules/read-pkg/node_modules/semver": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "node_modules/has-ansi/node_modules/ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", "dev": true, - "bin": { - "semver": "bin/semver" + "engines": { + "node": ">=0.10.0" } }, - "node_modules/read-pkg/node_modules/type-fest": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", - "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true, "engines": { "node": ">=8" } }, - "node_modules/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "node_modules/has-property-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz", + "integrity": "sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg==", "dev": true, "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" + "get-intrinsic": "^1.2.2" }, - "engines": { - "node": ">= 6" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "node_modules/has-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", + "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", "dev": true, - "dependencies": { - "picomatch": "^2.2.1" - }, "engines": { - "node": ">=8.10.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/rechoir": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.7.1.tgz", - "integrity": "sha512-/njmZ8s1wVeR6pjTZ+0nCnv8SpZNRMT2D1RLOJQESlYFDBvwpTA4KWJpZ+sBJ4+vhjILRcK7JIFdGCdxEAAitg==", + "node_modules/has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", "dev": true, - "dependencies": { - "resolve": "^1.9.0" - }, "engines": { - "node": ">= 0.10" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/redent": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", - "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", + "node_modules/hasown": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz", + "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==", "dev": true, "dependencies": { - "indent-string": "^4.0.0", - "strip-indent": "^3.0.0" + "function-bind": "^1.1.2" }, "engines": { - "node": ">=8" + "node": ">= 0.4" } }, - "node_modules/regexpp": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-1.1.0.tgz", - "integrity": "sha512-LOPw8FpgdQF9etWMaAfG/WRthIdXJGYp4mJ2Jgn/2lpkbod9jPn0t9UqN7AxBOKNfzRbYyVfgc7Vk4t/MpnXgw==", + "node_modules/hook-std": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/hook-std/-/hook-std-3.0.0.tgz", + "integrity": "sha512-jHRQzjSDzMtFy34AGj1DN+vq54WVuhSvKgrHf0OMiFQTwDD4L/qqofVEWjLOBMTn5+lCD3fPg32W9yOfnEJTTw==", "dev": true, + "license": "MIT", "engines": { - "node": ">=4.0.0" + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "node_modules/hosted-git-info": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz", + "integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==", "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, "engines": { - "node": ">=0.10.0" + "node": ">=10" } }, - "node_modules/require-from-string": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", - "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/require-uncached": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz", - "integrity": "sha512-Xct+41K3twrbBHdxAgMoOS+cNcoqIjfM2/VxBF4LL2hVph7YsF8VSKyQ3BDFZwEVbok9yeDl2le/qo0S77WG2w==", + "node_modules/hpack.js": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz", + "integrity": "sha512-zJxVehUdMGIKsRaNt7apO2Gqp0BdqW5yaiGHXXmbpvxgBYVZnAql+BJb4RO5ad2MgpbZKn5G6nMnegrH1FcNYQ==", "dev": true, "dependencies": { - "caller-path": "^0.1.0", - "resolve-from": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" + "inherits": "^2.0.1", + "obuf": "^1.0.0", + "readable-stream": "^2.0.1", + "wbuf": "^1.1.0" } }, - "node_modules/require-uncached/node_modules/resolve-from": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-1.0.1.tgz", - "integrity": "sha512-kT10v4dhrlLNcnO084hEjvXCI1wUG9qZLoz2RogxqDQQYy7IxjI/iMUkOtQTNEh6rzHxvdQWHsJyel1pKOVCxg==", + "node_modules/hpack.js/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", "dev": true, - "engines": { - "node": ">=0.10.0" + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" } }, - "node_modules/requires-port": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", - "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==" + "node_modules/hpack.js/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true }, - "node_modules/resolve": { - "version": "1.22.8", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", - "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", + "node_modules/hpack.js/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "dev": true, "dependencies": { - "is-core-module": "^2.13.0", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - }, - "bin": { - "resolve": "bin/resolve" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "safe-buffer": "~5.1.0" } }, - "node_modules/resolve-cwd": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", - "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", - "dev": true, + "node_modules/html-encoding-sniffer": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-4.0.0.tgz", + "integrity": "sha512-Y22oTqIU4uuPgEemfz7NDJz6OeKf12Lsu+QC+s3BVpda64lTiMYCyGwg5ki4vFxkMwQdeZDl2adZoqUgdFuTgQ==", "dependencies": { - "resolve-from": "^5.0.0" + "whatwg-encoding": "^3.1.1" }, "engines": { - "node": ">=8" + "node": ">=18" } }, - "node_modules/resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "node_modules/html-entities": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.4.0.tgz", + "integrity": "sha512-igBTJcNNNhvZFRtm8uA6xMY6xYleeDwn3PeBCkDz7tHttv4F2hsDI2aPgNERWzvRcNYHNT3ymRaQzllmXj4YsQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/mdevils" + }, + { + "type": "patreon", + "url": "https://patreon.com/mdevils" + } + ] + }, + "node_modules/http-deceiver": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz", + "integrity": "sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw==", + "dev": true + }, + "node_modules/http-errors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", "dev": true, + "dependencies": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + }, "engines": { - "node": ">=8" + "node": ">= 0.8" } }, - "node_modules/resolve-global": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/resolve-global/-/resolve-global-1.0.0.tgz", - "integrity": "sha512-zFa12V4OLtT5XUX/Q4VLvTfBf+Ok0SPc1FNGM/z9ctUdiU618qwKpWnd0CHs3+RqROfyEg/DhuHbMWYqcgljEw==", + "node_modules/http-parser-js": { + "version": "0.5.8", + "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.8.tgz", + "integrity": "sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q==", + "dev": true + }, + "node_modules/http-proxy": { + "version": "1.18.1", + "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", + "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", "dev": true, "dependencies": { - "global-dirs": "^0.1.1" + "eventemitter3": "^4.0.0", + "follow-redirects": "^1.0.0", + "requires-port": "^1.0.0" }, "engines": { - "node": ">=8" + "node": ">=8.0.0" } }, - "node_modules/restore-cursor": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", - "integrity": "sha512-6IzJLuGi4+R14vwagDHX+JrXmPVtPpn4mffDJ1UdR7/Edm87fl6yi8mMBIVvFtJaNTUvjughmW4hwLhRG7gC1Q==", - "dev": true, + "node_modules/http-proxy-agent": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", + "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", "dependencies": { - "onetime": "^2.0.0", - "signal-exit": "^3.0.2" + "agent-base": "^7.1.0", + "debug": "^4.3.4" }, "engines": { - "node": ">=4" + "node": ">= 14" } }, - "node_modules/restore-cursor/node_modules/mimic-fn": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", - "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", + "node_modules/http-proxy-middleware": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.6.tgz", + "integrity": "sha512-ya/UeJ6HVBYxrgYotAZo1KvPWlgB48kUJLDePFeneHsVujFaW5WNj2NgWCAE//B1Dl02BIfYlpNgBy8Kf8Rjmw==", "dev": true, + "dependencies": { + "@types/http-proxy": "^1.17.8", + "http-proxy": "^1.18.1", + "is-glob": "^4.0.1", + "is-plain-obj": "^3.0.0", + "micromatch": "^4.0.2" + }, "engines": { - "node": ">=4" + "node": ">=12.0.0" + }, + "peerDependencies": { + "@types/express": "^4.17.13" + }, + "peerDependenciesMeta": { + "@types/express": { + "optional": true + } } }, - "node_modules/restore-cursor/node_modules/onetime": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", - "integrity": "sha512-oyyPpiMaKARvvcgip+JV+7zci5L8D1W9RZIz2l1o08AM3pfspitVWnPt3mzHcBPp12oYMTy0pqrFs/C+m3EwsQ==", - "dev": true, + "node_modules/https-proxy-agent": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.4.tgz", + "integrity": "sha512-wlwpilI7YdjSkWaQ/7omYBMTliDcmCN8OLihO6I9B86g06lMyAoqgoDpV0XqoaPOKj+0DIdAvnsWfyAAhmimcg==", "dependencies": { - "mimic-fn": "^1.0.0" + "agent-base": "^7.0.2", + "debug": "4" }, "engines": { - "node": ">=4" + "node": ">= 14" } }, - "node_modules/retry": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", - "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", + "node_modules/human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", "dev": true, "engines": { - "node": ">= 4" + "node": ">=10.17.0" } }, - "node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "node_modules/husky": { + "version": "9.1.6", + "resolved": "https://registry.npmjs.org/husky/-/husky-9.1.6.tgz", + "integrity": "sha512-sqbjZKK7kf44hfdE94EoX8MZNk0n7HeW37O4YrVGCF4wzgQjp+akPAkfUK5LZ6KuR/6sqeAVuXHji+RzQgOn5A==", "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, + "license": "MIT", "bin": { - "rimraf": "bin.js" + "husky": "bin.js" + }, + "engines": { + "node": ">=18" }, "funding": { - "url": "https://github.com/sponsors/isaacs" + "url": "https://github.com/sponsors/typicode" } }, - "node_modules/rrweb-cssom": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.6.0.tgz", - "integrity": "sha512-APM0Gt1KoXBz0iIkkdB/kfvGOwC4UuJFeG/c+yV7wSc7q96cG/kJ0HiYCnzivD9SB53cLV1MlHFNfOuPaadYSw==" - }, - "node_modules/run-async": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", - "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==", - "dev": true, + "node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, "engines": { - "node": ">=0.12.0" + "node": ">=0.10.0" } }, - "node_modules/rx-lite": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-4.0.8.tgz", - "integrity": "sha512-Cun9QucwK6MIrp3mry/Y7hqD1oFqTYLQ4pGxaHTjIdaFDWRGGLikqp6u8LcWJnzpoALg9hap+JGk8sFIUuEGNA==", + "node_modules/ignore": { + "version": "3.3.10", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.10.tgz", + "integrity": "sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug==", "dev": true }, - "node_modules/rx-lite-aggregates": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/rx-lite-aggregates/-/rx-lite-aggregates-4.0.8.tgz", - "integrity": "sha512-3xPNZGW93oCjiO7PtKxRK6iOVYBWBvtf9QHDfU23Oc+dLIQmAV//UnyXV/yihv81VS/UqoQPk4NegS8EFi55Hg==", + "node_modules/import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", "dev": true, "dependencies": { - "rx-lite": "*" + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "node_modules/import-fresh/node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] + "engines": { + "node": ">=4" + } }, - "node_modules/safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + "node_modules/import-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/import-from/-/import-from-4.0.0.tgz", + "integrity": "sha512-P9J71vT5nLlDeV8FHs5nNxaLbrpfAV5cF5srvbZfpwpcJoM/xZR3hiv+q+SAnuSmuGbXMWud063iIMx/V/EWZQ==", + "dev": true, + "engines": { + "node": ">=12.2" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, - "node_modules/saxes": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz", - "integrity": "sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==", + "node_modules/import-from-esm": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/import-from-esm/-/import-from-esm-1.3.4.tgz", + "integrity": "sha512-7EyUlPFC0HOlBDpUFGfYstsU7XHxZJKAAMzCT8wZ0hMW7b+hG51LIKTDcsgtz8Pu6YC0HqRVbX+rVUtsGMUKvg==", + "dev": true, "dependencies": { - "xmlchars": "^2.2.0" + "debug": "^4.3.4", + "import-meta-resolve": "^4.0.0" }, "engines": { - "node": ">=v12.22.7" + "node": ">=16.20" } }, - "node_modules/schema-utils": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", - "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", + "node_modules/import-local": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", + "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==", "dev": true, "dependencies": { - "@types/json-schema": "^7.0.8", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.0.0" + }, + "bin": { + "import-local-fixture": "fixtures/cli.js" }, "engines": { - "node": ">= 10.13.0" + "node": ">=8" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/select-hose": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", - "integrity": "sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg==", - "dev": true + "node_modules/import-meta-resolve": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/import-meta-resolve/-/import-meta-resolve-4.1.0.tgz", + "integrity": "sha512-I6fiaX09Xivtk+THaMfAwnA3MVA5Big1WHF1Dfx9hFuvNIWpXnorlkzhcQf6ehrqQiiZECRt1poOAkPmer3ruw==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } }, - "node_modules/selfsigned": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-2.4.1.tgz", - "integrity": "sha512-th5B4L2U+eGLq1TVh7zNRGBapioSORUeymIydxgFpwww9d2qyKvtuPU2jJuHvYAwwqi2Y596QBL3eEqcPEYL8Q==", + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", "dev": true, - "dependencies": { - "@types/node-forge": "^1.3.0", - "node-forge": "^1" - }, "engines": { - "node": ">=10" + "node": ">=0.8.19" } }, - "node_modules/semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "node_modules/indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, "engines": { - "node": ">=10" + "node": ">=8" } }, - "node_modules/send": { - "version": "0.18.0", - "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", - "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", + "node_modules/index-to-position": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/index-to-position/-/index-to-position-0.1.2.tgz", + "integrity": "sha512-MWDKS3AS1bGCHLBA2VLImJz42f7bJh8wQsTGCzI3j519/CASStoDONUBVz2I/VID0MpiX3SGSnbOD2xUalbE5g==", "dev": true, - "dependencies": { - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "mime": "1.6.0", - "ms": "2.1.3", - "on-finished": "2.4.1", - "range-parser": "~1.2.1", - "statuses": "2.0.1" - }, "engines": { - "node": ">= 0.8.0" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/send/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", "dev": true, "dependencies": { - "ms": "2.0.0" + "once": "^1.3.0", + "wrappy": "1" } }, - "node_modules/send/node_modules/debug/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true }, - "node_modules/send/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", "dev": true }, - "node_modules/serialize-javascript": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.1.tgz", - "integrity": "sha512-owoXEFjWRllis8/M1Q+Cw5k8ZH40e3zhp/ovX+Xr/vi1qj6QesbyXXViFbpNvWvPNAD62SutwEXavefrLJWj7w==", + "node_modules/inquirer": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-3.3.0.tgz", + "integrity": "sha512-h+xtnyk4EwKvFWHrUYsWErEVR+igKtLdchu+o0Z1RL7VU/jVMFbYir2bp6bAj8efFNxWqHX0dIss6fJQ+/+qeQ==", "dev": true, "dependencies": { - "randombytes": "^2.1.0" + "ansi-escapes": "^3.0.0", + "chalk": "^2.0.0", + "cli-cursor": "^2.1.0", + "cli-width": "^2.0.0", + "external-editor": "^2.0.4", + "figures": "^2.0.0", + "lodash": "^4.3.0", + "mute-stream": "0.0.7", + "run-async": "^2.2.0", + "rx-lite": "^4.0.8", + "rx-lite-aggregates": "^4.0.8", + "string-width": "^2.1.0", + "strip-ansi": "^4.0.0", + "through": "^2.3.6" } }, - "node_modules/serve-index": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz", - "integrity": "sha512-pXHfKNP4qujrtteMrSBb0rc8HJ9Ms/GrXwcUtUtD5s4ewDJI8bT3Cz2zTVRMKtri49pLx2e0Ya8ziP5Ya2pZZw==", + "node_modules/inquirer/node_modules/ansi-regex": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz", + "integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==", "dev": true, - "dependencies": { - "accepts": "~1.3.4", - "batch": "0.6.1", - "debug": "2.6.9", - "escape-html": "~1.0.3", - "http-errors": "~1.6.2", - "mime-types": "~2.1.17", - "parseurl": "~1.3.2" - }, "engines": { - "node": ">= 0.8.0" + "node": ">=4" } }, - "node_modules/serve-index/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "node_modules/inquirer/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dev": true, "dependencies": { - "ms": "2.0.0" + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" } }, - "node_modules/serve-index/node_modules/depd": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", - "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==", + "node_modules/inquirer/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, "engines": { - "node": ">= 0.6" + "node": ">=4" } }, - "node_modules/serve-index/node_modules/http-errors": { - "version": "1.6.3", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", - "integrity": "sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A==", + "node_modules/inquirer/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", "dev": true, "dependencies": { - "depd": "~1.1.2", - "inherits": "2.0.3", - "setprototypeof": "1.1.0", - "statuses": ">= 1.4.0 < 2" - }, - "engines": { - "node": ">= 0.6" + "color-name": "1.1.3" } }, - "node_modules/serve-index/node_modules/inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==", - "dev": true - }, - "node_modules/serve-index/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true - }, - "node_modules/serve-index/node_modules/setprototypeof": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", - "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==", + "node_modules/inquirer/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", "dev": true }, - "node_modules/serve-index/node_modules/statuses": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", - "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==", + "node_modules/inquirer/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", "dev": true, "engines": { - "node": ">= 0.6" + "node": ">=4" } }, - "node_modules/serve-static": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", - "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", + "node_modules/inquirer/node_modules/is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", "dev": true, - "dependencies": { - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "parseurl": "~1.3.3", - "send": "0.18.0" - }, "engines": { - "node": ">= 0.8.0" + "node": ">=4" } }, - "node_modules/set-function-length": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.1.1.tgz", - "integrity": "sha512-VoaqjbBJKiWtg4yRcKBQ7g7wnGnLV3M8oLvVWwOk2PdYY6PEFegR1vezXR0tw6fZGF9csVakIRjrJiy2veSBFQ==", + "node_modules/inquirer/node_modules/string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", "dev": true, "dependencies": { - "define-data-property": "^1.1.1", - "get-intrinsic": "^1.2.1", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.0" + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" }, "engines": { - "node": ">= 0.4" + "node": ">=4" } }, - "node_modules/setprototypeof": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", - "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", - "dev": true - }, - "node_modules/shallow-clone": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", - "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", + "node_modules/inquirer/node_modules/strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==", "dev": true, "dependencies": { - "kind-of": "^6.0.2" + "ansi-regex": "^3.0.0" }, "engines": { - "node": ">=8" + "node": ">=4" } }, - "node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "node_modules/inquirer/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", "dev": true, "dependencies": { - "shebang-regex": "^3.0.0" + "has-flag": "^3.0.0" }, "engines": { - "node": ">=8" + "node": ">=4" } }, - "node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "node_modules/interpret": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-2.2.0.tgz", + "integrity": "sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw==", "dev": true, "engines": { - "node": ">=8" + "node": ">= 0.10" } }, - "node_modules/shell-quote": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.1.tgz", - "integrity": "sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==", + "node_modules/into-stream": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/into-stream/-/into-stream-7.0.0.tgz", + "integrity": "sha512-2dYz766i9HprMBasCMvHMuazJ7u4WzhJwo5kb3iPSiW/iRYV6uPari3zHoqZlnuaR7V1bEiNMxikhp37rdBXbw==", "dev": true, + "dependencies": { + "from2": "^2.3.0", + "p-is-promise": "^3.0.0" + }, + "engines": { + "node": ">=12" + }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/side-channel": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", - "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "node_modules/ipaddr.js": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.1.0.tgz", + "integrity": "sha512-LlbxQ7xKzfBusov6UMi4MFpEg0m+mAm9xyNGEduwXMEDuf4WfzB/RZwMVYEd7IKGvh4IUkEXYxtAVu9T3OelJQ==", "dev": true, - "dependencies": { - "call-bind": "^1.0.0", - "get-intrinsic": "^1.0.2", - "object-inspect": "^1.9.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "engines": { + "node": ">= 10" } }, - "node_modules/signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", "dev": true }, - "node_modules/slice-ansi": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-1.0.0.tgz", - "integrity": "sha512-POqxBK6Lb3q6s047D/XsDVNPnF9Dl8JSaqe9h9lURl0OdNqy/ujDrOiIHtsqXMGbWWTIomRzAMaTyawAU//Reg==", + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", "dev": true, "dependencies": { - "is-fullwidth-code-point": "^2.0.0" + "binary-extensions": "^2.0.0" }, "engines": { - "node": ">=4" + "node": ">=8" } }, - "node_modules/slice-ansi/node_modules/is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", + "node_modules/is-core-module": { + "version": "2.13.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", + "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", "dev": true, - "engines": { - "node": ">=4" + "dependencies": { + "hasown": "^2.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/sockjs": { - "version": "0.3.24", - "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.24.tgz", - "integrity": "sha512-GJgLTZ7vYb/JtPSSZ10hsOYIvEYsjbNU+zPdIHcUaWVNUEPivzxku31865sSSud0Da0W4lEeOPlmw93zLQchuQ==", + "node_modules/is-docker": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", + "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", "dev": true, - "dependencies": { - "faye-websocket": "^0.11.3", - "uuid": "^8.3.2", - "websocket-driver": "^0.7.4" + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", "dev": true, "engines": { "node": ">=0.10.0" } }, - "node_modules/source-map-js": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", - "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true, "engines": { - "node": ">=0.10.0" + "node": ">=8" } }, - "node_modules/source-map-loader": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/source-map-loader/-/source-map-loader-4.0.1.tgz", - "integrity": "sha512-oqXpzDIByKONVY8g1NUPOTQhe0UTU5bWUl32GSkqK2LjJj0HmwTMVKxcUip0RgAYhY1mqgOxjbQM48a0mmeNfA==", + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", "dev": true, "dependencies": { - "abab": "^2.0.6", - "iconv-lite": "^0.6.3", - "source-map-js": "^1.0.2" + "is-extglob": "^2.1.1" }, "engines": { - "node": ">= 14.15.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^5.72.1" + "node": ">=0.10.0" } }, - "node_modules/source-map-support": { - "version": "0.5.21", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", - "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "dev": true, - "dependencies": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" + "engines": { + "node": ">=0.12.0" } }, - "node_modules/spdx-correct": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", - "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", + "node_modules/is-obj": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", + "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", "dev": true, - "dependencies": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" + "engines": { + "node": ">=8" } }, - "node_modules/spdx-exceptions": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz", - "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==", - "dev": true - }, - "node_modules/spdx-expression-parse": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", - "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "node_modules/is-path-cwd": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz", + "integrity": "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==", "dev": true, - "dependencies": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" + "engines": { + "node": ">=6" } }, - "node_modules/spdx-license-ids": { - "version": "3.0.17", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.17.tgz", - "integrity": "sha512-sh8PWc/ftMqAAdFiBu6Fy6JUOYjqDJBJvIhpfDMyHrr0Rbp5liZqd4TjtQ/RgfLjKFZb+LMx5hpml5qOWy0qvg==", - "dev": true - }, - "node_modules/spdy": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.2.tgz", - "integrity": "sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA==", + "node_modules/is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", "dev": true, - "dependencies": { - "debug": "^4.1.0", - "handle-thing": "^2.0.0", - "http-deceiver": "^1.2.7", - "select-hose": "^2.0.0", - "spdy-transport": "^3.0.0" - }, "engines": { - "node": ">=6.0.0" + "node": ">=8" } }, - "node_modules/spdy-transport": { + "node_modules/is-plain-obj": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/spdy-transport/-/spdy-transport-3.0.0.tgz", - "integrity": "sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-3.0.0.tgz", + "integrity": "sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==", "dev": true, - "dependencies": { - "debug": "^4.1.0", - "detect-node": "^2.0.4", - "hpack.js": "^2.1.6", - "obuf": "^1.1.2", - "readable-stream": "^3.0.6", - "wbuf": "^1.7.3" + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/split2": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/split2/-/split2-3.2.2.tgz", - "integrity": "sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg==", + "node_modules/is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", "dev": true, "dependencies": { - "readable-stream": "^3.0.0" + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" } }, - "node_modules/sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "node_modules/is-potential-custom-element-name": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", + "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==" + }, + "node_modules/is-resolvable": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz", + "integrity": "sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==", "dev": true }, - "node_modules/statuses": { + "node_modules/is-stream": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", - "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", "dev": true, "engines": { - "node": ">= 0.8" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "node_modules/is-text-path": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-text-path/-/is-text-path-1.0.1.tgz", + "integrity": "sha512-xFuJpne9oFz5qDaodwmmG08e3CawH/2ZV8Qqza1Ko7Sk8POWbkRdwIoAWVhqvq0XeUzANEhKo2n0IXUGBm7A/w==", "dev": true, "dependencies": { - "safe-buffer": "~5.2.0" + "text-extensions": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" } }, - "node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "node_modules/is-unicode-supported": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-2.1.0.tgz", + "integrity": "sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ==", "dev": true, - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, "engines": { - "node": ">=8" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "node_modules/is-wsl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", "dev": true, "dependencies": { - "ansi-regex": "^5.0.1" + "is-docker": "^2.0.0" }, "engines": { "node": ">=8" } }, - "node_modules/strip-final-newline": { + "node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "dev": true + }, + "node_modules/isexe": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", - "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, + "node_modules/isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", "dev": true, "engines": { - "node": ">=6" + "node": ">=0.10.0" } }, - "node_modules/strip-indent": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", - "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", + "node_modules/issue-parser": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/issue-parser/-/issue-parser-6.0.0.tgz", + "integrity": "sha512-zKa/Dxq2lGsBIXQ7CUZWTHfvxPC2ej0KfO7fIPqLlHB9J2hJ7rGhZ5rilhuufylr4RXYPzJUeFjKxz305OsNlA==", "dev": true, "dependencies": { - "min-indent": "^1.0.0" + "lodash.capitalize": "^4.2.1", + "lodash.escaperegexp": "^4.1.2", + "lodash.isplainobject": "^4.0.6", + "lodash.isstring": "^4.0.1", + "lodash.uniqby": "^4.7.0" }, "engines": { - "node": ">=8" + "node": ">=10.13" } }, - "node_modules/strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", + "node_modules/java-properties": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/java-properties/-/java-properties-1.0.2.tgz", + "integrity": "sha512-qjdpeo2yKlYTH7nFdK0vbZWuTCesk4o63v5iVOlhMQPfuIZQfW/HI35SjfhA+4qpg36rnFSvUK5b1m+ckIblQQ==", "dev": true, "engines": { - "node": ">=0.10.0" + "node": ">= 0.6.0" } }, - "node_modules/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "node_modules/jest-worker": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", + "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", "dev": true, "dependencies": { - "has-flag": "^4.0.0" + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" }, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" + "node": ">= 10.13.0" } }, - "node_modules/supports-preserve-symlinks-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", "dev": true, - "engines": { - "node": ">= 0.4" + "dependencies": { + "argparse": "^2.0.1" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "bin": { + "js-yaml": "bin/js-yaml.js" } }, - "node_modules/symbol-tree": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", - "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==" - }, - "node_modules/table": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/table/-/table-4.0.2.tgz", - "integrity": "sha512-UUkEAPdSGxtRpiV9ozJ5cMTtYiqz7Ni1OGqLXRCynrvzdtR1p+cfOWe2RJLwvUG8hNanaSRjecIqwOjqeatDsA==", - "dev": true, + "node_modules/jsdom": { + "version": "23.0.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-23.0.0.tgz", + "integrity": "sha512-cbL/UCtohJguhFC7c2/hgW6BeZCNvP7URQGnx9tSJRYKCdnfbfWOrtuLTMfiB2VxKsx5wPHVsh/J0aBy9lIIhQ==", "dependencies": { - "ajv": "^5.2.3", - "ajv-keywords": "^2.1.0", - "chalk": "^2.1.0", - "lodash": "^4.17.4", - "slice-ansi": "1.0.0", - "string-width": "^2.1.1" + "cssstyle": "^3.0.0", + "data-urls": "^5.0.0", + "decimal.js": "^10.4.3", + "form-data": "^4.0.0", + "html-encoding-sniffer": "^4.0.0", + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.2", + "is-potential-custom-element-name": "^1.0.1", + "nwsapi": "^2.2.7", + "parse5": "^7.1.2", + "rrweb-cssom": "^0.6.0", + "saxes": "^6.0.0", + "symbol-tree": "^3.2.4", + "tough-cookie": "^4.1.3", + "w3c-xmlserializer": "^5.0.0", + "webidl-conversions": "^7.0.0", + "whatwg-encoding": "^3.1.1", + "whatwg-mimetype": "^4.0.0", + "whatwg-url": "^14.0.0", + "ws": "^8.14.2", + "xml-name-validator": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "canvas": "^3.0.0" + }, + "peerDependenciesMeta": { + "canvas": { + "optional": true + } } }, - "node_modules/table/node_modules/ajv": { - "version": "5.5.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz", - "integrity": "sha512-Ajr4IcMXq/2QmMkEmSvxqfLN5zGmJ92gHXAeOXq1OekoH2rfDNsgdDoL2f7QaRCy7G/E6TpxBVdRuNraMztGHw==", + "node_modules/json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", "dev": true, - "dependencies": { - "co": "^4.6.0", - "fast-deep-equal": "^1.0.0", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.3.0" - } + "license": "MIT" }, - "node_modules/table/node_modules/ajv-keywords": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-2.1.1.tgz", - "integrity": "sha512-ZFztHzVRdGLAzJmpUT9LNFLe1YiVOEylcaNpEutM26PVTCtOD919IMfD01CgbRouB42Dd9atjx1HseC15DgOZA==", - "dev": true, - "peerDependencies": { - "ajv": "^5.0.0" - } + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true }, - "node_modules/table/node_modules/ansi-regex": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz", - "integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==", - "dev": true, - "engines": { - "node": ">=4" - } + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true }, - "node_modules/table/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true + }, + "node_modules/json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", + "dev": true + }, + "node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", "dev": true, "dependencies": { - "color-convert": "^1.9.0" + "universalify": "^2.0.0" }, - "engines": { - "node": ">=4" + "optionalDependencies": { + "graceful-fs": "^4.1.6" } }, - "node_modules/table/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "node_modules/jsonfile/node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", "dev": true, - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, "engines": { - "node": ">=4" + "node": ">= 10.0.0" } }, - "node_modules/table/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "node_modules/jsonparse": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", + "integrity": "sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==", "dev": true, - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/table/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "node_modules/table/node_modules/fast-deep-equal": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz", - "integrity": "sha512-fueX787WZKCV0Is4/T2cyAdM4+x1S3MXXOAhavE1ys/W42SHAPacLTQhucja22QBYrfGw50M2sRiXPtTGv9Ymw==", - "dev": true + "engines": [ + "node >= 0.2.0" + ] }, - "node_modules/table/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "node_modules/JSONStream": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz", + "integrity": "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==", "dev": true, + "dependencies": { + "jsonparse": "^1.2.0", + "through": ">=2.2.7 <3" + }, + "bin": { + "JSONStream": "bin.js" + }, "engines": { - "node": ">=4" + "node": "*" } }, - "node_modules/table/node_modules/is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", + "node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", "dev": true, "engines": { - "node": ">=4" + "node": ">=0.10.0" } }, - "node_modules/table/node_modules/json-schema-traverse": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz", - "integrity": "sha512-4JD/Ivzg7PoW8NzdrBSr3UFwC9mHgvI7Z6z3QGBsSHgKaRTUDmyZAAKJo2UbG1kUVfS9WS8bi36N49U1xw43DA==", - "dev": true + "node_modules/launch-editor": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.6.1.tgz", + "integrity": "sha512-eB/uXmFVpY4zezmGp5XtU21kwo7GBbKB+EQ+UZeWtGb9yAM5xt/Evk+lYH3eRNAtId+ej4u7TYPFZ07w4s7rRw==", + "dev": true, + "dependencies": { + "picocolors": "^1.0.0", + "shell-quote": "^1.8.1" + } }, - "node_modules/table/node_modules/string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "node_modules/levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==", "dev": true, "dependencies": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" }, "engines": { - "node": ">=4" + "node": ">= 0.8.0" } }, - "node_modules/table/node_modules/strip-ansi": { + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true + }, + "node_modules/load-json-file": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", + "integrity": "sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw==", "dev": true, + "license": "MIT", "dependencies": { - "ansi-regex": "^3.0.0" + "graceful-fs": "^4.1.2", + "parse-json": "^4.0.0", + "pify": "^3.0.0", + "strip-bom": "^3.0.0" }, "engines": { "node": ">=4" } }, - "node_modules/table/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "node_modules/load-json-file/node_modules/parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==", "dev": true, + "license": "MIT", "dependencies": { - "has-flag": "^3.0.0" + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" }, "engines": { "node": ">=4" } }, - "node_modules/tapable": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", - "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", + "node_modules/loader-runner": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", + "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==", "dev": true, "engines": { - "node": ">=6" + "node": ">=6.11.5" } }, - "node_modules/terser": { - "version": "5.26.0", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.26.0.tgz", - "integrity": "sha512-dytTGoE2oHgbNV9nTzgBEPaqAWvcJNl66VZ0BkJqlvp71IjO8CxdBx/ykCNb47cLnCmCvRZ6ZR0tLkqvZCdVBQ==", + "node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", "dev": true, "dependencies": { - "@jridgewell/source-map": "^0.3.3", - "acorn": "^8.8.2", - "commander": "^2.20.0", - "source-map-support": "~0.5.20" - }, - "bin": { - "terser": "bin/terser" + "p-locate": "^4.1.0" }, "engines": { - "node": ">=10" + "node": ">=8" } }, - "node_modules/terser-webpack-plugin": { - "version": "5.3.9", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.9.tgz", - "integrity": "sha512-ZuXsqE07EcggTWQjXUj+Aot/OMcD0bMKGgF63f7UxYcu5/AJF53aIpK1YoP5xR9l6s/Hy2b+t1AM0bLNPRuhwA==", - "dev": true, - "dependencies": { - "@jridgewell/trace-mapping": "^0.3.17", - "jest-worker": "^27.4.5", - "schema-utils": "^3.1.1", - "serialize-javascript": "^6.0.1", - "terser": "^5.16.8" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^5.1.0" - }, - "peerDependenciesMeta": { - "@swc/core": { - "optional": true - }, - "esbuild": { - "optional": true - }, - "uglify-js": { - "optional": true - } - } + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true }, - "node_modules/text-extensions": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/text-extensions/-/text-extensions-1.9.0.tgz", - "integrity": "sha512-wiBrwC1EhBelW12Zy26JeOUkQ5mRu+5o8rpsJk5+2t+Y5vE7e842qtZDQ2g1NpX/29HdyFeJ4nSIhI47ENSxlQ==", - "dev": true, - "engines": { - "node": ">=0.10" - } + "node_modules/lodash-es": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz", + "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==", + "dev": true }, - "node_modules/text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", + "node_modules/lodash.camelcase": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", + "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==", "dev": true }, - "node_modules/through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", + "node_modules/lodash.capitalize": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/lodash.capitalize/-/lodash.capitalize-4.2.1.tgz", + "integrity": "sha512-kZzYOKspf8XVX5AvmQF94gQW0lejFVgb80G85bU4ZWzoJ6C03PQg3coYAUpSTpQWelrZELd3XWgHzw4Ck5kaIw==", "dev": true }, - "node_modules/through2": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/through2/-/through2-4.0.2.tgz", - "integrity": "sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==", - "dev": true, - "dependencies": { - "readable-stream": "3" - } + "node_modules/lodash.escaperegexp": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.escaperegexp/-/lodash.escaperegexp-4.1.2.tgz", + "integrity": "sha512-TM9YBvyC84ZxE3rgfefxUWiQKLilstD6k7PTGt6wfbtXF8ixIJLOL3VYyV/z+ZiPLsVxAsKAFVwWlWeb2Y8Yyw==", + "dev": true }, - "node_modules/thunky": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz", - "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==", + "node_modules/lodash.isfunction": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/lodash.isfunction/-/lodash.isfunction-3.0.9.tgz", + "integrity": "sha512-AirXNj15uRIMMPihnkInB4i3NHeb4iBtNg9WRWuK2o31S+ePwwNmDPaTL3o7dTJ+VXNZim7rFs4rxN4YU1oUJw==", "dev": true }, - "node_modules/tmp": { - "version": "0.0.33", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", - "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", - "dev": true, - "dependencies": { - "os-tmpdir": "~1.0.2" - }, - "engines": { - "node": ">=0.6.0" - } + "node_modules/lodash.ismatch": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.ismatch/-/lodash.ismatch-4.4.0.tgz", + "integrity": "sha512-fPMfXjGQEV9Xsq/8MTSgUf255gawYRbjwMyDbcvDhXgV7enSZA0hynz6vMPnpAb5iONEzBHBPsT+0zes5Z301g==", + "dev": true }, - "node_modules/to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "node_modules/lodash.isplainobject": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", + "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==", + "dev": true + }, + "node_modules/lodash.isstring": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", + "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==", + "dev": true + }, + "node_modules/lodash.kebabcase": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.kebabcase/-/lodash.kebabcase-4.1.1.tgz", + "integrity": "sha512-N8XRTIMMqqDgSy4VLKPnJ/+hpGZN+PHQiJnSenYqPaVV/NCqEogTnAdZLQiGKhxX+JCs8waWq2t1XHWKOmlY8g==", + "dev": true + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, + "node_modules/lodash.mergewith": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.mergewith/-/lodash.mergewith-4.6.2.tgz", + "integrity": "sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ==", + "dev": true + }, + "node_modules/lodash.snakecase": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.snakecase/-/lodash.snakecase-4.1.1.tgz", + "integrity": "sha512-QZ1d4xoBHYUeuouhEq3lk3Uq7ldgyFXGBhg04+oRLnIz8o9T65Eh+8YdroUwn846zchkA9yDsDl5CVVaV2nqYw==", + "dev": true + }, + "node_modules/lodash.startcase": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.startcase/-/lodash.startcase-4.4.0.tgz", + "integrity": "sha512-+WKqsK294HMSc2jEbNgpHpd0JfIBhp7rEV4aqXWqFr6AlXov+SlcgB1Fv01y2kGe3Gc8nMW7VA0SrGuSkRfIEg==", + "dev": true + }, + "node_modules/lodash.uniq": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", + "integrity": "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==", + "dev": true + }, + "node_modules/lodash.uniqby": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/lodash.uniqby/-/lodash.uniqby-4.7.0.tgz", + "integrity": "sha512-e/zcLx6CSbmaEgFHCA7BnoQKyCtKMxnuWrJygbwPs/AIn+IMKl66L8/s+wBUn5LRw2pZx3bUHibiV1b6aTWIww==", + "dev": true + }, + "node_modules/lodash.upperfirst": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/lodash.upperfirst/-/lodash.upperfirst-4.3.1.tgz", + "integrity": "sha512-sReKOYJIJf74dhJONhU4e0/shzi1trVbSWDOhKYE5XV2O+H7Sb2Dihwuc7xWxVl+DgFPyTqIN3zMfT9cq5iWDg==", + "dev": true + }, + "node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", "dev": true, "dependencies": { - "is-number": "^7.0.0" + "yallist": "^4.0.0" }, "engines": { - "node": ">=8.0" + "node": ">=10" } }, - "node_modules/toidentifier": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", - "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "node_modules/make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true + }, + "node_modules/map-obj": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.3.0.tgz", + "integrity": "sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==", "dev": true, "engines": { - "node": ">=0.6" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/tough-cookie": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.4.tgz", - "integrity": "sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==", - "dependencies": { - "psl": "^1.1.33", - "punycode": "^2.1.1", - "universalify": "^0.2.0", - "url-parse": "^1.5.3" + "node_modules/marked": { + "version": "9.1.6", + "resolved": "https://registry.npmjs.org/marked/-/marked-9.1.6.tgz", + "integrity": "sha512-jcByLnIFkd5gSXZmjNvS1TlmRhCXZjIzHYlaGkPlLIekG55JDR2Z4va9tZwCiP+/RDERiNhMOFu01xd6O5ct1Q==", + "dev": true, + "bin": { + "marked": "bin/marked.js" }, "engines": { - "node": ">=6" + "node": ">= 16" } }, - "node_modules/tr46": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-5.0.0.tgz", - "integrity": "sha512-tk2G5R2KRwBd+ZN0zaEXpmzdKyOYksXwywulIX95MBODjSzMIuQnQ3m8JxgbhnL1LeVo7lqQKsYa1O3Htl7K5g==", + "node_modules/marked-terminal": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/marked-terminal/-/marked-terminal-6.2.0.tgz", + "integrity": "sha512-ubWhwcBFHnXsjYNsu+Wndpg0zhY4CahSpPlA70PlO0rR9r2sZpkyU+rkCsOWH+KMEkx847UpALON+HWgxowFtw==", + "dev": true, "dependencies": { - "punycode": "^2.3.1" + "ansi-escapes": "^6.2.0", + "cardinal": "^2.1.1", + "chalk": "^5.3.0", + "cli-table3": "^0.6.3", + "node-emoji": "^2.1.3", + "supports-hyperlinks": "^3.0.0" }, "engines": { - "node": ">=18" + "node": ">=16.0.0" + }, + "peerDependencies": { + "marked": ">=1 <12" } }, - "node_modules/trim-newlines": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.1.tgz", - "integrity": "sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==", + "node_modules/marked-terminal/node_modules/ansi-escapes": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-6.2.1.tgz", + "integrity": "sha512-4nJ3yixlEthEJ9Rk4vPcdBRkZvQZlYyu8j4/Mqz5sgIkddmEnH2Yj2ZrnP9S3tQOvSNRUIgVNF/1yPpRAGNRig==", "dev": true, "engines": { - "node": ">=8" + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/ts-loader": { - "version": "9.5.1", - "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-9.5.1.tgz", - "integrity": "sha512-rNH3sK9kGZcH9dYzC7CewQm4NtxJTjSEVRJ2DyBZR7f8/wcta+iV44UPCXc5+nzDzivKtlzV6c9P4e+oFhDLYg==", + "node_modules/marked-terminal/node_modules/chalk": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", + "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", "dev": true, - "dependencies": { - "chalk": "^4.1.0", - "enhanced-resolve": "^5.0.0", - "micromatch": "^4.0.0", - "semver": "^7.3.4", - "source-map": "^0.7.4" - }, "engines": { - "node": ">=12.0.0" + "node": "^12.17.0 || ^14.13 || >=16.0.0" }, - "peerDependencies": { - "typescript": "*", - "webpack": "^5.0.0" + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/ts-loader/node_modules/source-map": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", - "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", + "node_modules/media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", "dev": true, "engines": { - "node": ">= 8" + "node": ">= 0.6" } }, - "node_modules/ts-node": { - "version": "10.9.2", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", - "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", + "node_modules/memfs": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.5.3.tgz", + "integrity": "sha512-UERzLsxzllchadvbPs5aolHh65ISpKpM+ccLbOJ8/vvpBKmAWf+la7dXFy7Mr0ySHbdHrFv5kGFCUHHe6GFEmw==", "dev": true, "dependencies": { - "@cspotcode/source-map-support": "^0.8.0", - "@tsconfig/node10": "^1.0.7", - "@tsconfig/node12": "^1.0.7", - "@tsconfig/node14": "^1.0.0", - "@tsconfig/node16": "^1.0.2", - "acorn": "^8.4.1", - "acorn-walk": "^8.1.1", - "arg": "^4.1.0", - "create-require": "^1.1.0", - "diff": "^4.0.1", - "make-error": "^1.1.1", - "v8-compile-cache-lib": "^3.0.1", - "yn": "3.1.1" - }, - "bin": { - "ts-node": "dist/bin.js", - "ts-node-cwd": "dist/bin-cwd.js", - "ts-node-esm": "dist/bin-esm.js", - "ts-node-script": "dist/bin-script.js", - "ts-node-transpile-only": "dist/bin-transpile.js", - "ts-script": "dist/bin-script-deprecated.js" - }, - "peerDependencies": { - "@swc/core": ">=1.2.50", - "@swc/wasm": ">=1.2.50", - "@types/node": "*", - "typescript": ">=2.7" + "fs-monkey": "^1.0.4" }, - "peerDependenciesMeta": { - "@swc/core": { - "optional": true - }, - "@swc/wasm": { - "optional": true - } + "engines": { + "node": ">= 4.0.0" } }, - "node_modules/type-check": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==", + "node_modules/meow": { + "version": "8.1.2", + "resolved": "https://registry.npmjs.org/meow/-/meow-8.1.2.tgz", + "integrity": "sha512-r85E3NdZ+mpYk1C6RjPFEMSE+s1iZMuHtsHAqY0DT3jZczl0diWUZ8g6oU7h0M9cD2EL+PzaYghhCLzR0ZNn5Q==", "dev": true, "dependencies": { - "prelude-ls": "~1.1.2" + "@types/minimist": "^1.2.0", + "camelcase-keys": "^6.2.2", + "decamelize-keys": "^1.1.0", + "hard-rejection": "^2.1.0", + "minimist-options": "4.1.0", + "normalize-package-data": "^3.0.0", + "read-pkg-up": "^7.0.1", + "redent": "^3.0.0", + "trim-newlines": "^3.0.0", + "type-fest": "^0.18.0", + "yargs-parser": "^20.2.3" }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/type-fest": { - "version": "0.18.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.18.1.tgz", - "integrity": "sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw==", - "dev": true, "engines": { "node": ">=10" }, @@ -6339,4974 +6379,20502 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/type-is": { - "version": "1.6.18", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", - "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", - "dev": true, - "dependencies": { - "media-typer": "0.3.0", - "mime-types": "~2.1.24" - }, - "engines": { - "node": ">= 0.6" - } + "node_modules/merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==", + "dev": true }, - "node_modules/typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==", + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", "dev": true }, - "node_modules/typescript": { - "version": "5.6.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.3.tgz", - "integrity": "sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==", + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", "dev": true, - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, "engines": { - "node": ">=14.17" + "node": ">= 8" } }, - "node_modules/undici-types": { - "version": "5.26.5", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", - "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", - "dev": true - }, - "node_modules/universalify": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", - "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==", + "node_modules/methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", + "dev": true, "engines": { - "node": ">= 4.0.0" + "node": ">= 0.6" } }, - "node_modules/unpipe": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "node_modules/micromatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", "dev": true, + "dependencies": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + }, "engines": { - "node": ">= 0.8" + "node": ">=8.6" } }, - "node_modules/update-browserslist-db": { - "version": "1.0.13", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", - "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==", + "node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "dependencies": { - "escalade": "^3.1.1", - "picocolors": "^1.0.0" - }, "bin": { - "update-browserslist-db": "cli.js" + "mime": "cli.js" }, - "peerDependencies": { - "browserslist": ">= 4.21.0" + "engines": { + "node": ">=4" } }, - "node_modules/uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dev": true, - "dependencies": { - "punycode": "^2.1.0" + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "engines": { + "node": ">= 0.6" } }, - "node_modules/url-parse": { - "version": "1.5.10", - "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", - "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", "dependencies": { - "querystringify": "^2.1.1", - "requires-port": "^1.0.0" + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" } }, - "node_modules/util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", - "dev": true - }, - "node_modules/utils-merge": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", "dev": true, "engines": { - "node": ">= 0.4.0" + "node": ">=6" } }, - "node_modules/uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "node_modules/min-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", + "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", "dev": true, - "bin": { - "uuid": "dist/bin/uuid" + "engines": { + "node": ">=4" } }, - "node_modules/v8-compile-cache-lib": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", - "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", + "node_modules/minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", "dev": true }, - "node_modules/validate-npm-package-license": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", - "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, "dependencies": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" } }, - "node_modules/vary": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", "dev": true, - "engines": { - "node": ">= 0.8" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/w3c-xmlserializer": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-5.0.0.tgz", - "integrity": "sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==", + "node_modules/minimist-options": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-4.1.0.tgz", + "integrity": "sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==", + "dev": true, "dependencies": { - "xml-name-validator": "^5.0.0" + "arrify": "^1.0.1", + "is-plain-obj": "^1.1.0", + "kind-of": "^6.0.3" }, "engines": { - "node": ">=18" + "node": ">= 6" } }, - "node_modules/watchpack": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz", - "integrity": "sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg==", + "node_modules/minimist-options/node_modules/is-plain-obj": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", + "integrity": "sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==", "dev": true, - "dependencies": { - "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.1.2" - }, "engines": { - "node": ">=10.13.0" + "node": ">=0.10.0" } }, - "node_modules/wbuf": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/wbuf/-/wbuf-1.7.3.tgz", - "integrity": "sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==", + "node_modules/mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", "dev": true, "dependencies": { - "minimalistic-assert": "^1.0.0" + "minimist": "^1.2.6" + }, + "bin": { + "mkdirp": "bin/cmd.js" } }, - "node_modules/webidl-conversions": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", - "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", + "node_modules/modify-values": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/modify-values/-/modify-values-1.0.1.tgz", + "integrity": "sha512-xV2bxeN6F7oYjZWTe/YPAy6MN2M+sL4u/Rlm2AHCIVGfo2p1yGmBHQ6vHehl4bRTZBdHu3TSkWdYgkwpYzAGSw==", + "dev": true, "engines": { - "node": ">=12" + "node": ">=0.10.0" } }, - "node_modules/webpack": { - "version": "5.89.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.89.0.tgz", - "integrity": "sha512-qyfIC10pOr70V+jkmud8tMfajraGCZMBWJtrmuBymQKCrLTRejBI8STDp1MCyZu/QTdZSeacCQYpYNQVOzX5kw==", + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "node_modules/multicast-dns": { + "version": "7.2.5", + "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-7.2.5.tgz", + "integrity": "sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg==", "dev": true, "dependencies": { - "@types/eslint-scope": "^3.7.3", - "@types/estree": "^1.0.0", - "@webassemblyjs/ast": "^1.11.5", - "@webassemblyjs/wasm-edit": "^1.11.5", - "@webassemblyjs/wasm-parser": "^1.11.5", - "acorn": "^8.7.1", - "acorn-import-assertions": "^1.9.0", - "browserslist": "^4.14.5", - "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.15.0", - "es-module-lexer": "^1.2.1", - "eslint-scope": "5.1.1", - "events": "^3.2.0", - "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.2.9", - "json-parse-even-better-errors": "^2.3.1", - "loader-runner": "^4.2.0", - "mime-types": "^2.1.27", - "neo-async": "^2.6.2", - "schema-utils": "^3.2.0", - "tapable": "^2.1.1", - "terser-webpack-plugin": "^5.3.7", - "watchpack": "^2.4.0", - "webpack-sources": "^3.2.3" + "dns-packet": "^5.2.2", + "thunky": "^1.0.2" }, "bin": { - "webpack": "bin/webpack.js" + "multicast-dns": "cli.js" + } + }, + "node_modules/mute-stream": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", + "integrity": "sha512-r65nCZhrbXXb6dXOACihYApHw2Q6pV0M3V0PSxd74N0+D8nzAdEAITq2oAjA1jVnKI+tGvEBUpqiMh0+rW6zDQ==", + "dev": true + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true + }, + "node_modules/negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "dev": true + }, + "node_modules/nerf-dart": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/nerf-dart/-/nerf-dart-1.0.0.tgz", + "integrity": "sha512-EZSPZB70jiVsivaBLYDCyntd5eH8NTSMOn3rB+HxwdmKThGELLdYv8qVIMWvZEFy9w8ZZpW9h9OB32l1rGtj7g==", + "dev": true + }, + "node_modules/node-emoji": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-2.1.3.tgz", + "integrity": "sha512-E2WEOVsgs7O16zsURJ/eH8BqhF029wGpEOnv7Urwdo2wmQanOACwJQh0devF9D9RhoZru0+9JXIS0dBXIAz+lA==", + "dev": true, + "dependencies": { + "@sindresorhus/is": "^4.6.0", + "char-regex": "^1.0.2", + "emojilib": "^2.4.0", + "skin-tone": "^2.0.0" }, "engines": { - "node": ">=10.13.0" + "node": ">=18" + } + }, + "node_modules/node-fetch": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "dev": true, + "dependencies": { + "whatwg-url": "^5.0.0" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" }, "peerDependenciesMeta": { - "webpack-cli": { + "encoding": { "optional": true } } }, - "node_modules/webpack-cli": { - "version": "4.10.0", - "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-4.10.0.tgz", - "integrity": "sha512-NLhDfH/h4O6UOy+0LSso42xvYypClINuMNBVVzX4vX98TmTaTUxwRbXdhucbFMd2qLaCTcLq/PdYrvi8onw90w==", + "node_modules/node-fetch/node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", + "dev": true + }, + "node_modules/node-fetch/node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", + "dev": true + }, + "node_modules/node-fetch/node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", "dev": true, "dependencies": { - "@discoveryjs/json-ext": "^0.5.0", - "@webpack-cli/configtest": "^1.2.0", - "@webpack-cli/info": "^1.5.0", - "@webpack-cli/serve": "^1.7.0", - "colorette": "^2.0.14", - "commander": "^7.0.0", - "cross-spawn": "^7.0.3", - "fastest-levenshtein": "^1.0.12", - "import-local": "^3.0.2", - "interpret": "^2.2.0", - "rechoir": "^0.7.0", - "webpack-merge": "^5.7.3" - }, - "bin": { - "webpack-cli": "bin/cli.js" + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "node_modules/node-forge": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz", + "integrity": "sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==", + "dev": true, + "engines": { + "node": ">= 6.13.0" + } + }, + "node_modules/node-releases": { + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", + "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==", + "dev": true + }, + "node_modules/normalize-package-data": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.3.tgz", + "integrity": "sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==", + "dev": true, + "dependencies": { + "hosted-git-info": "^4.0.1", + "is-core-module": "^2.5.0", + "semver": "^7.3.4", + "validate-npm-package-license": "^3.0.1" }, "engines": { - "node": ">=10.13.0" + "node": ">=10" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/normalize-url": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-8.0.1.tgz", + "integrity": "sha512-IO9QvjUMWxPQQhs60oOu10CRkWCiZzSUkzbXGGV9pviYl1fXYcvkzQ5jV9z8Y6un8ARoVRl4EtC6v6jNqbaJ/w==", + "dev": true, + "engines": { + "node": ">=14.16" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/npm": { + "version": "10.9.0", + "resolved": "https://registry.npmjs.org/npm/-/npm-10.9.0.tgz", + "integrity": "sha512-ZanDioFylI9helNhl2LNd+ErmVD+H5I53ry41ixlLyCBgkuYb+58CvbAp99hW+zr5L9W4X7CchSoeqKdngOLSw==", + "bundleDependencies": [ + "@isaacs/string-locale-compare", + "@npmcli/arborist", + "@npmcli/config", + "@npmcli/fs", + "@npmcli/map-workspaces", + "@npmcli/package-json", + "@npmcli/promise-spawn", + "@npmcli/redact", + "@npmcli/run-script", + "@sigstore/tuf", + "abbrev", + "archy", + "cacache", + "chalk", + "ci-info", + "cli-columns", + "fastest-levenshtein", + "fs-minipass", + "glob", + "graceful-fs", + "hosted-git-info", + "ini", + "init-package-json", + "is-cidr", + "json-parse-even-better-errors", + "libnpmaccess", + "libnpmdiff", + "libnpmexec", + "libnpmfund", + "libnpmhook", + "libnpmorg", + "libnpmpack", + "libnpmpublish", + "libnpmsearch", + "libnpmteam", + "libnpmversion", + "make-fetch-happen", + "minimatch", + "minipass", + "minipass-pipeline", + "ms", + "node-gyp", + "nopt", + "normalize-package-data", + "npm-audit-report", + "npm-install-checks", + "npm-package-arg", + "npm-pick-manifest", + "npm-profile", + "npm-registry-fetch", + "npm-user-validate", + "p-map", + "pacote", + "parse-conflict-json", + "proc-log", + "qrcode-terminal", + "read", + "semver", + "spdx-expression-parse", + "ssri", + "supports-color", + "tar", + "text-table", + "tiny-relative-date", + "treeverse", + "validate-npm-package-name", + "which", + "write-file-atomic" + ], + "dev": true, + "workspaces": [ + "docs", + "smoke-tests", + "mock-globals", + "mock-registry", + "workspaces/*" + ], + "dependencies": { + "@isaacs/string-locale-compare": "^1.1.0", + "@npmcli/arborist": "^8.0.0", + "@npmcli/config": "^9.0.0", + "@npmcli/fs": "^4.0.0", + "@npmcli/map-workspaces": "^4.0.1", + "@npmcli/package-json": "^6.0.1", + "@npmcli/promise-spawn": "^8.0.1", + "@npmcli/redact": "^3.0.0", + "@npmcli/run-script": "^9.0.1", + "@sigstore/tuf": "^2.3.4", + "abbrev": "^3.0.0", + "archy": "~1.0.0", + "cacache": "^19.0.1", + "chalk": "^5.3.0", + "ci-info": "^4.0.0", + "cli-columns": "^4.0.0", + "fastest-levenshtein": "^1.0.16", + "fs-minipass": "^3.0.3", + "glob": "^10.4.5", + "graceful-fs": "^4.2.11", + "hosted-git-info": "^8.0.0", + "ini": "^5.0.0", + "init-package-json": "^7.0.1", + "is-cidr": "^5.1.0", + "json-parse-even-better-errors": "^4.0.0", + "libnpmaccess": "^9.0.0", + "libnpmdiff": "^7.0.0", + "libnpmexec": "^9.0.0", + "libnpmfund": "^6.0.0", + "libnpmhook": "^11.0.0", + "libnpmorg": "^7.0.0", + "libnpmpack": "^8.0.0", + "libnpmpublish": "^10.0.0", + "libnpmsearch": "^8.0.0", + "libnpmteam": "^7.0.0", + "libnpmversion": "^7.0.0", + "make-fetch-happen": "^14.0.1", + "minimatch": "^9.0.5", + "minipass": "^7.1.1", + "minipass-pipeline": "^1.2.4", + "ms": "^2.1.2", + "node-gyp": "^10.2.0", + "nopt": "^8.0.0", + "normalize-package-data": "^7.0.0", + "npm-audit-report": "^6.0.0", + "npm-install-checks": "^7.1.0", + "npm-package-arg": "^12.0.0", + "npm-pick-manifest": "^10.0.0", + "npm-profile": "^11.0.1", + "npm-registry-fetch": "^18.0.1", + "npm-user-validate": "^3.0.0", + "p-map": "^4.0.0", + "pacote": "^19.0.0", + "parse-conflict-json": "^4.0.0", + "proc-log": "^5.0.0", + "qrcode-terminal": "^0.12.0", + "read": "^4.0.0", + "semver": "^7.6.3", + "spdx-expression-parse": "^4.0.0", + "ssri": "^12.0.0", + "supports-color": "^9.4.0", + "tar": "^6.2.1", + "text-table": "~0.2.0", + "tiny-relative-date": "^1.3.0", + "treeverse": "^3.0.0", + "validate-npm-package-name": "^6.0.0", + "which": "^5.0.0", + "write-file-atomic": "^6.0.0" }, - "peerDependencies": { - "webpack": "4.x.x || 5.x.x" + "bin": { + "npm": "bin/npm-cli.js", + "npx": "bin/npx-cli.js" }, - "peerDependenciesMeta": { - "@webpack-cli/generators": { - "optional": true - }, - "@webpack-cli/migrate": { - "optional": true - }, - "webpack-bundle-analyzer": { - "optional": true - }, - "webpack-dev-server": { - "optional": true - } + "engines": { + "node": "^18.17.0 || >=20.5.0" } }, - "node_modules/webpack-cli/node_modules/commander": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", - "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "node_modules/npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", "dev": true, + "dependencies": { + "path-key": "^3.0.0" + }, "engines": { - "node": ">= 10" + "node": ">=8" } }, - "node_modules/webpack-dev-middleware": { - "version": "5.3.3", - "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-5.3.3.tgz", - "integrity": "sha512-hj5CYrY0bZLB+eTO+x/j67Pkrquiy7kWepMHmUMoPsmcUaeEnQJqFzHJOyxgWlq746/wUuA64p9ta34Kyb01pA==", + "node_modules/npm/node_modules/@isaacs/cliui": { + "version": "8.0.2", "dev": true, + "inBundle": true, + "license": "ISC", "dependencies": { - "colorette": "^2.0.10", - "memfs": "^3.4.3", - "mime-types": "^2.1.31", - "range-parser": "^1.2.1", - "schema-utils": "^4.0.0" + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" }, "engines": { - "node": ">= 12.13.0" + "node": ">=12" + } + }, + "node_modules/npm/node_modules/@isaacs/cliui/node_modules/ansi-regex": { + "version": "6.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=12" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/npm/node_modules/@isaacs/cliui/node_modules/emoji-regex": { + "version": "9.2.2", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/@isaacs/cliui/node_modules/string-width": { + "version": "5.1.2", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" }, - "peerDependencies": { - "webpack": "^4.0.0 || ^5.0.0" + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/webpack-dev-middleware/node_modules/ajv": { - "version": "8.12.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", - "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "node_modules/npm/node_modules/@isaacs/cliui/node_modules/strip-ansi": { + "version": "7.1.0", "dev": true, + "inBundle": true, + "license": "MIT", "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" }, "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" + "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, - "node_modules/webpack-dev-middleware/node_modules/ajv-keywords": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", - "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", + "node_modules/npm/node_modules/@isaacs/fs-minipass": { + "version": "4.0.1", "dev": true, + "inBundle": true, + "license": "ISC", "dependencies": { - "fast-deep-equal": "^3.1.3" + "minipass": "^7.0.4" }, - "peerDependencies": { - "ajv": "^8.8.2" + "engines": { + "node": ">=18.0.0" } }, - "node_modules/webpack-dev-middleware/node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true + "node_modules/npm/node_modules/@isaacs/string-locale-compare": { + "version": "1.1.0", + "dev": true, + "inBundle": true, + "license": "ISC" }, - "node_modules/webpack-dev-middleware/node_modules/schema-utils": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz", - "integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==", + "node_modules/npm/node_modules/@npmcli/agent": { + "version": "3.0.0", "dev": true, + "inBundle": true, + "license": "ISC", "dependencies": { - "@types/json-schema": "^7.0.9", - "ajv": "^8.9.0", - "ajv-formats": "^2.1.1", - "ajv-keywords": "^5.1.0" + "agent-base": "^7.1.0", + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.1", + "lru-cache": "^10.0.1", + "socks-proxy-agent": "^8.0.3" }, "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" + "node": "^18.17.0 || >=20.5.0" } }, - "node_modules/webpack-dev-server": { - "version": "4.15.1", - "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-4.15.1.tgz", - "integrity": "sha512-5hbAst3h3C3L8w6W4P96L5vaV0PxSmJhxZvWKYIdgxOQm8pNZ5dEOmmSLBVpP85ReeyRt6AS1QJNyo/oFFPeVA==", + "node_modules/npm/node_modules/@npmcli/arborist": { + "version": "8.0.0", "dev": true, - "dependencies": { - "@types/bonjour": "^3.5.9", - "@types/connect-history-api-fallback": "^1.3.5", - "@types/express": "^4.17.13", - "@types/serve-index": "^1.9.1", - "@types/serve-static": "^1.13.10", - "@types/sockjs": "^0.3.33", - "@types/ws": "^8.5.5", - "ansi-html-community": "^0.0.8", - "bonjour-service": "^1.0.11", - "chokidar": "^3.5.3", - "colorette": "^2.0.10", - "compression": "^1.7.4", - "connect-history-api-fallback": "^2.0.0", - "default-gateway": "^6.0.3", - "express": "^4.17.3", - "graceful-fs": "^4.2.6", - "html-entities": "^2.3.2", - "http-proxy-middleware": "^2.0.3", - "ipaddr.js": "^2.0.1", - "launch-editor": "^2.6.0", - "open": "^8.0.9", - "p-retry": "^4.5.0", - "rimraf": "^3.0.2", - "schema-utils": "^4.0.0", - "selfsigned": "^2.1.1", - "serve-index": "^1.9.1", - "sockjs": "^0.3.24", - "spdy": "^4.0.2", - "webpack-dev-middleware": "^5.3.1", - "ws": "^8.13.0" + "inBundle": true, + "license": "ISC", + "dependencies": { + "@isaacs/string-locale-compare": "^1.1.0", + "@npmcli/fs": "^4.0.0", + "@npmcli/installed-package-contents": "^3.0.0", + "@npmcli/map-workspaces": "^4.0.1", + "@npmcli/metavuln-calculator": "^8.0.0", + "@npmcli/name-from-folder": "^3.0.0", + "@npmcli/node-gyp": "^4.0.0", + "@npmcli/package-json": "^6.0.1", + "@npmcli/query": "^4.0.0", + "@npmcli/redact": "^3.0.0", + "@npmcli/run-script": "^9.0.1", + "bin-links": "^5.0.0", + "cacache": "^19.0.1", + "common-ancestor-path": "^1.0.1", + "hosted-git-info": "^8.0.0", + "json-parse-even-better-errors": "^4.0.0", + "json-stringify-nice": "^1.1.4", + "lru-cache": "^10.2.2", + "minimatch": "^9.0.4", + "nopt": "^8.0.0", + "npm-install-checks": "^7.1.0", + "npm-package-arg": "^12.0.0", + "npm-pick-manifest": "^10.0.0", + "npm-registry-fetch": "^18.0.1", + "pacote": "^19.0.0", + "parse-conflict-json": "^4.0.0", + "proc-log": "^5.0.0", + "proggy": "^3.0.0", + "promise-all-reject-late": "^1.0.0", + "promise-call-limit": "^3.0.1", + "read-package-json-fast": "^4.0.0", + "semver": "^7.3.7", + "ssri": "^12.0.0", + "treeverse": "^3.0.0", + "walk-up-path": "^3.0.1" }, "bin": { - "webpack-dev-server": "bin/webpack-dev-server.js" + "arborist": "bin/index.js" }, "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^4.37.0 || ^5.0.0" - }, - "peerDependenciesMeta": { - "webpack": { - "optional": true - }, - "webpack-cli": { - "optional": true - } + "node": "^18.17.0 || >=20.5.0" } }, - "node_modules/webpack-dev-server/node_modules/ajv": { - "version": "8.12.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", - "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "node_modules/npm/node_modules/@npmcli/config": { + "version": "9.0.0", "dev": true, + "inBundle": true, + "license": "ISC", "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" + "@npmcli/map-workspaces": "^4.0.1", + "@npmcli/package-json": "^6.0.1", + "ci-info": "^4.0.0", + "ini": "^5.0.0", + "nopt": "^8.0.0", + "proc-log": "^5.0.0", + "semver": "^7.3.5", + "walk-up-path": "^3.0.1" }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" + "engines": { + "node": "^18.17.0 || >=20.5.0" } }, - "node_modules/webpack-dev-server/node_modules/ajv-keywords": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", - "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", + "node_modules/npm/node_modules/@npmcli/fs": { + "version": "4.0.0", "dev": true, + "inBundle": true, + "license": "ISC", "dependencies": { - "fast-deep-equal": "^3.1.3" + "semver": "^7.3.5" }, - "peerDependencies": { - "ajv": "^8.8.2" + "engines": { + "node": "^18.17.0 || >=20.5.0" } }, - "node_modules/webpack-dev-server/node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true - }, - "node_modules/webpack-dev-server/node_modules/schema-utils": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz", - "integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==", + "node_modules/npm/node_modules/@npmcli/git": { + "version": "6.0.1", "dev": true, + "inBundle": true, + "license": "ISC", "dependencies": { - "@types/json-schema": "^7.0.9", - "ajv": "^8.9.0", - "ajv-formats": "^2.1.1", - "ajv-keywords": "^5.1.0" + "@npmcli/promise-spawn": "^8.0.0", + "ini": "^5.0.0", + "lru-cache": "^10.0.1", + "npm-pick-manifest": "^10.0.0", + "proc-log": "^5.0.0", + "promise-inflight": "^1.0.1", + "promise-retry": "^2.0.1", + "semver": "^7.3.5", + "which": "^5.0.0" }, "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" + "node": "^18.17.0 || >=20.5.0" } }, - "node_modules/webpack-merge": { - "version": "5.10.0", - "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.10.0.tgz", - "integrity": "sha512-+4zXKdx7UnO+1jaN4l2lHVD+mFvnlZQP/6ljaJVb4SZiwIKeUnrT5l0gkT8z+n4hKpC+jpOv6O9R+gLtag7pSA==", + "node_modules/npm/node_modules/@npmcli/installed-package-contents": { + "version": "3.0.0", "dev": true, + "inBundle": true, + "license": "ISC", "dependencies": { - "clone-deep": "^4.0.1", - "flat": "^5.0.2", - "wildcard": "^2.0.0" + "npm-bundled": "^4.0.0", + "npm-normalize-package-bin": "^4.0.0" + }, + "bin": { + "installed-package-contents": "bin/index.js" }, "engines": { - "node": ">=10.0.0" + "node": "^18.17.0 || >=20.5.0" } }, - "node_modules/webpack-sources": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz", - "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==", + "node_modules/npm/node_modules/@npmcli/map-workspaces": { + "version": "4.0.1", "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/name-from-folder": "^3.0.0", + "@npmcli/package-json": "^6.0.0", + "glob": "^10.2.2", + "minimatch": "^9.0.0" + }, "engines": { - "node": ">=10.13.0" + "node": "^18.17.0 || >=20.5.0" } }, - "node_modules/websocket-driver": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", - "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", + "node_modules/npm/node_modules/@npmcli/metavuln-calculator": { + "version": "8.0.0", "dev": true, + "inBundle": true, + "license": "ISC", "dependencies": { - "http-parser-js": ">=0.5.1", - "safe-buffer": ">=5.1.0", - "websocket-extensions": ">=0.1.1" + "cacache": "^19.0.0", + "json-parse-even-better-errors": "^4.0.0", + "pacote": "^19.0.0", + "proc-log": "^5.0.0", + "semver": "^7.3.5" }, "engines": { - "node": ">=0.8.0" + "node": "^18.17.0 || >=20.5.0" } }, - "node_modules/websocket-extensions": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", - "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", + "node_modules/npm/node_modules/@npmcli/name-from-folder": { + "version": "3.0.0", "dev": true, + "inBundle": true, + "license": "ISC", "engines": { - "node": ">=0.8.0" + "node": "^18.17.0 || >=20.5.0" } }, - "node_modules/whatwg-encoding": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz", - "integrity": "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==", - "dependencies": { - "iconv-lite": "0.6.3" - }, + "node_modules/npm/node_modules/@npmcli/node-gyp": { + "version": "4.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", "engines": { - "node": ">=18" + "node": "^18.17.0 || >=20.5.0" } }, - "node_modules/whatwg-mimetype": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz", - "integrity": "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==", + "node_modules/npm/node_modules/@npmcli/package-json": { + "version": "6.0.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/git": "^6.0.0", + "glob": "^10.2.2", + "hosted-git-info": "^8.0.0", + "json-parse-even-better-errors": "^4.0.0", + "normalize-package-data": "^7.0.0", + "proc-log": "^5.0.0", + "semver": "^7.5.3" + }, "engines": { - "node": ">=18" + "node": "^18.17.0 || >=20.5.0" } }, - "node_modules/whatwg-url": { - "version": "14.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-14.0.0.tgz", - "integrity": "sha512-1lfMEm2IEr7RIV+f4lUNPOqfFL+pO+Xw3fJSqmjX9AbXcXcYOkCe1P6+9VBZB6n94af16NfZf+sSk0JCBZC9aw==", + "node_modules/npm/node_modules/@npmcli/promise-spawn": { + "version": "8.0.1", + "dev": true, + "inBundle": true, + "license": "ISC", "dependencies": { - "tr46": "^5.0.0", - "webidl-conversions": "^7.0.0" + "which": "^5.0.0" }, "engines": { - "node": ">=18" + "node": "^18.17.0 || >=20.5.0" } }, - "node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "node_modules/npm/node_modules/@npmcli/query": { + "version": "4.0.0", "dev": true, + "inBundle": true, + "license": "ISC", "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" + "postcss-selector-parser": "^6.1.2" }, "engines": { - "node": ">= 8" + "node": "^18.17.0 || >=20.5.0" } }, - "node_modules/wildcard": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.1.tgz", - "integrity": "sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==", - "dev": true - }, - "node_modules/word-wrap": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", - "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "node_modules/npm/node_modules/@npmcli/redact": { + "version": "3.0.0", "dev": true, + "inBundle": true, + "license": "ISC", "engines": { - "node": ">=0.10.0" + "node": "^18.17.0 || >=20.5.0" } }, - "node_modules/wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "node_modules/npm/node_modules/@npmcli/run-script": { + "version": "9.0.1", "dev": true, + "inBundle": true, + "license": "ISC", "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" + "@npmcli/node-gyp": "^4.0.0", + "@npmcli/package-json": "^6.0.0", + "@npmcli/promise-spawn": "^8.0.0", + "node-gyp": "^10.0.0", + "proc-log": "^5.0.0", + "which": "^5.0.0" }, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + "node": "^18.17.0 || >=20.5.0" } }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true + "node_modules/npm/node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=14" + } }, - "node_modules/write": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/write/-/write-0.2.1.tgz", - "integrity": "sha512-CJ17OoULEKXpA5pef3qLj5AxTJ6mSt7g84he2WIskKwqFO4T97d5V7Tadl0DYDk7qyUOQD5WlUlOMChaYrhxeA==", + "node_modules/npm/node_modules/@sigstore/bundle": { + "version": "2.3.2", "dev": true, + "inBundle": true, + "license": "Apache-2.0", "dependencies": { - "mkdirp": "^0.5.1" + "@sigstore/protobuf-specs": "^0.3.2" }, "engines": { - "node": ">=0.10.0" + "node": "^16.14.0 || >=18.0.0" } }, - "node_modules/ws": { - "version": "8.15.1", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.15.1.tgz", - "integrity": "sha512-W5OZiCjXEmk0yZ66ZN82beM5Sz7l7coYxpRkzS+p9PP+ToQry8szKh+61eNktr7EA9DOwvFGhfC605jDHbP6QQ==", + "node_modules/npm/node_modules/@sigstore/core": { + "version": "1.1.0", + "dev": true, + "inBundle": true, + "license": "Apache-2.0", "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": ">=5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } + "node": "^16.14.0 || >=18.0.0" } }, - "node_modules/xml-name-validator": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-5.0.0.tgz", - "integrity": "sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==", + "node_modules/npm/node_modules/@sigstore/protobuf-specs": { + "version": "0.3.2", + "dev": true, + "inBundle": true, + "license": "Apache-2.0", "engines": { - "node": ">=18" + "node": "^16.14.0 || >=18.0.0" } }, - "node_modules/xmlchars": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", - "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==" - }, - "node_modules/y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "node_modules/npm/node_modules/@sigstore/sign": { + "version": "2.3.2", "dev": true, + "inBundle": true, + "license": "Apache-2.0", + "dependencies": { + "@sigstore/bundle": "^2.3.2", + "@sigstore/core": "^1.0.0", + "@sigstore/protobuf-specs": "^0.3.2", + "make-fetch-happen": "^13.0.1", + "proc-log": "^4.2.0", + "promise-retry": "^2.0.1" + }, "engines": { - "node": ">=10" + "node": "^16.14.0 || >=18.0.0" } }, - "node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, - "node_modules/yargs": { - "version": "17.7.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", - "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "node_modules/npm/node_modules/@sigstore/sign/node_modules/@npmcli/agent": { + "version": "2.2.2", "dev": true, + "inBundle": true, + "license": "ISC", "dependencies": { - "cliui": "^8.0.1", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.3", - "y18n": "^5.0.5", - "yargs-parser": "^21.1.1" + "agent-base": "^7.1.0", + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.1", + "lru-cache": "^10.0.1", + "socks-proxy-agent": "^8.0.3" }, "engines": { - "node": ">=12" + "node": "^16.14.0 || >=18.0.0" } }, - "node_modules/yargs-parser": { - "version": "20.2.9", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", - "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "node_modules/npm/node_modules/@sigstore/sign/node_modules/@npmcli/fs": { + "version": "3.1.1", "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "semver": "^7.3.5" + }, "engines": { - "node": ">=10" + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "node_modules/yargs/node_modules/yargs-parser": { - "version": "21.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", - "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "node_modules/npm/node_modules/@sigstore/sign/node_modules/cacache": { + "version": "18.0.4", "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/fs": "^3.1.0", + "fs-minipass": "^3.0.0", + "glob": "^10.2.2", + "lru-cache": "^10.0.1", + "minipass": "^7.0.3", + "minipass-collect": "^2.0.1", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "p-map": "^4.0.0", + "ssri": "^10.0.0", + "tar": "^6.1.11", + "unique-filename": "^3.0.0" + }, "engines": { - "node": ">=12" + "node": "^16.14.0 || >=18.0.0" } }, - "node_modules/yn": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", - "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "node_modules/npm/node_modules/@sigstore/sign/node_modules/make-fetch-happen": { + "version": "13.0.1", "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/agent": "^2.0.0", + "cacache": "^18.0.0", + "http-cache-semantics": "^4.1.1", + "is-lambda": "^1.0.1", + "minipass": "^7.0.2", + "minipass-fetch": "^3.0.0", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "negotiator": "^0.6.3", + "proc-log": "^4.2.0", + "promise-retry": "^2.0.1", + "ssri": "^10.0.0" + }, "engines": { - "node": ">=6" + "node": "^16.14.0 || >=18.0.0" } }, - "node_modules/yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "node_modules/npm/node_modules/@sigstore/sign/node_modules/minipass-fetch": { + "version": "3.0.5", "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "minipass": "^7.0.3", + "minipass-sized": "^1.0.3", + "minizlib": "^2.1.2" + }, "engines": { - "node": ">=10" + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "optionalDependencies": { + "encoding": "^0.1.13" } - } - }, - "dependencies": { - "@babel/code-frame": { - "version": "7.24.2", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.2.tgz", - "integrity": "sha512-y5+tLQyV8pg3fsiln67BVLD1P13Eg4lh5RW9mF0zUuvLrv9uIQ4MCL+CRT+FTsBlBjcIan6PGsLcBN0m3ClUyQ==", + }, + "node_modules/npm/node_modules/@sigstore/sign/node_modules/proc-log": { + "version": "4.2.0", "dev": true, - "requires": { - "@babel/highlight": "^7.24.2", - "picocolors": "^1.0.0" + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "@babel/helper-validator-identifier": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", - "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", - "dev": true - }, - "@babel/highlight": { - "version": "7.24.2", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.2.tgz", - "integrity": "sha512-Yac1ao4flkTxTteCDZLEvdxg2fZfz1v8M4QpaGypq/WPDqg3ijHYbDfs+LG5hvzSoqaSZ9/Z9lKSP3CjZjv+pA==", + "node_modules/npm/node_modules/@sigstore/sign/node_modules/ssri": { + "version": "10.0.6", "dev": true, - "requires": { - "@babel/helper-validator-identifier": "^7.22.20", - "chalk": "^2.4.2", - "js-tokens": "^4.0.0", - "picocolors": "^1.0.0" - }, + "inBundle": true, + "license": "ISC", "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } + "minipass": "^7.0.3" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "@blockly/continuous-toolbox": { - "version": "6.0.9", - "resolved": "https://registry.npmjs.org/@blockly/continuous-toolbox/-/continuous-toolbox-6.0.9.tgz", - "integrity": "sha512-b7WrMeZwxOJJ35aJggJ8ndBt8yUzm2i+HsfmQ78Ti7+xHHlJ2+DMLWORKoDc9HYVtYwiwZzjbJd3LucFm7mE2w==", - "requires": {} - }, - "@blockly/field-colour": { - "version": "5.0.9", - "resolved": "https://registry.npmjs.org/@blockly/field-colour/-/field-colour-5.0.9.tgz", - "integrity": "sha512-ebj4oGwrqkcGKTYjLDHLQYilZ1qfmiPIfi3QVv/ROfSut4VPEf4JEnTmc/AJJrKQgzygdbz02QLZ2DBlVkoWNg==", - "requires": {} - }, - "@commitlint/cli": { - "version": "17.8.1", - "resolved": "https://registry.npmjs.org/@commitlint/cli/-/cli-17.8.1.tgz", - "integrity": "sha512-ay+WbzQesE0Rv4EQKfNbSMiJJ12KdKTDzIt0tcK4k11FdsWmtwP0Kp1NWMOUswfIWo6Eb7p7Ln721Nx9FLNBjg==", + "node_modules/npm/node_modules/@sigstore/sign/node_modules/unique-filename": { + "version": "3.0.0", "dev": true, - "requires": { - "@commitlint/format": "^17.8.1", - "@commitlint/lint": "^17.8.1", - "@commitlint/load": "^17.8.1", - "@commitlint/read": "^17.8.1", - "@commitlint/types": "^17.8.1", - "execa": "^5.0.0", - "lodash.isfunction": "^3.0.9", - "resolve-from": "5.0.0", - "resolve-global": "1.0.0", - "yargs": "^17.0.0" + "inBundle": true, + "license": "ISC", + "dependencies": { + "unique-slug": "^4.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "@commitlint/config-conventional": { - "version": "17.8.1", - "resolved": "https://registry.npmjs.org/@commitlint/config-conventional/-/config-conventional-17.8.1.tgz", - "integrity": "sha512-NxCOHx1kgneig3VLauWJcDWS40DVjg7nKOpBEEK9E5fjJpQqLCilcnKkIIjdBH98kEO1q3NpE5NSrZ2kl/QGJg==", + "node_modules/npm/node_modules/@sigstore/sign/node_modules/unique-slug": { + "version": "4.0.0", "dev": true, - "requires": { - "conventional-changelog-conventionalcommits": "^6.1.0" + "inBundle": true, + "license": "ISC", + "dependencies": { + "imurmurhash": "^0.1.4" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "@commitlint/config-validator": { - "version": "17.8.1", - "resolved": "https://registry.npmjs.org/@commitlint/config-validator/-/config-validator-17.8.1.tgz", - "integrity": "sha512-UUgUC+sNiiMwkyiuIFR7JG2cfd9t/7MV8VB4TZ+q02ZFkHoduUS4tJGsCBWvBOGD9Btev6IecPMvlWUfJorkEA==", + "node_modules/npm/node_modules/@sigstore/tuf": { + "version": "2.3.4", "dev": true, - "requires": { - "@commitlint/types": "^17.8.1", - "ajv": "^8.11.0" - }, + "inBundle": true, + "license": "Apache-2.0", "dependencies": { - "ajv": { - "version": "8.12.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", - "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - } - }, - "json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true - } + "@sigstore/protobuf-specs": "^0.3.2", + "tuf-js": "^2.2.1" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" } }, - "@commitlint/ensure": { - "version": "17.8.1", - "resolved": "https://registry.npmjs.org/@commitlint/ensure/-/ensure-17.8.1.tgz", - "integrity": "sha512-xjafwKxid8s1K23NFpL8JNo6JnY/ysetKo8kegVM7c8vs+kWLP8VrQq+NbhgVlmCojhEDbzQKp4eRXSjVOGsow==", + "node_modules/npm/node_modules/@sigstore/verify": { + "version": "1.2.1", "dev": true, - "requires": { - "@commitlint/types": "^17.8.1", - "lodash.camelcase": "^4.3.0", - "lodash.kebabcase": "^4.1.1", - "lodash.snakecase": "^4.1.1", - "lodash.startcase": "^4.4.0", - "lodash.upperfirst": "^4.3.1" + "inBundle": true, + "license": "Apache-2.0", + "dependencies": { + "@sigstore/bundle": "^2.3.2", + "@sigstore/core": "^1.1.0", + "@sigstore/protobuf-specs": "^0.3.2" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" } }, - "@commitlint/execute-rule": { - "version": "17.8.1", - "resolved": "https://registry.npmjs.org/@commitlint/execute-rule/-/execute-rule-17.8.1.tgz", - "integrity": "sha512-JHVupQeSdNI6xzA9SqMF+p/JjrHTcrJdI02PwesQIDCIGUrv04hicJgCcws5nzaoZbROapPs0s6zeVHoxpMwFQ==", - "dev": true - }, - "@commitlint/format": { - "version": "17.8.1", - "resolved": "https://registry.npmjs.org/@commitlint/format/-/format-17.8.1.tgz", - "integrity": "sha512-f3oMTyZ84M9ht7fb93wbCKmWxO5/kKSbwuYvS867duVomoOsgrgljkGGIztmT/srZnaiGbaK8+Wf8Ik2tSr5eg==", + "node_modules/npm/node_modules/@tufjs/canonical-json": { + "version": "2.0.0", "dev": true, - "requires": { - "@commitlint/types": "^17.8.1", - "chalk": "^4.1.0" + "inBundle": true, + "license": "MIT", + "engines": { + "node": "^16.14.0 || >=18.0.0" } }, - "@commitlint/is-ignored": { - "version": "17.8.1", - "resolved": "https://registry.npmjs.org/@commitlint/is-ignored/-/is-ignored-17.8.1.tgz", - "integrity": "sha512-UshMi4Ltb4ZlNn4F7WtSEugFDZmctzFpmbqvpyxD3la510J+PLcnyhf9chs7EryaRFJMdAKwsEKfNK0jL/QM4g==", + "node_modules/npm/node_modules/@tufjs/models": { + "version": "2.0.1", "dev": true, - "requires": { - "@commitlint/types": "^17.8.1", - "semver": "7.5.4" + "inBundle": true, + "license": "MIT", + "dependencies": { + "@tufjs/canonical-json": "2.0.0", + "minimatch": "^9.0.4" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" } }, - "@commitlint/lint": { - "version": "17.8.1", - "resolved": "https://registry.npmjs.org/@commitlint/lint/-/lint-17.8.1.tgz", - "integrity": "sha512-aQUlwIR1/VMv2D4GXSk7PfL5hIaFSfy6hSHV94O8Y27T5q+DlDEgd/cZ4KmVI+MWKzFfCTiTuWqjfRSfdRllCA==", + "node_modules/npm/node_modules/abbrev": { + "version": "3.0.0", "dev": true, - "requires": { - "@commitlint/is-ignored": "^17.8.1", - "@commitlint/parse": "^17.8.1", - "@commitlint/rules": "^17.8.1", - "@commitlint/types": "^17.8.1" + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^18.17.0 || >=20.5.0" } }, - "@commitlint/load": { - "version": "17.8.1", - "resolved": "https://registry.npmjs.org/@commitlint/load/-/load-17.8.1.tgz", - "integrity": "sha512-iF4CL7KDFstP1kpVUkT8K2Wl17h2yx9VaR1ztTc8vzByWWcbO/WaKwxsnCOqow9tVAlzPfo1ywk9m2oJ9ucMqA==", + "node_modules/npm/node_modules/agent-base": { + "version": "7.1.1", "dev": true, - "requires": { - "@commitlint/config-validator": "^17.8.1", - "@commitlint/execute-rule": "^17.8.1", - "@commitlint/resolve-extends": "^17.8.1", - "@commitlint/types": "^17.8.1", - "@types/node": "20.5.1", - "chalk": "^4.1.0", - "cosmiconfig": "^8.0.0", - "cosmiconfig-typescript-loader": "^4.0.0", - "lodash.isplainobject": "^4.0.6", - "lodash.merge": "^4.6.2", - "lodash.uniq": "^4.5.0", - "resolve-from": "^5.0.0", - "ts-node": "^10.8.1", - "typescript": "^4.6.4 || ^5.2.2" - }, + "inBundle": true, + "license": "MIT", "dependencies": { - "@types/node": { - "version": "20.5.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.5.1.tgz", - "integrity": "sha512-4tT2UrL5LBqDwoed9wZ6N3umC4Yhz3W3FloMmiiG4JwmUJWpie0c7lcnUNd4gtMKuDEO4wRVS8B6Xa0uMRsMKg==", - "dev": true - } + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" } }, - "@commitlint/message": { - "version": "17.8.1", - "resolved": "https://registry.npmjs.org/@commitlint/message/-/message-17.8.1.tgz", - "integrity": "sha512-6bYL1GUQsD6bLhTH3QQty8pVFoETfFQlMn2Nzmz3AOLqRVfNNtXBaSY0dhZ0dM6A2MEq4+2d7L/2LP8TjqGRkA==", - "dev": true - }, - "@commitlint/parse": { - "version": "17.8.1", - "resolved": "https://registry.npmjs.org/@commitlint/parse/-/parse-17.8.1.tgz", - "integrity": "sha512-/wLUickTo0rNpQgWwLPavTm7WbwkZoBy3X8PpkUmlSmQJyWQTj0m6bDjiykMaDt41qcUbfeFfaCvXfiR4EGnfw==", + "node_modules/npm/node_modules/aggregate-error": { + "version": "3.1.0", "dev": true, - "requires": { - "@commitlint/types": "^17.8.1", - "conventional-changelog-angular": "^6.0.0", - "conventional-commits-parser": "^4.0.0" + "inBundle": true, + "license": "MIT", + "dependencies": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + }, + "engines": { + "node": ">=8" } }, - "@commitlint/read": { - "version": "17.8.1", - "resolved": "https://registry.npmjs.org/@commitlint/read/-/read-17.8.1.tgz", - "integrity": "sha512-Fd55Oaz9irzBESPCdMd8vWWgxsW3OWR99wOntBDHgf9h7Y6OOHjWEdS9Xzen1GFndqgyoaFplQS5y7KZe0kO2w==", + "node_modules/npm/node_modules/ansi-regex": { + "version": "5.0.1", "dev": true, - "requires": { - "@commitlint/top-level": "^17.8.1", - "@commitlint/types": "^17.8.1", - "fs-extra": "^11.0.0", - "git-raw-commits": "^2.0.11", - "minimist": "^1.2.6" + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=8" } }, - "@commitlint/resolve-extends": { - "version": "17.8.1", - "resolved": "https://registry.npmjs.org/@commitlint/resolve-extends/-/resolve-extends-17.8.1.tgz", - "integrity": "sha512-W/ryRoQ0TSVXqJrx5SGkaYuAaE/BUontL1j1HsKckvM6e5ZaG0M9126zcwL6peKSuIetJi7E87PRQF8O86EW0Q==", + "node_modules/npm/node_modules/ansi-styles": { + "version": "6.2.1", "dev": true, - "requires": { - "@commitlint/config-validator": "^17.8.1", - "@commitlint/types": "^17.8.1", - "import-fresh": "^3.0.0", - "lodash.mergewith": "^4.6.2", - "resolve-from": "^5.0.0", - "resolve-global": "^1.0.0" + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "@commitlint/rules": { - "version": "17.8.1", - "resolved": "https://registry.npmjs.org/@commitlint/rules/-/rules-17.8.1.tgz", - "integrity": "sha512-2b7OdVbN7MTAt9U0vKOYKCDsOvESVXxQmrvuVUZ0rGFMCrCPJWWP1GJ7f0lAypbDAhaGb8zqtdOr47192LBrIA==", + "node_modules/npm/node_modules/aproba": { + "version": "2.0.0", "dev": true, - "requires": { - "@commitlint/ensure": "^17.8.1", - "@commitlint/message": "^17.8.1", - "@commitlint/to-lines": "^17.8.1", - "@commitlint/types": "^17.8.1", - "execa": "^5.0.0" - } + "inBundle": true, + "license": "ISC" }, - "@commitlint/to-lines": { - "version": "17.8.1", - "resolved": "https://registry.npmjs.org/@commitlint/to-lines/-/to-lines-17.8.1.tgz", - "integrity": "sha512-LE0jb8CuR/mj6xJyrIk8VLz03OEzXFgLdivBytoooKO5xLt5yalc8Ma5guTWobw998sbR3ogDd+2jed03CFmJA==", - "dev": true + "node_modules/npm/node_modules/archy": { + "version": "1.0.0", + "dev": true, + "inBundle": true, + "license": "MIT" }, - "@commitlint/top-level": { - "version": "17.8.1", - "resolved": "https://registry.npmjs.org/@commitlint/top-level/-/top-level-17.8.1.tgz", - "integrity": "sha512-l6+Z6rrNf5p333SHfEte6r+WkOxGlWK4bLuZKbtf/2TXRN+qhrvn1XE63VhD8Oe9oIHQ7F7W1nG2k/TJFhx2yA==", + "node_modules/npm/node_modules/balanced-match": { + "version": "1.0.2", "dev": true, - "requires": { - "find-up": "^5.0.0" - }, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/bin-links": { + "version": "5.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", "dependencies": { - "find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dev": true, - "requires": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - } - }, - "locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dev": true, - "requires": { - "p-locate": "^5.0.0" - } - }, - "p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, - "requires": { - "yocto-queue": "^0.1.0" - } - }, - "p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dev": true, - "requires": { - "p-limit": "^3.0.2" - } - } + "cmd-shim": "^7.0.0", + "npm-normalize-package-bin": "^4.0.0", + "proc-log": "^5.0.0", + "read-cmd-shim": "^5.0.0", + "write-file-atomic": "^6.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" } }, - "@commitlint/types": { - "version": "17.8.1", - "resolved": "https://registry.npmjs.org/@commitlint/types/-/types-17.8.1.tgz", - "integrity": "sha512-PXDQXkAmiMEG162Bqdh9ChML/GJZo6vU+7F03ALKDK8zYc6SuAr47LjG7hGYRqUOz+WK0dU7bQ0xzuqFMdxzeQ==", + "node_modules/npm/node_modules/binary-extensions": { + "version": "2.3.0", "dev": true, - "requires": { - "chalk": "^4.1.0" + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "@cspotcode/source-map-support": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", - "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "node_modules/npm/node_modules/brace-expansion": { + "version": "2.0.1", "dev": true, - "requires": { - "@jridgewell/trace-mapping": "0.3.9" - }, + "inBundle": true, + "license": "MIT", "dependencies": { - "@jridgewell/trace-mapping": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", - "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", - "dev": true, - "requires": { - "@jridgewell/resolve-uri": "^3.0.3", - "@jridgewell/sourcemap-codec": "^1.4.10" - } - } + "balanced-match": "^1.0.0" } }, - "@discoveryjs/json-ext": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz", - "integrity": "sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==", - "dev": true - }, - "@jridgewell/gen-mapping": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", - "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", + "node_modules/npm/node_modules/cacache": { + "version": "19.0.1", "dev": true, - "requires": { - "@jridgewell/set-array": "^1.0.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.9" + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/fs": "^4.0.0", + "fs-minipass": "^3.0.0", + "glob": "^10.2.2", + "lru-cache": "^10.0.1", + "minipass": "^7.0.3", + "minipass-collect": "^2.0.1", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "p-map": "^7.0.2", + "ssri": "^12.0.0", + "tar": "^7.4.3", + "unique-filename": "^4.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" } }, - "@jridgewell/resolve-uri": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", - "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==", - "dev": true + "node_modules/npm/node_modules/cacache/node_modules/chownr": { + "version": "3.0.0", + "dev": true, + "inBundle": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=18" + } }, - "@jridgewell/set-array": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", - "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", - "dev": true + "node_modules/npm/node_modules/cacache/node_modules/minizlib": { + "version": "3.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "minipass": "^7.0.4", + "rimraf": "^5.0.5" + }, + "engines": { + "node": ">= 18" + } }, - "@jridgewell/source-map": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.5.tgz", - "integrity": "sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ==", + "node_modules/npm/node_modules/cacache/node_modules/mkdirp": { + "version": "3.0.1", "dev": true, - "requires": { - "@jridgewell/gen-mapping": "^0.3.0", - "@jridgewell/trace-mapping": "^0.3.9" + "inBundle": true, + "license": "MIT", + "bin": { + "mkdirp": "dist/cjs/src/bin.js" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "@jridgewell/sourcemap-codec": { - "version": "1.4.15", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", - "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", - "dev": true + "node_modules/npm/node_modules/cacache/node_modules/p-map": { + "version": "7.0.2", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, - "@jridgewell/trace-mapping": { - "version": "0.3.20", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.20.tgz", - "integrity": "sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q==", + "node_modules/npm/node_modules/cacache/node_modules/tar": { + "version": "7.4.3", "dev": true, - "requires": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" + "inBundle": true, + "license": "ISC", + "dependencies": { + "@isaacs/fs-minipass": "^4.0.0", + "chownr": "^3.0.0", + "minipass": "^7.1.2", + "minizlib": "^3.0.1", + "mkdirp": "^3.0.1", + "yallist": "^5.0.0" + }, + "engines": { + "node": ">=18" } }, - "@leichtgewicht/ip-codec": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.4.tgz", - "integrity": "sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A==", - "dev": true - }, - "@tsconfig/node10": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz", - "integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==", - "dev": true - }, - "@tsconfig/node12": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", - "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", - "dev": true + "node_modules/npm/node_modules/cacache/node_modules/yallist": { + "version": "5.0.0", + "dev": true, + "inBundle": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=18" + } }, - "@tsconfig/node14": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", - "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", - "dev": true + "node_modules/npm/node_modules/chalk": { + "version": "5.3.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } }, - "@tsconfig/node16": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", - "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", - "dev": true + "node_modules/npm/node_modules/chownr": { + "version": "2.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "engines": { + "node": ">=10" + } }, - "@types/body-parser": { - "version": "1.19.5", - "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz", - "integrity": "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==", + "node_modules/npm/node_modules/ci-info": { + "version": "4.0.0", "dev": true, - "requires": { - "@types/connect": "*", - "@types/node": "*" + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=8" } }, - "@types/bonjour": { - "version": "3.5.13", - "resolved": "https://registry.npmjs.org/@types/bonjour/-/bonjour-3.5.13.tgz", - "integrity": "sha512-z9fJ5Im06zvUL548KvYNecEVlA7cVDkGUi6kZusb04mpyEFKCIZJvloCcmpmLaIahDpOQGHaHmG6imtPMmPXGQ==", + "node_modules/npm/node_modules/cidr-regex": { + "version": "4.1.1", "dev": true, - "requires": { - "@types/node": "*" + "inBundle": true, + "license": "BSD-2-Clause", + "dependencies": { + "ip-regex": "^5.0.0" + }, + "engines": { + "node": ">=14" } }, - "@types/connect": { - "version": "3.4.38", - "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", - "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", + "node_modules/npm/node_modules/clean-stack": { + "version": "2.2.0", "dev": true, - "requires": { - "@types/node": "*" + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=6" } }, - "@types/connect-history-api-fallback": { - "version": "1.5.4", - "resolved": "https://registry.npmjs.org/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.5.4.tgz", - "integrity": "sha512-n6Cr2xS1h4uAulPRdlw6Jl6s1oG8KrVilPN2yUITEs+K48EzMJJ3W1xy8K5eWuFvjp3R74AOIGSmp2UfBJ8HFw==", + "node_modules/npm/node_modules/cli-columns": { + "version": "4.0.0", "dev": true, - "requires": { - "@types/express-serve-static-core": "*", - "@types/node": "*" + "inBundle": true, + "license": "MIT", + "dependencies": { + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">= 10" } }, - "@types/eslint": { - "version": "8.56.0", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.0.tgz", - "integrity": "sha512-FlsN0p4FhuYRjIxpbdXovvHQhtlG05O1GG/RNWvdAxTboR438IOTwmrY/vLA+Xfgg06BTkP045M3vpFwTMv1dg==", + "node_modules/npm/node_modules/cmd-shim": { + "version": "7.0.0", "dev": true, - "requires": { - "@types/estree": "*", - "@types/json-schema": "*" + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^18.17.0 || >=20.5.0" } }, - "@types/eslint-scope": { - "version": "3.7.7", - "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz", - "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==", + "node_modules/npm/node_modules/color-convert": { + "version": "2.0.1", "dev": true, - "requires": { - "@types/eslint": "*", - "@types/estree": "*" + "inBundle": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" } }, - "@types/estree": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", - "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", - "dev": true + "node_modules/npm/node_modules/color-name": { + "version": "1.1.4", + "dev": true, + "inBundle": true, + "license": "MIT" }, - "@types/express": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz", - "integrity": "sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==", + "node_modules/npm/node_modules/common-ancestor-path": { + "version": "1.0.1", "dev": true, - "requires": { - "@types/body-parser": "*", - "@types/express-serve-static-core": "^4.17.33", - "@types/qs": "*", - "@types/serve-static": "*" + "inBundle": true, + "license": "ISC" + }, + "node_modules/npm/node_modules/cross-spawn": { + "version": "7.0.3", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" } }, - "@types/express-serve-static-core": { - "version": "4.17.41", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.41.tgz", - "integrity": "sha512-OaJ7XLaelTgrvlZD8/aa0vvvxZdUmlCn6MtWeB7TkiKW70BQLc9XEPpDLPdbo52ZhXUCrznlWdCHWxJWtdyajA==", + "node_modules/npm/node_modules/cross-spawn/node_modules/which": { + "version": "2.0.2", "dev": true, - "requires": { - "@types/node": "*", - "@types/qs": "*", - "@types/range-parser": "*", - "@types/send": "*" + "inBundle": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" } }, - "@types/http-errors": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz", - "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==", - "dev": true + "node_modules/npm/node_modules/cssesc": { + "version": "3.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } }, - "@types/http-proxy": { - "version": "1.17.14", - "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.14.tgz", - "integrity": "sha512-SSrD0c1OQzlFX7pGu1eXxSEjemej64aaNPRhhVYUGqXh0BtldAAx37MG8btcumvpgKyZp1F5Gn3JkktdxiFv6w==", + "node_modules/npm/node_modules/debug": { + "version": "4.3.6", "dev": true, - "requires": { - "@types/node": "*" + "inBundle": true, + "license": "MIT", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } } }, - "@types/json-schema": { - "version": "7.0.15", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", - "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", - "dev": true + "node_modules/npm/node_modules/debug/node_modules/ms": { + "version": "2.1.2", + "dev": true, + "inBundle": true, + "license": "MIT" }, - "@types/mime": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", - "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==", - "dev": true + "node_modules/npm/node_modules/diff": { + "version": "5.2.0", + "dev": true, + "inBundle": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.3.1" + } }, - "@types/minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-hov8bUuiLiyFPGyFPE1lwWhmzYbirOXQNNo40+y3zow8aFVTeyn3VWL0VFFfdNddA8S4Vf0Tc062rzyNr7Paag==", - "dev": true + "node_modules/npm/node_modules/eastasianwidth": { + "version": "0.2.0", + "dev": true, + "inBundle": true, + "license": "MIT" }, - "@types/node": { - "version": "20.10.5", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.10.5.tgz", - "integrity": "sha512-nNPsNE65wjMxEKI93yOP+NPGGBJz/PoN3kZsVLee0XMiJolxSekEVD8wRwBUBqkwc7UWop0edW50yrCQW4CyRw==", + "node_modules/npm/node_modules/emoji-regex": { + "version": "8.0.0", "dev": true, - "requires": { - "undici-types": "~5.26.4" + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/encoding": { + "version": "0.1.13", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true, + "dependencies": { + "iconv-lite": "^0.6.2" } }, - "@types/node-forge": { - "version": "1.3.10", - "resolved": "https://registry.npmjs.org/@types/node-forge/-/node-forge-1.3.10.tgz", - "integrity": "sha512-y6PJDYN4xYBxwd22l+OVH35N+1fCYWiuC3aiP2SlXVE6Lo7SS+rSx9r89hLxrP4pn6n1lBGhHJ12pj3F3Mpttw==", + "node_modules/npm/node_modules/env-paths": { + "version": "2.2.1", "dev": true, - "requires": { - "@types/node": "*" + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=6" } }, - "@types/normalize-package-data": { - "version": "2.4.4", - "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.4.tgz", - "integrity": "sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==", - "dev": true + "node_modules/npm/node_modules/err-code": { + "version": "2.0.3", + "dev": true, + "inBundle": true, + "license": "MIT" }, - "@types/qs": { - "version": "6.9.10", - "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.10.tgz", - "integrity": "sha512-3Gnx08Ns1sEoCrWssEgTSJs/rsT2vhGP+Ja9cnnk9k4ALxinORlQneLXFeFKOTJMOeZUFD1s7w+w2AphTpvzZw==", - "dev": true + "node_modules/npm/node_modules/exponential-backoff": { + "version": "3.1.1", + "dev": true, + "inBundle": true, + "license": "Apache-2.0" }, - "@types/range-parser": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", - "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==", - "dev": true - }, - "@types/retry": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.0.tgz", - "integrity": "sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==", - "dev": true - }, - "@types/send": { - "version": "0.17.4", - "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz", - "integrity": "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==", + "node_modules/npm/node_modules/fastest-levenshtein": { + "version": "1.0.16", "dev": true, - "requires": { - "@types/mime": "^1", - "@types/node": "*" + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">= 4.9.1" } }, - "@types/serve-index": { - "version": "1.9.4", - "resolved": "https://registry.npmjs.org/@types/serve-index/-/serve-index-1.9.4.tgz", - "integrity": "sha512-qLpGZ/c2fhSs5gnYsQxtDEq3Oy8SXPClIXkW5ghvAvsNuVSA8k+gCONcUCS/UjLEYvYps+e8uBtfgXgvhwfNug==", + "node_modules/npm/node_modules/foreground-child": { + "version": "3.3.0", "dev": true, - "requires": { - "@types/express": "*" + "inBundle": true, + "license": "ISC", + "dependencies": { + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "@types/serve-static": { - "version": "1.15.5", - "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.5.tgz", - "integrity": "sha512-PDRk21MnK70hja/YF8AHfC7yIsiQHn1rcXx7ijCFBX/k+XQJhQT/gw3xekXKJvx+5SXaMMS8oqQy09Mzvz2TuQ==", + "node_modules/npm/node_modules/fs-minipass": { + "version": "3.0.3", "dev": true, - "requires": { - "@types/http-errors": "*", - "@types/mime": "*", - "@types/node": "*" + "inBundle": true, + "license": "ISC", + "dependencies": { + "minipass": "^7.0.3" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "@types/sockjs": { - "version": "0.3.36", - "resolved": "https://registry.npmjs.org/@types/sockjs/-/sockjs-0.3.36.tgz", - "integrity": "sha512-MK9V6NzAS1+Ud7JV9lJLFqW85VbC9dq3LmwZCuBe4wBDgKC0Kj/jd8Xl+nSviU+Qc3+m7umHHyHg//2KSa0a0Q==", + "node_modules/npm/node_modules/glob": { + "version": "10.4.5", "dev": true, - "requires": { - "@types/node": "*" + "inBundle": true, + "license": "ISC", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "@types/ws": { - "version": "8.5.10", - "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.10.tgz", - "integrity": "sha512-vmQSUcfalpIq0R9q7uTo2lXs6eGIpt9wtnLdMv9LVpIjCA/+ufZRozlVoVelIYixx1ugCBKDhn89vnsEGOCx9A==", + "node_modules/npm/node_modules/graceful-fs": { + "version": "4.2.11", "dev": true, - "requires": { - "@types/node": "*" - } + "inBundle": true, + "license": "ISC" }, - "@webassemblyjs/ast": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.6.tgz", - "integrity": "sha512-IN1xI7PwOvLPgjcf180gC1bqn3q/QaOCwYUahIOhbYUu8KA/3tw2RT/T0Gidi1l7Hhj5D/INhJxiICObqpMu4Q==", + "node_modules/npm/node_modules/hosted-git-info": { + "version": "8.0.0", "dev": true, - "requires": { - "@webassemblyjs/helper-numbers": "1.11.6", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6" + "inBundle": true, + "license": "ISC", + "dependencies": { + "lru-cache": "^10.0.1" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" } }, - "@webassemblyjs/floating-point-hex-parser": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz", - "integrity": "sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==", - "dev": true - }, - "@webassemblyjs/helper-api-error": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz", - "integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==", - "dev": true - }, - "@webassemblyjs/helper-buffer": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.6.tgz", - "integrity": "sha512-z3nFzdcp1mb8nEOFFk8DrYLpHvhKC3grJD2ardfKOzmbmJvEf/tPIqCY+sNcwZIY8ZD7IkB2l7/pqhUhqm7hLA==", - "dev": true + "node_modules/npm/node_modules/http-cache-semantics": { + "version": "4.1.1", + "dev": true, + "inBundle": true, + "license": "BSD-2-Clause" }, - "@webassemblyjs/helper-numbers": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz", - "integrity": "sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==", + "node_modules/npm/node_modules/http-proxy-agent": { + "version": "7.0.2", "dev": true, - "requires": { - "@webassemblyjs/floating-point-hex-parser": "1.11.6", - "@webassemblyjs/helper-api-error": "1.11.6", - "@xtuc/long": "4.2.2" + "inBundle": true, + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.0", + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" } }, - "@webassemblyjs/helper-wasm-bytecode": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz", - "integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==", - "dev": true - }, - "@webassemblyjs/helper-wasm-section": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.6.tgz", - "integrity": "sha512-LPpZbSOwTpEC2cgn4hTydySy1Ke+XEu+ETXuoyvuyezHO3Kjdu90KK95Sh9xTbmjrCsUwvWwCOQQNta37VrS9g==", + "node_modules/npm/node_modules/https-proxy-agent": { + "version": "7.0.5", "dev": true, - "requires": { - "@webassemblyjs/ast": "1.11.6", - "@webassemblyjs/helper-buffer": "1.11.6", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/wasm-gen": "1.11.6" + "inBundle": true, + "license": "MIT", + "dependencies": { + "agent-base": "^7.0.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" } }, - "@webassemblyjs/ieee754": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz", - "integrity": "sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==", + "node_modules/npm/node_modules/iconv-lite": { + "version": "0.6.3", "dev": true, - "requires": { - "@xtuc/ieee754": "^1.2.0" + "inBundle": true, + "license": "MIT", + "optional": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" } }, - "@webassemblyjs/leb128": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.6.tgz", - "integrity": "sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==", + "node_modules/npm/node_modules/ignore-walk": { + "version": "7.0.0", "dev": true, - "requires": { - "@xtuc/long": "4.2.2" + "inBundle": true, + "license": "ISC", + "dependencies": { + "minimatch": "^9.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" } }, - "@webassemblyjs/utf8": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.6.tgz", - "integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==", - "dev": true - }, - "@webassemblyjs/wasm-edit": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.6.tgz", - "integrity": "sha512-Ybn2I6fnfIGuCR+Faaz7YcvtBKxvoLV3Lebn1tM4o/IAJzmi9AWYIPWpyBfU8cC+JxAO57bk4+zdsTjJR+VTOw==", + "node_modules/npm/node_modules/imurmurhash": { + "version": "0.1.4", "dev": true, - "requires": { - "@webassemblyjs/ast": "1.11.6", - "@webassemblyjs/helper-buffer": "1.11.6", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/helper-wasm-section": "1.11.6", - "@webassemblyjs/wasm-gen": "1.11.6", - "@webassemblyjs/wasm-opt": "1.11.6", - "@webassemblyjs/wasm-parser": "1.11.6", - "@webassemblyjs/wast-printer": "1.11.6" + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=0.8.19" } }, - "@webassemblyjs/wasm-gen": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.6.tgz", - "integrity": "sha512-3XOqkZP/y6B4F0PBAXvI1/bky7GryoogUtfwExeP/v7Nzwo1QLcq5oQmpKlftZLbT+ERUOAZVQjuNVak6UXjPA==", + "node_modules/npm/node_modules/indent-string": { + "version": "4.0.0", "dev": true, - "requires": { - "@webassemblyjs/ast": "1.11.6", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/ieee754": "1.11.6", - "@webassemblyjs/leb128": "1.11.6", - "@webassemblyjs/utf8": "1.11.6" + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=8" } }, - "@webassemblyjs/wasm-opt": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.6.tgz", - "integrity": "sha512-cOrKuLRE7PCe6AsOVl7WasYf3wbSo4CeOk6PkrjS7g57MFfVUF9u6ysQBBODX0LdgSvQqRiGz3CXvIDKcPNy4g==", + "node_modules/npm/node_modules/ini": { + "version": "5.0.0", "dev": true, - "requires": { - "@webassemblyjs/ast": "1.11.6", - "@webassemblyjs/helper-buffer": "1.11.6", - "@webassemblyjs/wasm-gen": "1.11.6", - "@webassemblyjs/wasm-parser": "1.11.6" + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^18.17.0 || >=20.5.0" } }, - "@webassemblyjs/wasm-parser": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.6.tgz", - "integrity": "sha512-6ZwPeGzMJM3Dqp3hCsLgESxBGtT/OeCvCZ4TA1JUPYgmhAx38tTPR9JaKy0S5H3evQpO/h2uWs2j6Yc/fjkpTQ==", + "node_modules/npm/node_modules/init-package-json": { + "version": "7.0.1", "dev": true, - "requires": { - "@webassemblyjs/ast": "1.11.6", - "@webassemblyjs/helper-api-error": "1.11.6", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/ieee754": "1.11.6", - "@webassemblyjs/leb128": "1.11.6", - "@webassemblyjs/utf8": "1.11.6" + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/package-json": "^6.0.0", + "npm-package-arg": "^12.0.0", + "promzard": "^2.0.0", + "read": "^4.0.0", + "semver": "^7.3.5", + "validate-npm-package-license": "^3.0.4", + "validate-npm-package-name": "^6.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" } }, - "@webassemblyjs/wast-printer": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.6.tgz", - "integrity": "sha512-JM7AhRcE+yW2GWYaKeHL5vt4xqee5N2WcezptmgyhNS+ScggqcT1OtXykhAb13Sn5Yas0j2uv9tHgrjwvzAP4A==", + "node_modules/npm/node_modules/ip-address": { + "version": "9.0.5", "dev": true, - "requires": { - "@webassemblyjs/ast": "1.11.6", - "@xtuc/long": "4.2.2" + "inBundle": true, + "license": "MIT", + "dependencies": { + "jsbn": "1.1.0", + "sprintf-js": "^1.1.3" + }, + "engines": { + "node": ">= 12" } }, - "@webpack-cli/configtest": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-1.2.0.tgz", - "integrity": "sha512-4FB8Tj6xyVkyqjj1OaTqCjXYULB9FMkqQ8yGrZjRDrYh0nOE+7Lhs45WioWQQMV+ceFlE368Ukhe6xdvJM9Egg==", + "node_modules/npm/node_modules/ip-regex": { + "version": "5.0.0", "dev": true, - "requires": {} + "inBundle": true, + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, - "@webpack-cli/info": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-1.5.0.tgz", - "integrity": "sha512-e8tSXZpw2hPl2uMJY6fsMswaok5FdlGNRTktvFk2sD8RjH0hE2+XistawJx1vmKteh4NmGmNUrp+Tb2w+udPcQ==", + "node_modules/npm/node_modules/is-cidr": { + "version": "5.1.0", "dev": true, - "requires": { - "envinfo": "^7.7.3" + "inBundle": true, + "license": "BSD-2-Clause", + "dependencies": { + "cidr-regex": "^4.1.1" + }, + "engines": { + "node": ">=14" } }, - "@webpack-cli/serve": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-1.7.0.tgz", - "integrity": "sha512-oxnCNGj88fL+xzV+dacXs44HcDwf1ovs3AuEzvP7mqXw7fQntqIhQ1BRmynh4qEKQSSSRSWVyXRjmTbZIX9V2Q==", + "node_modules/npm/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", "dev": true, - "requires": {} + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=8" + } }, - "@xtuc/ieee754": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", - "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", - "dev": true + "node_modules/npm/node_modules/is-lambda": { + "version": "1.0.1", + "dev": true, + "inBundle": true, + "license": "MIT" }, - "@xtuc/long": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", - "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", - "dev": true + "node_modules/npm/node_modules/isexe": { + "version": "2.0.0", + "dev": true, + "inBundle": true, + "license": "ISC" }, - "abab": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz", - "integrity": "sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==", - "dev": true + "node_modules/npm/node_modules/jackspeak": { + "version": "3.4.3", + "dev": true, + "inBundle": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } }, - "accepts": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", - "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "node_modules/npm/node_modules/jsbn": { + "version": "1.1.0", "dev": true, - "requires": { - "mime-types": "~2.1.34", - "negotiator": "0.6.3" + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/json-parse-even-better-errors": { + "version": "4.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": "^18.17.0 || >=20.5.0" } }, - "acorn": { - "version": "8.11.2", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.2.tgz", - "integrity": "sha512-nc0Axzp/0FILLEVsm4fNwLCwMttvhEI263QtVPQcbpfZZ3ts0hLsZGOpE6czNlid7CJ9MlyH8reXkpsf3YUY4w==", - "dev": true + "node_modules/npm/node_modules/json-stringify-nice": { + "version": "1.1.4", + "dev": true, + "inBundle": true, + "license": "ISC", + "funding": { + "url": "https://github.com/sponsors/isaacs" + } }, - "acorn-import-assertions": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz", - "integrity": "sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==", + "node_modules/npm/node_modules/jsonparse": { + "version": "1.3.1", "dev": true, - "requires": {} + "engines": [ + "node >= 0.2.0" + ], + "inBundle": true, + "license": "MIT" }, - "acorn-jsx": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz", - "integrity": "sha512-AU7pnZkguthwBjKgCg6998ByQNIMjbuDQZ8bb78QAFZwPfmKia8AIzgY/gWgqCjnht8JLdXmB4YxA0KaV60ncQ==", + "node_modules/npm/node_modules/just-diff": { + "version": "6.0.2", "dev": true, - "requires": { - "acorn": "^3.0.4" + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/just-diff-apply": { + "version": "5.5.0", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/libnpmaccess": { + "version": "9.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "npm-package-arg": "^12.0.0", + "npm-registry-fetch": "^18.0.1" }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/libnpmdiff": { + "version": "7.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", "dependencies": { - "acorn": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz", - "integrity": "sha512-OLUyIIZ7mF5oaAUT1w0TFqQS81q3saT46x8t7ukpPjMNk+nbs4ZHhs7ToV8EWnLYLepjETXd4XaCE4uxkMeqUw==", - "dev": true - } + "@npmcli/arborist": "^8.0.0", + "@npmcli/installed-package-contents": "^3.0.0", + "binary-extensions": "^2.3.0", + "diff": "^5.1.0", + "minimatch": "^9.0.4", + "npm-package-arg": "^12.0.0", + "pacote": "^19.0.0", + "tar": "^6.2.1" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" } }, - "acorn-walk": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.2.tgz", - "integrity": "sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==", - "dev": true + "node_modules/npm/node_modules/libnpmexec": { + "version": "9.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/arborist": "^8.0.0", + "@npmcli/run-script": "^9.0.1", + "ci-info": "^4.0.0", + "npm-package-arg": "^12.0.0", + "pacote": "^19.0.0", + "proc-log": "^5.0.0", + "read": "^4.0.0", + "read-package-json-fast": "^4.0.0", + "semver": "^7.3.7", + "walk-up-path": "^3.0.1" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } }, - "agent-base": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz", - "integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==", - "requires": { - "debug": "^4.3.4" + "node_modules/npm/node_modules/libnpmfund": { + "version": "6.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/arborist": "^8.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" } }, - "ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "node_modules/npm/node_modules/libnpmhook": { + "version": "11.0.0", "dev": true, - "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" + "inBundle": true, + "license": "ISC", + "dependencies": { + "aproba": "^2.0.0", + "npm-registry-fetch": "^18.0.1" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" } }, - "ajv-formats": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", - "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", + "node_modules/npm/node_modules/libnpmorg": { + "version": "7.0.0", "dev": true, - "requires": { - "ajv": "^8.0.0" + "inBundle": true, + "license": "ISC", + "dependencies": { + "aproba": "^2.0.0", + "npm-registry-fetch": "^18.0.1" }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/libnpmpack": { + "version": "8.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", "dependencies": { - "ajv": { - "version": "8.12.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", - "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - } - }, - "json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true - } + "@npmcli/arborist": "^8.0.0", + "@npmcli/run-script": "^9.0.1", + "npm-package-arg": "^12.0.0", + "pacote": "^19.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" } }, - "ajv-keywords": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", - "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "node_modules/npm/node_modules/libnpmpublish": { + "version": "10.0.0", "dev": true, - "requires": {} + "inBundle": true, + "license": "ISC", + "dependencies": { + "ci-info": "^4.0.0", + "normalize-package-data": "^7.0.0", + "npm-package-arg": "^12.0.0", + "npm-registry-fetch": "^18.0.1", + "proc-log": "^5.0.0", + "semver": "^7.3.7", + "sigstore": "^2.2.0", + "ssri": "^12.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } }, - "ansi-escapes": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz", - "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==", - "dev": true + "node_modules/npm/node_modules/libnpmsearch": { + "version": "8.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "npm-registry-fetch": "^18.0.1" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } }, - "ansi-html-community": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/ansi-html-community/-/ansi-html-community-0.0.8.tgz", - "integrity": "sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw==", - "dev": true + "node_modules/npm/node_modules/libnpmteam": { + "version": "7.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "aproba": "^2.0.0", + "npm-registry-fetch": "^18.0.1" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } }, - "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true + "node_modules/npm/node_modules/libnpmversion": { + "version": "7.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/git": "^6.0.1", + "@npmcli/run-script": "^9.0.1", + "json-parse-even-better-errors": "^4.0.0", + "proc-log": "^5.0.0", + "semver": "^7.3.7" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } }, - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "node_modules/npm/node_modules/lru-cache": { + "version": "10.4.3", "dev": true, - "requires": { - "color-convert": "^2.0.1" + "inBundle": true, + "license": "ISC" + }, + "node_modules/npm/node_modules/make-fetch-happen": { + "version": "14.0.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/agent": "^3.0.0", + "cacache": "^19.0.1", + "http-cache-semantics": "^4.1.1", + "minipass": "^7.0.2", + "minipass-fetch": "^4.0.0", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "negotiator": "^0.6.3", + "proc-log": "^5.0.0", + "promise-retry": "^2.0.1", + "ssri": "^12.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" } }, - "anymatch": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", - "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "node_modules/npm/node_modules/minimatch": { + "version": "9.0.5", "dev": true, - "requires": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" + "inBundle": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "arg": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", - "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", - "dev": true + "node_modules/npm/node_modules/minipass": { + "version": "7.1.2", + "dev": true, + "inBundle": true, + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } }, - "argparse": { + "node_modules/npm/node_modules/minipass-collect": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true - }, - "array-flatten": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-2.1.2.tgz", - "integrity": "sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ==", - "dev": true + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "minipass": "^7.0.3" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + } }, - "array-ify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/array-ify/-/array-ify-1.0.0.tgz", - "integrity": "sha512-c5AMf34bKdvPhQ7tBGhqkgKNUzMr4WUs+WDtC2ZUGOUncbxKMTvqxYctiseW3+L4bA8ec+GcZ6/A/FW4m8ukng==", - "dev": true - }, - "arrify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==", - "dev": true - }, - "asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" - }, - "babel-code-frame": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", - "integrity": "sha512-XqYMR2dfdGMW+hd0IUZ2PwK+fGeFkOxZJ0wY+JaQAHzt1Zx8LcvpiZD2NiGkEG8qx0CfkAOr5xt76d1e8vG90g==", + "node_modules/npm/node_modules/minipass-fetch": { + "version": "4.0.0", "dev": true, - "requires": { - "chalk": "^1.1.3", - "esutils": "^2.0.2", - "js-tokens": "^3.0.2" - }, + "inBundle": true, + "license": "MIT", "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", - "dev": true - }, - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha512-kmCevFghRiWM7HB5zTPULl4r9bVFSWjz62MhqizDGUrq2NWuNMQyuv4tHHoKJHs69M/MF64lEcHdYIocrdWQYA==", - "dev": true - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha512-U3lRVLMSlsCfjqYPbLyVv11M9CPW4I728d6TCKMAOJueEeB9/8o+eSsMnxPJD+Q+K909sdESg7C+tIkoH6on1A==", - "dev": true, - "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - } - }, - "js-tokens": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", - "integrity": "sha512-RjTcuD4xjtthQkaWH7dFlH85L+QaVtSoOyGdZ3g6HFhS9dFNDfLyqgm2NFe2X6cQpeFmt0452FJjFG5UameExg==", - "dev": true - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha512-KKNVtd6pCYgPIKU4cp2733HWYCpplQhddZLBUryaAHou723x+FRzQ5Df824Fj+IyyuiQTRoub4SnIFfIcrp70g==", - "dev": true - } + "minipass": "^7.0.3", + "minipass-sized": "^1.0.3", + "minizlib": "^3.0.1" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + }, + "optionalDependencies": { + "encoding": "^0.1.13" } }, - "balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true - }, - "batch": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", - "integrity": "sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==", - "dev": true - }, - "binary-extensions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", - "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", - "dev": true - }, - "blockly": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/blockly/-/blockly-11.0.0.tgz", - "integrity": "sha512-6Ie7HuZWZLaETIVKFEP4FPDz267Pubn6+weQNZvXzqnkOYp9sKPSsPue8QIMCV9Qb5F4wYhqivgiDcZJcE1UlQ==", - "requires": { - "jsdom": "23.0.0" + "node_modules/npm/node_modules/minipass-fetch/node_modules/minizlib": { + "version": "3.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "minipass": "^7.0.4", + "rimraf": "^5.0.5" + }, + "engines": { + "node": ">= 18" } }, - "body-parser": { - "version": "1.20.1", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", - "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", + "node_modules/npm/node_modules/minipass-flush": { + "version": "1.0.5", "dev": true, - "requires": { - "bytes": "3.1.2", - "content-type": "~1.0.4", - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "on-finished": "2.4.1", - "qs": "6.11.0", - "raw-body": "2.5.1", - "type-is": "~1.6.18", - "unpipe": "1.0.0" - }, + "inBundle": true, + "license": "ISC", "dependencies": { - "bytes": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", - "dev": true - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dev": true, - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true - } + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" } }, - "bonjour-service": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/bonjour-service/-/bonjour-service-1.1.1.tgz", - "integrity": "sha512-Z/5lQRMOG9k7W+FkeGTNjh7htqn/2LMnfOvBZ8pynNZCM9MwkQkI3zeI4oz09uWdcgmgHugVvBqxGg4VQJ5PCg==", + "node_modules/npm/node_modules/minipass-flush/node_modules/minipass": { + "version": "3.3.6", "dev": true, - "requires": { - "array-flatten": "^2.1.2", - "dns-equal": "^1.0.0", - "fast-deep-equal": "^3.1.3", - "multicast-dns": "^7.2.5" + "inBundle": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" } }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "node_modules/npm/node_modules/minipass-pipeline": { + "version": "1.2.4", "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "inBundle": true, + "license": "ISC", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">=8" } }, - "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "node_modules/npm/node_modules/minipass-pipeline/node_modules/minipass": { + "version": "3.3.6", "dev": true, - "requires": { - "fill-range": "^7.0.1" + "inBundle": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" } }, - "browserslist": { - "version": "4.22.2", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.2.tgz", - "integrity": "sha512-0UgcrvQmBDvZHFGdYUehrCNIazki7/lUP3kkoi/r3YB2amZbFM9J43ZRkJTXBUZK4gmx56+Sqk9+Vs9mwZx9+A==", + "node_modules/npm/node_modules/minipass-sized": { + "version": "1.0.3", "dev": true, - "requires": { - "caniuse-lite": "^1.0.30001565", - "electron-to-chromium": "^1.4.601", - "node-releases": "^2.0.14", - "update-browserslist-db": "^1.0.13" + "inBundle": true, + "license": "ISC", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">=8" } }, - "buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "dev": true - }, - "bytes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", - "integrity": "sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==", - "dev": true - }, - "call-bind": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.5.tgz", - "integrity": "sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ==", + "node_modules/npm/node_modules/minipass-sized/node_modules/minipass": { + "version": "3.3.6", "dev": true, - "requires": { - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.1", - "set-function-length": "^1.1.1" + "inBundle": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" } }, - "caller-path": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz", - "integrity": "sha512-UJiE1otjXPF5/x+T3zTnSFiTOEmJoGTD9HmBoxnCUwho61a2eSNn/VwtwuIBDAo2SEOv1AJ7ARI5gCmohFLu/g==", + "node_modules/npm/node_modules/minizlib": { + "version": "2.1.2", "dev": true, - "requires": { - "callsites": "^0.2.0" + "inBundle": true, + "license": "MIT", + "dependencies": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/npm/node_modules/minizlib/node_modules/minipass": { + "version": "3.3.6", + "dev": true, + "inBundle": true, + "license": "ISC", "dependencies": { - "callsites": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz", - "integrity": "sha512-Zv4Dns9IbXXmPkgRRUjAaJQgfN4xX5p6+RQFhWUqscdvvK2xK/ZL8b3IXIJsj+4sD+f24NwnWy2BY8AJ82JB0A==", - "dev": true - } + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" } }, - "callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true + "node_modules/npm/node_modules/mkdirp": { + "version": "1.0.4", + "dev": true, + "inBundle": true, + "license": "MIT", + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } }, - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true + "node_modules/npm/node_modules/ms": { + "version": "2.1.3", + "dev": true, + "inBundle": true, + "license": "MIT" }, - "camelcase-keys": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-6.2.2.tgz", - "integrity": "sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==", + "node_modules/npm/node_modules/mute-stream": { + "version": "2.0.0", "dev": true, - "requires": { - "camelcase": "^5.3.1", - "map-obj": "^4.0.0", - "quick-lru": "^4.0.1" + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^18.17.0 || >=20.5.0" } }, - "caniuse-lite": { - "version": "1.0.30001570", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001570.tgz", - "integrity": "sha512-+3e0ASu4sw1SWaoCtvPeyXp+5PsjigkSt8OXZbF9StH5pQWbxEjLAZE3n8Aup5udop1uRiKA7a4utUk/uoSpUw==", - "dev": true + "node_modules/npm/node_modules/negotiator": { + "version": "0.6.3", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "node_modules/npm/node_modules/node-gyp": { + "version": "10.2.0", "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, + "inBundle": true, + "license": "MIT", "dependencies": { - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } + "env-paths": "^2.2.0", + "exponential-backoff": "^3.1.1", + "glob": "^10.3.10", + "graceful-fs": "^4.2.6", + "make-fetch-happen": "^13.0.0", + "nopt": "^7.0.0", + "proc-log": "^4.1.0", + "semver": "^7.3.5", + "tar": "^6.2.1", + "which": "^4.0.0" + }, + "bin": { + "node-gyp": "bin/node-gyp.js" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" } }, - "chardet": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.4.2.tgz", - "integrity": "sha512-j/Toj7f1z98Hh2cYo2BVr85EpIRWqUi7rtRSGxh/cqUjqrnJe9l9UE7IUGd2vQ2p+kSHLkSzObQPZPLUC6TQwg==", - "dev": true + "node_modules/npm/node_modules/node-gyp/node_modules/@npmcli/agent": { + "version": "2.2.2", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "agent-base": "^7.1.0", + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.1", + "lru-cache": "^10.0.1", + "socks-proxy-agent": "^8.0.3" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } }, - "chokidar": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", - "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "node_modules/npm/node_modules/node-gyp/node_modules/@npmcli/fs": { + "version": "3.1.1", "dev": true, - "requires": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "fsevents": "~2.3.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" + "inBundle": true, + "license": "ISC", + "dependencies": { + "semver": "^7.3.5" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "chrome-trace-event": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", - "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==", - "dev": true + "node_modules/npm/node_modules/node-gyp/node_modules/abbrev": { + "version": "2.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } }, - "circular-json": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz", - "integrity": "sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A==", - "dev": true + "node_modules/npm/node_modules/node-gyp/node_modules/cacache": { + "version": "18.0.4", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/fs": "^3.1.0", + "fs-minipass": "^3.0.0", + "glob": "^10.2.2", + "lru-cache": "^10.0.1", + "minipass": "^7.0.3", + "minipass-collect": "^2.0.1", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "p-map": "^4.0.0", + "ssri": "^10.0.0", + "tar": "^6.1.11", + "unique-filename": "^3.0.0" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } }, - "cli-cursor": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", - "integrity": "sha512-8lgKz8LmCRYZZQDpRyT2m5rKJ08TnU4tR9FFFW2rxpxR1FzWi4PQ/NfyODchAatHaUgnSPVcx/R5w6NuTBzFiw==", + "node_modules/npm/node_modules/node-gyp/node_modules/isexe": { + "version": "3.1.1", "dev": true, - "requires": { - "restore-cursor": "^2.0.0" + "inBundle": true, + "license": "ISC", + "engines": { + "node": ">=16" } }, - "cli-width": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.1.tgz", - "integrity": "sha512-GRMWDxpOB6Dgk2E5Uo+3eEBvtOOlimMmpbFiKuLFnQzYDavtLFY3K5ona41jgN/WdRZtG7utuVSVTL4HbZHGkw==", - "dev": true + "node_modules/npm/node_modules/node-gyp/node_modules/make-fetch-happen": { + "version": "13.0.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/agent": "^2.0.0", + "cacache": "^18.0.0", + "http-cache-semantics": "^4.1.1", + "is-lambda": "^1.0.1", + "minipass": "^7.0.2", + "minipass-fetch": "^3.0.0", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "negotiator": "^0.6.3", + "proc-log": "^4.2.0", + "promise-retry": "^2.0.1", + "ssri": "^10.0.0" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } }, - "cliui": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", - "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "node_modules/npm/node_modules/node-gyp/node_modules/minipass-fetch": { + "version": "3.0.5", "dev": true, - "requires": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.1", - "wrap-ansi": "^7.0.0" + "inBundle": true, + "license": "MIT", + "dependencies": { + "minipass": "^7.0.3", + "minipass-sized": "^1.0.3", + "minizlib": "^2.1.2" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + }, + "optionalDependencies": { + "encoding": "^0.1.13" } }, - "clone-deep": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", - "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", + "node_modules/npm/node_modules/node-gyp/node_modules/nopt": { + "version": "7.2.1", "dev": true, - "requires": { - "is-plain-object": "^2.0.4", - "kind-of": "^6.0.2", - "shallow-clone": "^3.0.0" + "inBundle": true, + "license": "ISC", + "dependencies": { + "abbrev": "^2.0.0" + }, + "bin": { + "nopt": "bin/nopt.js" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "co": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", - "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", - "dev": true + "node_modules/npm/node_modules/node-gyp/node_modules/proc-log": { + "version": "4.2.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "node_modules/npm/node_modules/node-gyp/node_modules/ssri": { + "version": "10.0.6", "dev": true, - "requires": { - "color-name": "~1.1.4" + "inBundle": true, + "license": "ISC", + "dependencies": { + "minipass": "^7.0.3" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true + "node_modules/npm/node_modules/node-gyp/node_modules/unique-filename": { + "version": "3.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "unique-slug": "^4.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } }, - "colorette": { - "version": "2.0.20", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", - "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", - "dev": true + "node_modules/npm/node_modules/node-gyp/node_modules/unique-slug": { + "version": "4.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "imurmurhash": "^0.1.4" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } }, - "combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "requires": { - "delayed-stream": "~1.0.0" + "node_modules/npm/node_modules/node-gyp/node_modules/which": { + "version": "4.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "isexe": "^3.1.1" + }, + "bin": { + "node-which": "bin/which.js" + }, + "engines": { + "node": "^16.13.0 || >=18.0.0" } }, - "commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true + "node_modules/npm/node_modules/nopt": { + "version": "8.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "abbrev": "^2.0.0" + }, + "bin": { + "nopt": "bin/nopt.js" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } }, - "compare-func": { + "node_modules/npm/node_modules/nopt/node_modules/abbrev": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/compare-func/-/compare-func-2.0.0.tgz", - "integrity": "sha512-zHig5N+tPWARooBnb0Zx1MFcdfpyJrfTJ3Y5L+IFvUm8rM74hHz66z0gw0x4tijh5CorKkKUCnW82R2vmpeCRA==", "dev": true, - "requires": { - "array-ify": "^1.0.0", - "dot-prop": "^5.1.0" + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "compressible": { - "version": "2.0.18", - "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", - "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", + "node_modules/npm/node_modules/normalize-package-data": { + "version": "7.0.0", "dev": true, - "requires": { - "mime-db": ">= 1.43.0 < 2" + "inBundle": true, + "license": "BSD-2-Clause", + "dependencies": { + "hosted-git-info": "^8.0.0", + "semver": "^7.3.5", + "validate-npm-package-license": "^3.0.4" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" } }, - "compression": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz", - "integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==", + "node_modules/npm/node_modules/npm-audit-report": { + "version": "6.0.0", "dev": true, - "requires": { - "accepts": "~1.3.5", - "bytes": "3.0.0", - "compressible": "~2.0.16", - "debug": "2.6.9", - "on-headers": "~1.0.2", - "safe-buffer": "5.1.2", - "vary": "~1.1.2" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - } + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^18.17.0 || >=20.5.0" } }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true - }, - "concat-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", - "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "node_modules/npm/node_modules/npm-bundled": { + "version": "4.0.0", "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" - }, + "inBundle": true, + "license": "ISC", "dependencies": { - "readable-stream": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", - "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } + "npm-normalize-package-bin": "^4.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" } }, - "connect-history-api-fallback": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-2.0.0.tgz", - "integrity": "sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA==", - "dev": true + "node_modules/npm/node_modules/npm-install-checks": { + "version": "7.1.0", + "dev": true, + "inBundle": true, + "license": "BSD-2-Clause", + "dependencies": { + "semver": "^7.1.1" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } }, - "content-disposition": { - "version": "0.5.4", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", - "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "node_modules/npm/node_modules/npm-normalize-package-bin": { + "version": "4.0.0", "dev": true, - "requires": { - "safe-buffer": "5.2.1" + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^18.17.0 || >=20.5.0" } }, - "content-type": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", - "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", - "dev": true + "node_modules/npm/node_modules/npm-package-arg": { + "version": "12.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "hosted-git-info": "^8.0.0", + "proc-log": "^5.0.0", + "semver": "^7.3.5", + "validate-npm-package-name": "^6.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } }, - "conventional-changelog-angular": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-6.0.0.tgz", - "integrity": "sha512-6qLgrBF4gueoC7AFVHu51nHL9pF9FRjXrH+ceVf7WmAfH3gs+gEYOkvxhjMPjZu57I4AGUGoNTY8V7Hrgf1uqg==", + "node_modules/npm/node_modules/npm-packlist": { + "version": "9.0.0", "dev": true, - "requires": { - "compare-func": "^2.0.0" + "inBundle": true, + "license": "ISC", + "dependencies": { + "ignore-walk": "^7.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" } }, - "conventional-changelog-conventionalcommits": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/conventional-changelog-conventionalcommits/-/conventional-changelog-conventionalcommits-6.1.0.tgz", - "integrity": "sha512-3cS3GEtR78zTfMzk0AizXKKIdN4OvSh7ibNz6/DPbhWWQu7LqE/8+/GqSodV+sywUR2gpJAdP/1JFf4XtN7Zpw==", + "node_modules/npm/node_modules/npm-pick-manifest": { + "version": "10.0.0", "dev": true, - "requires": { - "compare-func": "^2.0.0" + "inBundle": true, + "license": "ISC", + "dependencies": { + "npm-install-checks": "^7.1.0", + "npm-normalize-package-bin": "^4.0.0", + "npm-package-arg": "^12.0.0", + "semver": "^7.3.5" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" } }, - "conventional-commits-parser": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-4.0.0.tgz", - "integrity": "sha512-WRv5j1FsVM5FISJkoYMR6tPk07fkKT0UodruX4je86V4owk451yjXAKzKAPOs9l7y59E2viHUS9eQ+dfUA9NSg==", + "node_modules/npm/node_modules/npm-profile": { + "version": "11.0.1", "dev": true, - "requires": { - "is-text-path": "^1.0.1", - "JSONStream": "^1.3.5", - "meow": "^8.1.2", - "split2": "^3.2.2" + "inBundle": true, + "license": "ISC", + "dependencies": { + "npm-registry-fetch": "^18.0.0", + "proc-log": "^5.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" } }, - "cookie": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", - "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", - "dev": true + "node_modules/npm/node_modules/npm-registry-fetch": { + "version": "18.0.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/redact": "^3.0.0", + "jsonparse": "^1.3.1", + "make-fetch-happen": "^14.0.0", + "minipass": "^7.0.2", + "minipass-fetch": "^4.0.0", + "minizlib": "^3.0.1", + "npm-package-arg": "^12.0.0", + "proc-log": "^5.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } }, - "cookie-signature": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", - "dev": true + "node_modules/npm/node_modules/npm-registry-fetch/node_modules/minizlib": { + "version": "3.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "minipass": "^7.0.4", + "rimraf": "^5.0.5" + }, + "engines": { + "node": ">= 18" + } }, - "core-util-is": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", - "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", - "dev": true + "node_modules/npm/node_modules/npm-user-validate": { + "version": "3.0.0", + "dev": true, + "inBundle": true, + "license": "BSD-2-Clause", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } }, - "cosmiconfig": { - "version": "8.3.6", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.3.6.tgz", - "integrity": "sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==", + "node_modules/npm/node_modules/p-map": { + "version": "4.0.0", "dev": true, - "requires": { - "import-fresh": "^3.3.0", - "js-yaml": "^4.1.0", - "parse-json": "^5.2.0", - "path-type": "^4.0.0" + "inBundle": true, + "license": "MIT", + "dependencies": { + "aggregate-error": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "cosmiconfig-typescript-loader": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/cosmiconfig-typescript-loader/-/cosmiconfig-typescript-loader-4.4.0.tgz", - "integrity": "sha512-BabizFdC3wBHhbI4kJh0VkQP9GkBfoHPydD0COMce1nJ1kJAB3F2TmJ/I7diULBKtmEWSwEbuN/KDtgnmUUVmw==", + "node_modules/npm/node_modules/package-json-from-dist": { + "version": "1.0.0", "dev": true, - "requires": {} + "inBundle": true, + "license": "BlueOak-1.0.0" + }, + "node_modules/npm/node_modules/pacote": { + "version": "19.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/git": "^6.0.0", + "@npmcli/installed-package-contents": "^3.0.0", + "@npmcli/package-json": "^6.0.0", + "@npmcli/promise-spawn": "^8.0.0", + "@npmcli/run-script": "^9.0.0", + "cacache": "^19.0.0", + "fs-minipass": "^3.0.0", + "minipass": "^7.0.2", + "npm-package-arg": "^12.0.0", + "npm-packlist": "^9.0.0", + "npm-pick-manifest": "^10.0.0", + "npm-registry-fetch": "^18.0.0", + "proc-log": "^5.0.0", + "promise-retry": "^2.0.1", + "sigstore": "^2.2.0", + "ssri": "^12.0.0", + "tar": "^6.1.11" + }, + "bin": { + "pacote": "bin/index.js" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } }, - "create-require": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", - "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", - "dev": true + "node_modules/npm/node_modules/parse-conflict-json": { + "version": "4.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "json-parse-even-better-errors": "^4.0.0", + "just-diff": "^6.0.0", + "just-diff-apply": "^5.2.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } }, - "cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "node_modules/npm/node_modules/path-key": { + "version": "3.1.1", "dev": true, - "requires": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=8" } }, - "cssstyle": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-3.0.0.tgz", - "integrity": "sha512-N4u2ABATi3Qplzf0hWbVCdjenim8F3ojEXpBDF5hBpjzW182MjNGLqfmQ0SkSPeQ+V86ZXgeH8aXj6kayd4jgg==", - "requires": { - "rrweb-cssom": "^0.6.0" + "node_modules/npm/node_modules/path-scurry": { + "version": "1.11.1", + "dev": true, + "inBundle": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "dargs": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/dargs/-/dargs-7.0.0.tgz", - "integrity": "sha512-2iy1EkLdlBzQGvbweYRFxmFath8+K7+AKB0TlhHWkNuH+TmovaMH/Wp7V7R4u7f4SnX3OgLsU9t1NI9ioDnUpg==", - "dev": true + "node_modules/npm/node_modules/postcss-selector-parser": { + "version": "6.1.2", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } }, - "data-urls": { + "node_modules/npm/node_modules/proc-log": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-5.0.0.tgz", - "integrity": "sha512-ZYP5VBHshaDAiVZxjbRVcFJpc+4xGgT0bK3vzy1HLN8jTO975HEbuYzZJcHoQEY5K1a0z8YayJkyVETa08eNTg==", - "requires": { - "whatwg-mimetype": "^4.0.0", - "whatwg-url": "^14.0.0" + "dev": true, + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^18.17.0 || >=20.5.0" } }, - "debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "requires": { - "ms": "2.1.2" + "node_modules/npm/node_modules/proggy": { + "version": "3.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^18.17.0 || >=20.5.0" } }, - "decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", - "dev": true - }, - "decamelize-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.1.tgz", - "integrity": "sha512-WiPxgEirIV0/eIOMcnFBA3/IJZAZqKnwAwWyvvdi4lsr1WCN22nhdf/3db3DoZcUjTV2SqfzIwNyp6y2xs3nmg==", + "node_modules/npm/node_modules/promise-all-reject-late": { + "version": "1.0.1", "dev": true, - "requires": { - "decamelize": "^1.1.0", - "map-obj": "^1.0.0" - }, - "dependencies": { - "map-obj": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", - "integrity": "sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==", - "dev": true - } + "inBundle": true, + "license": "ISC", + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "decimal.js": { - "version": "10.4.3", - "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.3.tgz", - "integrity": "sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==" + "node_modules/npm/node_modules/promise-call-limit": { + "version": "3.0.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "funding": { + "url": "https://github.com/sponsors/isaacs" + } }, - "deep-is": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "dev": true + "node_modules/npm/node_modules/promise-inflight": { + "version": "1.0.1", + "dev": true, + "inBundle": true, + "license": "ISC" }, - "default-gateway": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-6.0.3.tgz", - "integrity": "sha512-fwSOJsbbNzZ/CUFpqFBqYfYNLj1NbMPm8MMCIzHjC83iSJRBEGmDUxU+WP661BaBQImeC2yHwXtz+P/O9o+XEg==", + "node_modules/npm/node_modules/promise-retry": { + "version": "2.0.1", "dev": true, - "requires": { - "execa": "^5.0.0" + "inBundle": true, + "license": "MIT", + "dependencies": { + "err-code": "^2.0.2", + "retry": "^0.12.0" + }, + "engines": { + "node": ">=10" } }, - "define-data-property": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.1.tgz", - "integrity": "sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==", + "node_modules/npm/node_modules/promzard": { + "version": "2.0.0", "dev": true, - "requires": { - "get-intrinsic": "^1.2.1", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.0" + "inBundle": true, + "license": "ISC", + "dependencies": { + "read": "^4.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" } }, - "define-lazy-prop": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", - "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==", - "dev": true + "node_modules/npm/node_modules/qrcode-terminal": { + "version": "0.12.0", + "dev": true, + "inBundle": true, + "bin": { + "qrcode-terminal": "bin/qrcode-terminal.js" + } }, - "delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==" + "node_modules/npm/node_modules/read": { + "version": "4.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "mute-stream": "^2.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } }, - "depd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", - "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", - "dev": true + "node_modules/npm/node_modules/read-cmd-shim": { + "version": "5.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } }, - "destroy": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", - "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", - "dev": true + "node_modules/npm/node_modules/read-package-json-fast": { + "version": "4.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "json-parse-even-better-errors": "^4.0.0", + "npm-normalize-package-bin": "^4.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } }, - "detect-node": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", - "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==", - "dev": true + "node_modules/npm/node_modules/retry": { + "version": "0.12.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } }, - "diff": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", - "dev": true + "node_modules/npm/node_modules/rimraf": { + "version": "5.0.10", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "glob": "^10.3.7" + }, + "bin": { + "rimraf": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } }, - "dns-equal": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/dns-equal/-/dns-equal-1.0.0.tgz", - "integrity": "sha512-z+paD6YUQsk+AbGCEM4PrOXSss5gd66QfcVBFTKR/HpFL9jCqikS94HYwKww6fQyO7IxrIIyUu+g0Ka9tUS2Cg==", - "dev": true + "node_modules/npm/node_modules/safer-buffer": { + "version": "2.1.2", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true }, - "dns-packet": { - "version": "5.6.1", - "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-5.6.1.tgz", - "integrity": "sha512-l4gcSouhcgIKRvyy99RNVOgxXiicE+2jZoNmaNmZ6JXiGajBOJAesk1OBlJuM5k2c+eudGdLxDqXuPCKIj6kpw==", + "node_modules/npm/node_modules/semver": { + "version": "7.6.3", "dev": true, - "requires": { - "@leichtgewicht/ip-codec": "^2.0.1" + "inBundle": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" } }, - "doctrine": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "node_modules/npm/node_modules/shebang-command": { + "version": "2.0.0", "dev": true, - "requires": { - "esutils": "^2.0.2" + "inBundle": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" } }, - "dot-prop": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", - "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==", + "node_modules/npm/node_modules/shebang-regex": { + "version": "3.0.0", "dev": true, - "requires": { - "is-obj": "^2.0.0" + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=8" } }, - "ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", - "dev": true - }, - "electron-to-chromium": { - "version": "1.4.615", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.615.tgz", - "integrity": "sha512-/bKPPcgZVUziECqDc+0HkT87+0zhaWSZHNXqF8FLd2lQcptpmUFwoCSWjCdOng9Gdq+afKArPdEg/0ZW461Eng==", - "dev": true + "node_modules/npm/node_modules/signal-exit": { + "version": "4.1.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } }, - "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true + "node_modules/npm/node_modules/sigstore": { + "version": "2.3.1", + "dev": true, + "inBundle": true, + "license": "Apache-2.0", + "dependencies": { + "@sigstore/bundle": "^2.3.2", + "@sigstore/core": "^1.0.0", + "@sigstore/protobuf-specs": "^0.3.2", + "@sigstore/sign": "^2.3.2", + "@sigstore/tuf": "^2.3.4", + "@sigstore/verify": "^1.2.1" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } }, - "encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", - "dev": true + "node_modules/npm/node_modules/smart-buffer": { + "version": "4.2.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">= 6.0.0", + "npm": ">= 3.0.0" + } }, - "enhanced-resolve": { - "version": "5.15.0", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.15.0.tgz", - "integrity": "sha512-LXYT42KJ7lpIKECr2mAXIaMldcNCh/7E0KBKOu4KSfkHmP+mZmSs+8V5gBAqisWBy0OO4W5Oyys0GO1Y8KtdKg==", + "node_modules/npm/node_modules/socks": { + "version": "2.8.3", "dev": true, - "requires": { - "graceful-fs": "^4.2.4", - "tapable": "^2.2.0" + "inBundle": true, + "license": "MIT", + "dependencies": { + "ip-address": "^9.0.5", + "smart-buffer": "^4.2.0" + }, + "engines": { + "node": ">= 10.0.0", + "npm": ">= 3.0.0" } }, - "entities": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", - "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==" + "node_modules/npm/node_modules/socks-proxy-agent": { + "version": "8.0.4", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.1", + "debug": "^4.3.4", + "socks": "^2.8.3" + }, + "engines": { + "node": ">= 14" + } }, - "envinfo": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.11.0.tgz", - "integrity": "sha512-G9/6xF1FPbIw0TtalAMaVPpiq2aDEuKLXM314jPVAO9r2fo2a4BLqMNkmRS7O/xPPZ+COAhGIz3ETvHEV3eUcg==", - "dev": true + "node_modules/npm/node_modules/spdx-correct": { + "version": "3.2.0", + "dev": true, + "inBundle": true, + "license": "Apache-2.0", + "dependencies": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } }, - "error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "node_modules/npm/node_modules/spdx-correct/node_modules/spdx-expression-parse": { + "version": "3.0.1", "dev": true, - "requires": { - "is-arrayish": "^0.2.1" + "inBundle": true, + "license": "MIT", + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" } }, - "es-module-lexer": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.4.1.tgz", - "integrity": "sha512-cXLGjP0c4T3flZJKQSuziYoq7MlT+rnvfZjfp7h+I7K9BNX54kP9nyWvdbwjQ4u1iWbOL4u96fgeZLToQlZC7w==", - "dev": true + "node_modules/npm/node_modules/spdx-exceptions": { + "version": "2.5.0", + "dev": true, + "inBundle": true, + "license": "CC-BY-3.0" }, - "escalade": { + "node_modules/npm/node_modules/spdx-expression-parse": { + "version": "4.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/npm/node_modules/spdx-license-ids": { + "version": "3.0.18", + "dev": true, + "inBundle": true, + "license": "CC0-1.0" + }, + "node_modules/npm/node_modules/sprintf-js": { + "version": "1.1.3", + "dev": true, + "inBundle": true, + "license": "BSD-3-Clause" + }, + "node_modules/npm/node_modules/ssri": { + "version": "12.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "minipass": "^7.0.3" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/string-width": { + "version": "4.2.3", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/strip-ansi": { + "version": "6.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/supports-color": { + "version": "9.4.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/npm/node_modules/tar": { + "version": "6.2.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "minipass": "^5.0.0", + "minizlib": "^2.1.1", + "mkdirp": "^1.0.3", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/npm/node_modules/tar/node_modules/fs-minipass": { + "version": "2.1.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/npm/node_modules/tar/node_modules/fs-minipass/node_modules/minipass": { + "version": "3.3.6", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/tar/node_modules/minipass": { + "version": "5.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/text-table": { + "version": "0.2.0", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/tiny-relative-date": { + "version": "1.3.0", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/treeverse": { + "version": "3.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/tuf-js": { + "version": "2.2.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "@tufjs/models": "2.0.1", + "debug": "^4.3.4", + "make-fetch-happen": "^13.0.1" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/tuf-js/node_modules/@npmcli/agent": { + "version": "2.2.2", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "agent-base": "^7.1.0", + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.1", + "lru-cache": "^10.0.1", + "socks-proxy-agent": "^8.0.3" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/tuf-js/node_modules/@npmcli/fs": { "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "dev": true + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "semver": "^7.3.5" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } }, - "escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", - "dev": true + "node_modules/npm/node_modules/tuf-js/node_modules/cacache": { + "version": "18.0.4", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/fs": "^3.1.0", + "fs-minipass": "^3.0.0", + "glob": "^10.2.2", + "lru-cache": "^10.0.1", + "minipass": "^7.0.3", + "minipass-collect": "^2.0.1", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "p-map": "^4.0.0", + "ssri": "^10.0.0", + "tar": "^6.1.11", + "unique-filename": "^3.0.0" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true + "node_modules/npm/node_modules/tuf-js/node_modules/make-fetch-happen": { + "version": "13.0.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/agent": "^2.0.0", + "cacache": "^18.0.0", + "http-cache-semantics": "^4.1.1", + "is-lambda": "^1.0.1", + "minipass": "^7.0.2", + "minipass-fetch": "^3.0.0", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "negotiator": "^0.6.3", + "proc-log": "^4.2.0", + "promise-retry": "^2.0.1", + "ssri": "^10.0.0" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } }, - "eslint": { - "version": "4.19.1", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-4.19.1.tgz", - "integrity": "sha512-bT3/1x1EbZB7phzYu7vCr1v3ONuzDtX8WjuM9c0iYxe+cq+pwcKEoQjl7zd3RpC6YOLgnSy3cTN58M2jcoPDIQ==", + "node_modules/npm/node_modules/tuf-js/node_modules/minipass-fetch": { + "version": "3.0.5", "dev": true, - "requires": { - "ajv": "^5.3.0", - "babel-code-frame": "^6.22.0", - "chalk": "^2.1.0", - "concat-stream": "^1.6.0", - "cross-spawn": "^5.1.0", - "debug": "^3.1.0", - "doctrine": "^2.1.0", - "eslint-scope": "^3.7.1", - "eslint-visitor-keys": "^1.0.0", - "espree": "^3.5.4", - "esquery": "^1.0.0", - "esutils": "^2.0.2", - "file-entry-cache": "^2.0.0", - "functional-red-black-tree": "^1.0.1", - "glob": "^7.1.2", - "globals": "^11.0.1", - "ignore": "^3.3.3", - "imurmurhash": "^0.1.4", - "inquirer": "^3.0.6", - "is-resolvable": "^1.0.0", - "js-yaml": "^3.9.1", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.3.0", - "lodash": "^4.17.4", - "minimatch": "^3.0.2", - "mkdirp": "^0.5.1", - "natural-compare": "^1.4.0", - "optionator": "^0.8.2", - "path-is-inside": "^1.0.2", - "pluralize": "^7.0.0", - "progress": "^2.0.0", - "regexpp": "^1.0.1", - "require-uncached": "^1.0.3", - "semver": "^5.3.0", - "strip-ansi": "^4.0.0", - "strip-json-comments": "~2.0.1", - "table": "4.0.2", - "text-table": "~0.2.0" + "inBundle": true, + "license": "MIT", + "dependencies": { + "minipass": "^7.0.3", + "minipass-sized": "^1.0.3", + "minizlib": "^2.1.2" }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + }, + "optionalDependencies": { + "encoding": "^0.1.13" + } + }, + "node_modules/npm/node_modules/tuf-js/node_modules/proc-log": { + "version": "4.2.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/tuf-js/node_modules/ssri": { + "version": "10.0.6", + "dev": true, + "inBundle": true, + "license": "ISC", "dependencies": { - "ajv": { - "version": "5.5.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz", - "integrity": "sha512-Ajr4IcMXq/2QmMkEmSvxqfLN5zGmJ92gHXAeOXq1OekoH2rfDNsgdDoL2f7QaRCy7G/E6TpxBVdRuNraMztGHw==", - "dev": true, - "requires": { - "co": "^4.6.0", - "fast-deep-equal": "^1.0.0", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.3.0" - } - }, - "ansi-regex": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz", - "integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==", - "dev": true - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "requires": { - "sprintf-js": "~1.0.2" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "cross-spawn": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", - "integrity": "sha512-pTgQJ5KC0d2hcY8eyL1IzlBPYjTkyH72XRZPnLyKus2mBfNjQs3klqbJU2VILqZryAZUt9JOb3h/mWMy23/f5A==", - "dev": true, - "requires": { - "lru-cache": "^4.0.1", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } - }, - "debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "eslint-scope": { - "version": "3.7.3", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-3.7.3.tgz", - "integrity": "sha512-W+B0SvF4gamyCTmUc+uITPY0989iXVfKvhwtmJocTaYoc/3khEHmEmvfY/Gn9HA9VV75jrQECsHizkNw1b68FA==", - "dev": true, - "requires": { - "esrecurse": "^4.1.0", - "estraverse": "^4.1.1" - } - }, - "fast-deep-equal": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz", - "integrity": "sha512-fueX787WZKCV0Is4/T2cyAdM4+x1S3MXXOAhavE1ys/W42SHAPacLTQhucja22QBYrfGw50M2sRiXPtTGv9Ymw==", - "dev": true - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true - }, - "js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", - "dev": true, - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, - "json-schema-traverse": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz", - "integrity": "sha512-4JD/Ivzg7PoW8NzdrBSr3UFwC9mHgvI7Z6z3QGBsSHgKaRTUDmyZAAKJo2UbG1kUVfS9WS8bi36N49U1xw43DA==", - "dev": true - }, - "lru-cache": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", - "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", - "dev": true, - "requires": { - "pseudomap": "^1.0.2", - "yallist": "^2.1.2" - } - }, - "semver": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", - "dev": true - }, - "shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==", - "dev": true, - "requires": { - "shebang-regex": "^1.0.0" - } - }, - "shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==", - "dev": true - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - }, - "yallist": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", - "integrity": "sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==", - "dev": true - } + "minipass": "^7.0.3" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "node_modules/npm/node_modules/tuf-js/node_modules/unique-filename": { + "version": "3.0.0", "dev": true, - "requires": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" + "inBundle": true, + "license": "ISC", + "dependencies": { + "unique-slug": "^4.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", - "dev": true + "node_modules/npm/node_modules/tuf-js/node_modules/unique-slug": { + "version": "4.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "imurmurhash": "^0.1.4" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } }, - "espree": { - "version": "3.5.4", - "resolved": "https://registry.npmjs.org/espree/-/espree-3.5.4.tgz", - "integrity": "sha512-yAcIQxtmMiB/jL32dzEp2enBeidsB7xWPLNiw3IIkpVds1P+h7qF9YwJq1yUNzp2OKXgAprs4F61ih66UsoD1A==", + "node_modules/npm/node_modules/unique-filename": { + "version": "4.0.0", "dev": true, - "requires": { - "acorn": "^5.5.0", - "acorn-jsx": "^3.0.0" + "inBundle": true, + "license": "ISC", + "dependencies": { + "unique-slug": "^5.0.0" }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/unique-slug": { + "version": "5.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", "dependencies": { - "acorn": { - "version": "5.7.4", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.4.tgz", - "integrity": "sha512-1D++VG7BhrtvQpNbBzovKNc1FLGGEE/oGe7b9xJm/RFHMBeUaUGpluV9RLjZa47YFdPcDAenEYuq9pQPcMdLJg==", - "dev": true - } + "imurmurhash": "^0.1.4" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" } }, - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true + "node_modules/npm/node_modules/util-deprecate": { + "version": "1.0.2", + "dev": true, + "inBundle": true, + "license": "MIT" }, - "esquery": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", - "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", + "node_modules/npm/node_modules/validate-npm-package-license": { + "version": "3.0.4", "dev": true, - "requires": { - "estraverse": "^5.1.0" - }, + "inBundle": true, + "license": "Apache-2.0", "dependencies": { - "estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true - } + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" } }, - "esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "node_modules/npm/node_modules/validate-npm-package-license/node_modules/spdx-expression-parse": { + "version": "3.0.1", "dev": true, - "requires": { - "estraverse": "^5.2.0" - }, + "inBundle": true, + "license": "MIT", "dependencies": { - "estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true - } + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" } }, - "estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true - }, - "esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true + "node_modules/npm/node_modules/validate-npm-package-name": { + "version": "6.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } }, - "etag": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", - "dev": true + "node_modules/npm/node_modules/walk-up-path": { + "version": "3.0.1", + "dev": true, + "inBundle": true, + "license": "ISC" }, - "eventemitter3": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", - "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", - "dev": true - }, - "events": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", - "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", - "dev": true + "node_modules/npm/node_modules/which": { + "version": "5.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "isexe": "^3.1.1" + }, + "bin": { + "node-which": "bin/which.js" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } }, - "execa": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", - "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "node_modules/npm/node_modules/which/node_modules/isexe": { + "version": "3.1.1", "dev": true, - "requires": { - "cross-spawn": "^7.0.3", - "get-stream": "^6.0.0", - "human-signals": "^2.1.0", - "is-stream": "^2.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.1", - "onetime": "^5.1.2", - "signal-exit": "^3.0.3", - "strip-final-newline": "^2.0.0" + "inBundle": true, + "license": "ISC", + "engines": { + "node": ">=16" } }, - "express": { - "version": "4.18.2", - "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", - "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", + "node_modules/npm/node_modules/wrap-ansi": { + "version": "8.1.0", "dev": true, - "requires": { - "accepts": "~1.3.8", - "array-flatten": "1.1.1", - "body-parser": "1.20.1", - "content-disposition": "0.5.4", - "content-type": "~1.0.4", - "cookie": "0.5.0", - "cookie-signature": "1.0.6", - "debug": "2.6.9", - "depd": "2.0.0", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "finalhandler": "1.2.0", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "merge-descriptors": "1.0.1", - "methods": "~1.1.2", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "path-to-regexp": "0.1.7", - "proxy-addr": "~2.0.7", - "qs": "6.11.0", - "range-parser": "~1.2.1", - "safe-buffer": "5.2.1", - "send": "0.18.0", - "serve-static": "1.15.0", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "type-is": "~1.6.18", - "utils-merge": "1.0.1", - "vary": "~1.1.2" - }, + "inBundle": true, + "license": "MIT", "dependencies": { - "array-flatten": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", - "dev": true - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true - } + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, - "external-editor": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-2.2.0.tgz", - "integrity": "sha512-bSn6gvGxKt+b7+6TKEv1ZycHleA7aHhRHyAqJyp5pbUFuYYNIzpZnQDk7AsYckyWdEnTeAnay0aCy2aV6iTk9A==", + "node_modules/npm/node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", "dev": true, - "requires": { - "chardet": "^0.4.0", - "iconv-lite": "^0.4.17", - "tmp": "^0.0.33" - }, + "inBundle": true, + "license": "MIT", "dependencies": { - "iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dev": true, - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - } + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, - "fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true - }, - "fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true - }, - "fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", - "dev": true - }, - "fastest-levenshtein": { - "version": "1.0.16", - "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz", - "integrity": "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==", - "dev": true - }, - "faye-websocket": { - "version": "0.11.4", - "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz", - "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==", + "node_modules/npm/node_modules/wrap-ansi-cjs/node_modules/ansi-styles": { + "version": "4.3.0", "dev": true, - "requires": { - "websocket-driver": ">=0.5.1" + "inBundle": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "figures": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", - "integrity": "sha512-Oa2M9atig69ZkfwiApY8F2Yy+tzMbazyvqv21R0NsSC8floSOC09BbT1ITWAdoMGQvJ/aZnR1KMwdx9tvHnTNA==", + "node_modules/npm/node_modules/wrap-ansi/node_modules/ansi-regex": { + "version": "6.0.1", "dev": true, - "requires": { - "escape-string-regexp": "^1.0.5" + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" } }, - "file-entry-cache": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-2.0.0.tgz", - "integrity": "sha512-uXP/zGzxxFvFfcZGgBIwotm+Tdc55ddPAzF7iHshP4YGaXMww7rSF9peD9D1sui5ebONg5UobsZv+FfgEpGv/w==", + "node_modules/npm/node_modules/wrap-ansi/node_modules/emoji-regex": { + "version": "9.2.2", "dev": true, - "requires": { - "flat-cache": "^1.2.1", - "object-assign": "^4.0.1" - } + "inBundle": true, + "license": "MIT" }, - "fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "node_modules/npm/node_modules/wrap-ansi/node_modules/string-width": { + "version": "5.1.2", "dev": true, - "requires": { - "to-regex-range": "^5.0.1" + "inBundle": true, + "license": "MIT", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "finalhandler": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", - "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", + "node_modules/npm/node_modules/wrap-ansi/node_modules/strip-ansi": { + "version": "7.1.0", "dev": true, - "requires": { - "debug": "2.6.9", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "statuses": "2.0.1", - "unpipe": "~1.0.0" - }, + "inBundle": true, + "license": "MIT", "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true - } + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, - "find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "node_modules/npm/node_modules/write-file-atomic": { + "version": "6.0.0", "dev": true, - "requires": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" + "inBundle": true, + "license": "ISC", + "dependencies": { + "imurmurhash": "^0.1.4", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" } }, - "flat": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", - "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", - "dev": true - }, - "flat-cache": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.3.4.tgz", - "integrity": "sha512-VwyB3Lkgacfik2vhqR4uv2rvebqmDvFu4jlN/C1RzWoJEo8I7z4Q404oiqYCkq41mni8EzQnm95emU9seckwtg==", - "dev": true, - "requires": { - "circular-json": "^0.3.1", - "graceful-fs": "^4.1.2", - "rimraf": "~2.6.2", - "write": "^0.2.1" - }, - "dependencies": { - "rimraf": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", - "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - } - } - }, - "follow-redirects": { - "version": "1.15.3", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.3.tgz", - "integrity": "sha512-1VzOtuEM8pC9SFU1E+8KfTjZyMztRsgEfwQl44z8A25uy13jSzTj6dyK2Df52iV0vgHCfBwLhDWevLn95w5v6Q==", - "dev": true - }, - "form-data": { + "node_modules/npm/node_modules/yallist": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", - "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" - } - }, - "forwarded": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", - "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", - "dev": true + "dev": true, + "inBundle": true, + "license": "ISC" }, - "fresh": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", - "dev": true + "node_modules/nwsapi": { + "version": "2.2.9", + "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.9.tgz", + "integrity": "sha512-2f3F0SEEer8bBu0dsNCFF50N0cTThV1nWFYcEYFZttdW0lDAoybv9cQoK7X7/68Z89S7FoRrVjP1LPX4XRf9vg==" }, - "fs-extra": { - "version": "11.2.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz", - "integrity": "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==", + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", "dev": true, - "requires": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - }, - "dependencies": { - "universalify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", - "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", - "dev": true - } + "engines": { + "node": ">=0.10.0" } }, - "fs-monkey": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.0.5.tgz", - "integrity": "sha512-8uMbBjrhzW76TYgEV27Y5E//W2f/lTFmx78P2w19FZSxarhI/798APGQyuGCwmkNxgwGRhrLfvWyLBvNtuOmew==", - "dev": true - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true - }, - "fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "node_modules/object-inspect": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", + "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", "dev": true, - "optional": true + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, - "function-bind": { + "node_modules/obuf": { "version": "1.1.2", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", - "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", - "dev": true - }, - "functional-red-black-tree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==", - "dev": true - }, - "get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", + "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==", "dev": true }, - "get-intrinsic": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.2.tgz", - "integrity": "sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA==", + "node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", "dev": true, - "requires": { - "function-bind": "^1.1.2", - "has-proto": "^1.0.1", - "has-symbols": "^1.0.3", - "hasown": "^2.0.0" + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" } }, - "get-stream": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", - "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", - "dev": true - }, - "git-raw-commits": { - "version": "2.0.11", - "resolved": "https://registry.npmjs.org/git-raw-commits/-/git-raw-commits-2.0.11.tgz", - "integrity": "sha512-VnctFhw+xfj8Va1xtfEqCUD2XDrbAPSJx+hSrE5K7fGdjZruW7XV+QOrN7LF/RJyvspRiD2I0asWsxFp0ya26A==", + "node_modules/on-headers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", + "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", "dev": true, - "requires": { - "dargs": "^7.0.0", - "lodash": "^4.17.15", - "meow": "^8.0.0", - "split2": "^3.0.0", - "through2": "^4.0.0" + "engines": { + "node": ">= 0.8" } }, - "glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" + "dependencies": { + "wrappy": "1" } }, - "glob-parent": { + "node_modules/onetime": { "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", "dev": true, - "requires": { - "is-glob": "^4.0.1" + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "glob-to-regexp": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", - "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", - "dev": true - }, - "global-dirs": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-0.1.1.tgz", - "integrity": "sha512-NknMLn7F2J7aflwFOlGdNIuCDpN3VGoSoB+aap3KABFWbHVn1TCgFC+np23J8W2BiZbjfEw3BFBycSMv1AFblg==", + "node_modules/open": { + "version": "8.4.2", + "resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz", + "integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==", "dev": true, - "requires": { - "ini": "^1.3.4" + "dependencies": { + "define-lazy-prop": "^2.0.0", + "is-docker": "^2.1.1", + "is-wsl": "^2.2.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "dev": true - }, - "gopd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", - "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "node_modules/optionator": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", + "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", "dev": true, - "requires": { - "get-intrinsic": "^1.1.3" + "dependencies": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.6", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "word-wrap": "~1.2.3" + }, + "engines": { + "node": ">= 0.8.0" } }, - "graceful-fs": { - "version": "4.2.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", - "dev": true + "node_modules/os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "handle-thing": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz", - "integrity": "sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==", - "dev": true + "node_modules/p-each-series": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-each-series/-/p-each-series-3.0.0.tgz", + "integrity": "sha512-lastgtAdoH9YaLyDa5i5z64q+kzOcQHsQ5SsZJD3q0VEyI8mq872S3geuNbRUQLVAE9siMfgKrpj7MloKFHruw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, - "hard-rejection": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz", - "integrity": "sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==", - "dev": true + "node_modules/p-filter": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-filter/-/p-filter-4.1.0.tgz", + "integrity": "sha512-37/tPdZ3oJwHaS3gNJdenCDB3Tz26i9sjhnguBtvN0vYlRIiDNnvTWkuh+0hETV9rLPdJ3rlL3yVOYPIAnM8rw==", + "dev": true, + "dependencies": { + "p-map": "^7.0.1" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, - "has-ansi": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", - "integrity": "sha512-C8vBJ8DwUCx19vhm7urhTuUsr4/IyP6l4VzNQDv+ryHQObW3TTTp9yB68WpYgRe2bbaGuZ/se74IqFeVnMnLZg==", + "node_modules/p-is-promise": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-3.0.0.tgz", + "integrity": "sha512-Wo8VsW4IRQSKVXsJCn7TomUaVtyfjVDn3nUP7kE967BQk0CwFpdbZs0X0uk5sW9mkBa9eNM7hCMaG93WUAwxYQ==", "dev": true, - "requires": { - "ansi-regex": "^2.0.0" + "engines": { + "node": ">=8" + } + }, + "node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", - "dev": true - } + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" } }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true + "node_modules/p-map": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-7.0.2.tgz", + "integrity": "sha512-z4cYYMMdKHzw4O5UkWJImbZynVIo0lSGTXc7bzB1e/rrDqkgGUNysK/o4bTr+0+xKvvLoTyGqYC4Fgljy9qe1Q==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, - "has-property-descriptors": { + "node_modules/p-reduce": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-reduce/-/p-reduce-3.0.0.tgz", + "integrity": "sha512-xsrIUgI0Kn6iyDYm9StOpOeK29XM1aboGji26+QEortiFST1hGZaUQOLhtEbqHErPpGW/aSz6allwK2qcptp0Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-retry": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-4.6.2.tgz", + "integrity": "sha512-312Id396EbJdvRONlngUx0NydfrIQ5lsYu0znKVUzVvArzEIt08V1qhtyESbGVd1FGX7UKtiFp5uwKZdM8wIuQ==", + "dev": true, + "dependencies": { + "@types/retry": "0.12.0", + "retry": "^0.13.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/parent-module": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz", - "integrity": "sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg==", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", "dev": true, - "requires": { - "get-intrinsic": "^1.2.2" + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" } }, - "has-proto": { + "node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parse5": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz", + "integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==", + "dependencies": { + "entities": "^4.4.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", - "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", - "dev": true + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "node_modules/path-is-inside": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", + "integrity": "sha512-DUWJr3+ULp4zXmol/SZkFf3JGsS9/SIv+Y3Rt93/UjPpDpklB5f1er4O3POIbUuUJ3FXgqte2Q7SrU6zAqwk8w==", "dev": true }, - "hasown": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz", - "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==", + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "dev": true, - "requires": { - "function-bind": "^1.1.2" + "engines": { + "node": ">=8" } }, - "hosted-git-info": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz", - "integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==", + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "node_modules/path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==", + "dev": true + }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", "dev": true, - "requires": { - "lru-cache": "^6.0.0" + "engines": { + "node": ">=8" } }, - "hpack.js": { - "version": "2.1.6", - "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz", - "integrity": "sha512-zJxVehUdMGIKsRaNt7apO2Gqp0BdqW5yaiGHXXmbpvxgBYVZnAql+BJb4RO5ad2MgpbZKn5G6nMnegrH1FcNYQ==", + "node_modules/picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "dev": true + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "dev": true, - "requires": { - "inherits": "^2.0.1", - "obuf": "^1.0.0", - "readable-stream": "^2.0.1", - "wbuf": "^1.1.0" + "engines": { + "node": ">=8.6" }, - "dependencies": { - "readable-stream": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", - "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/pkg-conf": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/pkg-conf/-/pkg-conf-2.1.0.tgz", + "integrity": "sha512-C+VUP+8jis7EsQZIhDYmS5qlNtjv2yP4SNtjXK9AP1ZcTRlnSfuumaTnRfYZnYgUUYVIKqL0fRvmUGDV2fmp6g==", + "dev": true, + "license": "MIT", + "dependencies": { + "find-up": "^2.0.0", + "load-json-file": "^4.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/pkg-conf/node_modules/find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/pkg-conf/node_modules/locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/pkg-conf/node_modules/p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-try": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/pkg-conf/node_modules/p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^1.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/pkg-conf/node_modules/p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/pkg-conf/node_modules/path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "dependencies": { + "find-up": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pluralize": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-7.0.0.tgz", + "integrity": "sha512-ARhBOdzS3e41FbkW/XWrTEtukqqLoK5+Z/4UeDaLuSW+39JPeFgs4gCGqsrJHVZX0fUrx//4OF0K1CUGwlIFow==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "dev": true + }, + "node_modules/progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/proto-list": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz", + "integrity": "sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==", + "dev": true + }, + "node_modules/proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "dev": true, + "dependencies": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/proxy-addr/node_modules/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "dev": true, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==", + "dev": true + }, + "node_modules/psl": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", + "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==" + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "engines": { + "node": ">=6" + } + }, + "node_modules/q": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", + "integrity": "sha512-kV/CThkXo6xyFEZUugw/+pIOywXcDbFYgSct5cT3gqlbkBE1SJdwy6UQoZvodiWF/ckQLZyDE/Bu1M6gVu5lVw==", + "deprecated": "You or someone you depend on is using Q, the JavaScript Promise library that gave JavaScript developers strong feelings about promises. They can almost certainly migrate to the native JavaScript promise now. Thank you literally everyone for joining me in this bet against the odds. Be excellent to each other.\n\n(For a CapTP with native promises, see @endo/eventual-send and @endo/captp)", + "dev": true, + "engines": { + "node": ">=0.6.0", + "teleport": ">=0.2.0" + } + }, + "node_modules/qs": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", + "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", + "dev": true, + "dependencies": { + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/querystringify": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", + "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==" + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/quick-lru": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz", + "integrity": "sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/raw-body": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", + "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", + "dev": true, + "dependencies": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/raw-body/node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/raw-body/node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "dev": true, + "dependencies": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "bin": { + "rc": "cli.js" + } + }, + "node_modules/read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "dev": true, + "dependencies": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/read-pkg-up": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", + "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "dev": true, + "dependencies": { + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/read-pkg-up/node_modules/type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/read-pkg/node_modules/hosted-git-info": { + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", + "dev": true + }, + "node_modules/read-pkg/node_modules/normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "dependencies": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "node_modules/read-pkg/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/read-pkg/node_modules/type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/rechoir": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.7.1.tgz", + "integrity": "sha512-/njmZ8s1wVeR6pjTZ+0nCnv8SpZNRMT2D1RLOJQESlYFDBvwpTA4KWJpZ+sBJ4+vhjILRcK7JIFdGCdxEAAitg==", + "dev": true, + "dependencies": { + "resolve": "^1.9.0" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/redent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", + "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", + "dev": true, + "dependencies": { + "indent-string": "^4.0.0", + "strip-indent": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/redeyed": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/redeyed/-/redeyed-2.1.1.tgz", + "integrity": "sha512-FNpGGo1DycYAdnrKFxCMmKYgo/mILAqtRYbkdQD8Ep/Hk2PQ5+aEAEx+IU713RTDmuBaH0c8P5ZozurNu5ObRQ==", + "dev": true, + "dependencies": { + "esprima": "~4.0.0" + } + }, + "node_modules/regexpp": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-1.1.0.tgz", + "integrity": "sha512-LOPw8FpgdQF9etWMaAfG/WRthIdXJGYp4mJ2Jgn/2lpkbod9jPn0t9UqN7AxBOKNfzRbYyVfgc7Vk4t/MpnXgw==", + "dev": true, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/registry-auth-token": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-5.0.2.tgz", + "integrity": "sha512-o/3ikDxtXaA59BmZuZrJZDJv8NMDGSj+6j6XaeBmHw8eY1i1qd9+6H+LjVvQXx3HN6aRCGa1cUdJ9RaJZUugnQ==", + "dev": true, + "dependencies": { + "@pnpm/npm-conf": "^2.1.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-uncached": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz", + "integrity": "sha512-Xct+41K3twrbBHdxAgMoOS+cNcoqIjfM2/VxBF4LL2hVph7YsF8VSKyQ3BDFZwEVbok9yeDl2le/qo0S77WG2w==", + "dev": true, + "dependencies": { + "caller-path": "^0.1.0", + "resolve-from": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-uncached/node_modules/resolve-from": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-1.0.1.tgz", + "integrity": "sha512-kT10v4dhrlLNcnO084hEjvXCI1wUG9qZLoz2RogxqDQQYy7IxjI/iMUkOtQTNEh6rzHxvdQWHsJyel1pKOVCxg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==" + }, + "node_modules/resolve": { + "version": "1.22.8", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", + "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", + "dev": true, + "dependencies": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-cwd": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", + "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", + "dev": true, + "dependencies": { + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve-global": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/resolve-global/-/resolve-global-1.0.0.tgz", + "integrity": "sha512-zFa12V4OLtT5XUX/Q4VLvTfBf+Ok0SPc1FNGM/z9ctUdiU618qwKpWnd0CHs3+RqROfyEg/DhuHbMWYqcgljEw==", + "dev": true, + "dependencies": { + "global-dirs": "^0.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/restore-cursor": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", + "integrity": "sha512-6IzJLuGi4+R14vwagDHX+JrXmPVtPpn4mffDJ1UdR7/Edm87fl6yi8mMBIVvFtJaNTUvjughmW4hwLhRG7gC1Q==", + "dev": true, + "dependencies": { + "onetime": "^2.0.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/restore-cursor/node_modules/mimic-fn": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", + "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/restore-cursor/node_modules/onetime": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", + "integrity": "sha512-oyyPpiMaKARvvcgip+JV+7zci5L8D1W9RZIz2l1o08AM3pfspitVWnPt3mzHcBPp12oYMTy0pqrFs/C+m3EwsQ==", + "dev": true, + "dependencies": { + "mimic-fn": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/retry": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", + "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true, + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rrweb-cssom": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.6.0.tgz", + "integrity": "sha512-APM0Gt1KoXBz0iIkkdB/kfvGOwC4UuJFeG/c+yV7wSc7q96cG/kJ0HiYCnzivD9SB53cLV1MlHFNfOuPaadYSw==" + }, + "node_modules/run-async": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", + "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/rx-lite": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-4.0.8.tgz", + "integrity": "sha512-Cun9QucwK6MIrp3mry/Y7hqD1oFqTYLQ4pGxaHTjIdaFDWRGGLikqp6u8LcWJnzpoALg9hap+JGk8sFIUuEGNA==", + "dev": true + }, + "node_modules/rx-lite-aggregates": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/rx-lite-aggregates/-/rx-lite-aggregates-4.0.8.tgz", + "integrity": "sha512-3xPNZGW93oCjiO7PtKxRK6iOVYBWBvtf9QHDfU23Oc+dLIQmAV//UnyXV/yihv81VS/UqoQPk4NegS8EFi55Hg==", + "dev": true, + "dependencies": { + "rx-lite": "*" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "node_modules/saxes": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz", + "integrity": "sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==", + "dependencies": { + "xmlchars": "^2.2.0" + }, + "engines": { + "node": ">=v12.22.7" + } + }, + "node_modules/schema-utils": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", + "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/scratch-semantic-release-config": { + "version": "1.0.16", + "resolved": "https://registry.npmjs.org/scratch-semantic-release-config/-/scratch-semantic-release-config-1.0.16.tgz", + "integrity": "sha512-gY2f+aL0t7WyHWsV9vWDJk1VGPm1m2fuRQB4iqZ7XOZY88lH7Mws9/pvFDBSNCEQVDWC7TQxsMudFSUrhSljxA==", + "dev": true, + "dependencies": { + "@semantic-release/changelog": "^6.0.1", + "@semantic-release/commit-analyzer": "^9.0.2", + "@semantic-release/git": "^10.0.1", + "@semantic-release/github": "^8.0.4", + "@semantic-release/npm": "^9.0.1", + "@semantic-release/release-notes-generator": "^10.0.3" + }, + "peerDependencies": { + "semantic-release": ">=19.0.2" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/@octokit/auth-token": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-3.0.4.tgz", + "integrity": "sha512-TWFX7cZF2LXoCvdmJWY7XVPi74aSY0+FfBZNSXEXFkMpjcqsQwDSYVv5FhRFaI0V1ECnwbz4j59T/G+rXNWaIQ==", + "dev": true, + "engines": { + "node": ">= 14" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/@octokit/core": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/@octokit/core/-/core-4.2.4.tgz", + "integrity": "sha512-rYKilwgzQ7/imScn3M9/pFfUf4I1AZEH3KhyJmtPdE2zfaXAn2mFfUy4FbKewzc2We5y/LlKLj36fWJLKC2SIQ==", + "dev": true, + "dependencies": { + "@octokit/auth-token": "^3.0.0", + "@octokit/graphql": "^5.0.0", + "@octokit/request": "^6.0.0", + "@octokit/request-error": "^3.0.0", + "@octokit/types": "^9.0.0", + "before-after-hook": "^2.2.0", + "universal-user-agent": "^6.0.0" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/@octokit/endpoint": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-7.0.6.tgz", + "integrity": "sha512-5L4fseVRUsDFGR00tMWD/Trdeeihn999rTMGRMC1G/Ldi1uWlWJzI98H4Iak5DB/RVvQuyMYKqSK/R6mbSOQyg==", + "dev": true, + "dependencies": { + "@octokit/types": "^9.0.0", + "is-plain-object": "^5.0.0", + "universal-user-agent": "^6.0.0" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/@octokit/graphql": { + "version": "5.0.6", + "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-5.0.6.tgz", + "integrity": "sha512-Fxyxdy/JH0MnIB5h+UQ3yCoh1FG4kWXfFKkpWqjZHw/p+Kc8Y44Hu/kCgNBT6nU1shNumEchmW/sUO1JuQnPcw==", + "dev": true, + "dependencies": { + "@octokit/request": "^6.0.0", + "@octokit/types": "^9.0.0", + "universal-user-agent": "^6.0.0" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/@octokit/openapi-types": { + "version": "18.1.1", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-18.1.1.tgz", + "integrity": "sha512-VRaeH8nCDtF5aXWnjPuEMIYf1itK/s3JYyJcWFJT8X9pSNnBtriDf7wlEWsGuhPLl4QIH4xM8fqTXDwJ3Mu6sw==", + "dev": true + }, + "node_modules/scratch-semantic-release-config/node_modules/@octokit/plugin-paginate-rest": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-6.1.2.tgz", + "integrity": "sha512-qhrmtQeHU/IivxucOV1bbI/xZyC/iOBhclokv7Sut5vnejAIAEXVcGQeRpQlU39E0WwK9lNvJHphHri/DB6lbQ==", + "dev": true, + "dependencies": { + "@octokit/tsconfig": "^1.0.2", + "@octokit/types": "^9.2.3" + }, + "engines": { + "node": ">= 14" + }, + "peerDependencies": { + "@octokit/core": ">=4" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/@octokit/plugin-retry": { + "version": "4.1.6", + "resolved": "https://registry.npmjs.org/@octokit/plugin-retry/-/plugin-retry-4.1.6.tgz", + "integrity": "sha512-obkYzIgEC75r8+9Pnfiiqy3y/x1bc3QLE5B7qvv9wi9Kj0R5tGQFC6QMBg1154WQ9lAVypuQDGyp3hNpp15gQQ==", + "dev": true, + "dependencies": { + "@octokit/types": "^9.0.0", + "bottleneck": "^2.15.3" + }, + "engines": { + "node": ">= 14" + }, + "peerDependencies": { + "@octokit/core": ">=3" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/@octokit/plugin-throttling": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/@octokit/plugin-throttling/-/plugin-throttling-5.2.3.tgz", + "integrity": "sha512-C9CFg9mrf6cugneKiaI841iG8DOv6P5XXkjmiNNut+swePxQ7RWEdAZRp5rJoE1hjsIqiYcKa/ZkOQ+ujPI39Q==", + "dev": true, + "dependencies": { + "@octokit/types": "^9.0.0", + "bottleneck": "^2.15.3" + }, + "engines": { + "node": ">= 14" + }, + "peerDependencies": { + "@octokit/core": "^4.0.0" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/@octokit/request": { + "version": "6.2.8", + "resolved": "https://registry.npmjs.org/@octokit/request/-/request-6.2.8.tgz", + "integrity": "sha512-ow4+pkVQ+6XVVsekSYBzJC0VTVvh/FCTUUgTsboGq+DTeWdyIFV8WSCdo0RIxk6wSkBTHqIK1mYuY7nOBXOchw==", + "dev": true, + "dependencies": { + "@octokit/endpoint": "^7.0.0", + "@octokit/request-error": "^3.0.0", + "@octokit/types": "^9.0.0", + "is-plain-object": "^5.0.0", + "node-fetch": "^2.6.7", + "universal-user-agent": "^6.0.0" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/@octokit/request-error": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-3.0.3.tgz", + "integrity": "sha512-crqw3V5Iy2uOU5Np+8M/YexTlT8zxCfI+qu+LxUB7SZpje4Qmx3mub5DfEKSO8Ylyk0aogi6TYdf6kxzh2BguQ==", + "dev": true, + "dependencies": { + "@octokit/types": "^9.0.0", + "deprecation": "^2.0.0", + "once": "^1.4.0" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/@octokit/types": { + "version": "9.3.2", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-9.3.2.tgz", + "integrity": "sha512-D4iHGTdAnEEVsB8fl95m1hiz7D5YiRdQ9b/OEb3BYRVwbLsGHcRVPz+u+BgRLNk0Q0/4iZCBqDN96j2XNxfXrA==", + "dev": true, + "dependencies": { + "@octokit/openapi-types": "^18.0.0" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/@semantic-release/commit-analyzer": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/@semantic-release/commit-analyzer/-/commit-analyzer-9.0.2.tgz", + "integrity": "sha512-E+dr6L+xIHZkX4zNMe6Rnwg4YQrWNXK+rNsvwOPpdFppvZO1olE2fIgWhv89TkQErygevbjsZFSIxp+u6w2e5g==", + "dev": true, + "dependencies": { + "conventional-changelog-angular": "^5.0.0", + "conventional-commits-filter": "^2.0.0", + "conventional-commits-parser": "^3.2.3", + "debug": "^4.0.0", + "import-from": "^4.0.0", + "lodash": "^4.17.4", + "micromatch": "^4.0.2" + }, + "engines": { + "node": ">=14.17" + }, + "peerDependencies": { + "semantic-release": ">=18.0.0-beta.1" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/@semantic-release/error": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@semantic-release/error/-/error-3.0.0.tgz", + "integrity": "sha512-5hiM4Un+tpl4cKw3lV4UgzJj+SmfNIDCLLw0TepzQxz9ZGV5ixnqkzIVF+3tp0ZHgcMKE+VNGHJjEeyFG2dcSw==", + "dev": true, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/@semantic-release/github": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@semantic-release/github/-/github-8.1.0.tgz", + "integrity": "sha512-erR9E5rpdsz0dW1I7785JtndQuMWN/iDcemcptf67tBNOmBUN0b2YNOgcjYUnBpgRpZ5ozfBHrK7Bz+2ets/Dg==", + "dev": true, + "dependencies": { + "@octokit/core": "^4.2.1", + "@octokit/plugin-paginate-rest": "^6.1.2", + "@octokit/plugin-retry": "^4.1.3", + "@octokit/plugin-throttling": "^5.2.3", + "@semantic-release/error": "^3.0.0", + "aggregate-error": "^3.0.0", + "debug": "^4.0.0", + "dir-glob": "^3.0.0", + "fs-extra": "^11.0.0", + "globby": "^11.0.0", + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.0", + "issue-parser": "^6.0.0", + "lodash": "^4.17.4", + "mime": "^3.0.0", + "p-filter": "^2.0.0", + "url-join": "^4.0.0" + }, + "engines": { + "node": ">=14.17" + }, + "peerDependencies": { + "semantic-release": ">=18.0.0-beta.1" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/@semantic-release/npm": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/@semantic-release/npm/-/npm-9.0.2.tgz", + "integrity": "sha512-zgsynF6McdzxPnFet+a4iO9HpAlARXOM5adz7VGVCvj0ne8wtL2ZOQoDV2wZPDmdEotDIbVeJjafhelZjs9j6g==", + "dev": true, + "dependencies": { + "@semantic-release/error": "^3.0.0", + "aggregate-error": "^3.0.0", + "execa": "^5.0.0", + "fs-extra": "^11.0.0", + "lodash": "^4.17.15", + "nerf-dart": "^1.0.0", + "normalize-url": "^6.0.0", + "npm": "^8.3.0", + "rc": "^1.2.8", + "read-pkg": "^5.0.0", + "registry-auth-token": "^5.0.0", + "semver": "^7.1.2", + "tempy": "^1.0.0" + }, + "engines": { + "node": ">=16 || ^14.17" + }, + "peerDependencies": { + "semantic-release": ">=19.0.0" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/@semantic-release/release-notes-generator": { + "version": "10.0.3", + "resolved": "https://registry.npmjs.org/@semantic-release/release-notes-generator/-/release-notes-generator-10.0.3.tgz", + "integrity": "sha512-k4x4VhIKneOWoBGHkx0qZogNjCldLPRiAjnIpMnlUh6PtaWXp/T+C9U7/TaNDDtgDa5HMbHl4WlREdxHio6/3w==", + "dev": true, + "dependencies": { + "conventional-changelog-angular": "^5.0.0", + "conventional-changelog-writer": "^5.0.0", + "conventional-commits-filter": "^2.0.0", + "conventional-commits-parser": "^3.2.3", + "debug": "^4.0.0", + "get-stream": "^6.0.0", + "import-from": "^4.0.0", + "into-stream": "^6.0.0", + "lodash": "^4.17.4", + "read-pkg-up": "^7.0.0" + }, + "engines": { + "node": ">=14.17" + }, + "peerDependencies": { + "semantic-release": ">=18.0.0-beta.1" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/aggregate-error": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", + "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", + "dev": true, + "dependencies": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/conventional-changelog-angular": { + "version": "5.0.13", + "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-5.0.13.tgz", + "integrity": "sha512-i/gipMxs7s8L/QeuavPF2hLnJgH6pEZAttySB6aiQLWcX3puWDL3ACVmvBhJGxnAy52Qc15ua26BufY6KpmrVA==", + "dev": true, + "dependencies": { + "compare-func": "^2.0.0", + "q": "^1.5.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/conventional-changelog-writer": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/conventional-changelog-writer/-/conventional-changelog-writer-5.0.1.tgz", + "integrity": "sha512-5WsuKUfxW7suLblAbFnxAcrvf6r+0b7GvNaWUwUIk0bXMnENP/PEieGKVUQrjPqwPT4o3EPAASBXiY6iHooLOQ==", + "dev": true, + "dependencies": { + "conventional-commits-filter": "^2.0.7", + "dateformat": "^3.0.0", + "handlebars": "^4.7.7", + "json-stringify-safe": "^5.0.1", + "lodash": "^4.17.15", + "meow": "^8.0.0", + "semver": "^6.0.0", + "split": "^1.0.0", + "through2": "^4.0.0" + }, + "bin": { + "conventional-changelog-writer": "cli.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/conventional-changelog-writer/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/conventional-commits-filter": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/conventional-commits-filter/-/conventional-commits-filter-2.0.7.tgz", + "integrity": "sha512-ASS9SamOP4TbCClsRHxIHXRfcGCnIoQqkvAzCSbZzTFLfcTqJVugB0agRgsEELsqaeWgsXv513eS116wnlSSPA==", + "dev": true, + "dependencies": { + "lodash.ismatch": "^4.4.0", + "modify-values": "^1.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/conventional-commits-parser": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-3.2.4.tgz", + "integrity": "sha512-nK7sAtfi+QXbxHCYfhpZsfRtaitZLIA6889kFIouLvz6repszQDgxBu7wf2WbU+Dco7sAnNCJYERCwt54WPC2Q==", + "dev": true, + "dependencies": { + "is-text-path": "^1.0.1", + "JSONStream": "^1.0.4", + "lodash": "^4.17.15", + "meow": "^8.0.0", + "split2": "^3.0.0", + "through2": "^4.0.0" + }, + "bin": { + "conventional-commits-parser": "cli.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/crypto-random-string": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz", + "integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dev": true, + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/into-stream": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/into-stream/-/into-stream-6.0.0.tgz", + "integrity": "sha512-XHbaOAvP+uFKUFsOgoNPRjLkwB+I22JFPFe5OjTkQ0nwgj6+pSjb4NmB6VMxaPshLiOf+zcpOCBQuLwC1KHhZA==", + "dev": true, + "dependencies": { + "from2": "^2.3.0", + "p-is-promise": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/is-plain-object": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", + "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/mime": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-3.0.0.tgz", + "integrity": "sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==", + "dev": true, + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/normalize-url": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", + "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm": { + "version": "8.19.4", + "resolved": "https://registry.npmjs.org/npm/-/npm-8.19.4.tgz", + "integrity": "sha512-3HANl8i9DKnUA89P4KEgVNN28EjSeDCmvEqbzOAuxCFDzdBZzjUl99zgnGpOUumvW5lvJo2HKcjrsc+tfyv1Hw==", + "bundleDependencies": [ + "@isaacs/string-locale-compare", + "@npmcli/arborist", + "@npmcli/ci-detect", + "@npmcli/config", + "@npmcli/fs", + "@npmcli/map-workspaces", + "@npmcli/package-json", + "@npmcli/run-script", + "abbrev", + "archy", + "cacache", + "chalk", + "chownr", + "cli-columns", + "cli-table3", + "columnify", + "fastest-levenshtein", + "fs-minipass", + "glob", + "graceful-fs", + "hosted-git-info", + "ini", + "init-package-json", + "is-cidr", + "json-parse-even-better-errors", + "libnpmaccess", + "libnpmdiff", + "libnpmexec", + "libnpmfund", + "libnpmhook", + "libnpmorg", + "libnpmpack", + "libnpmpublish", + "libnpmsearch", + "libnpmteam", + "libnpmversion", + "make-fetch-happen", + "minimatch", + "minipass", + "minipass-pipeline", + "mkdirp", + "mkdirp-infer-owner", + "ms", + "node-gyp", + "nopt", + "npm-audit-report", + "npm-install-checks", + "npm-package-arg", + "npm-pick-manifest", + "npm-profile", + "npm-registry-fetch", + "npm-user-validate", + "npmlog", + "opener", + "p-map", + "pacote", + "parse-conflict-json", + "proc-log", + "qrcode-terminal", + "read", + "read-package-json", + "read-package-json-fast", + "readdir-scoped-modules", + "rimraf", + "semver", + "ssri", + "tar", + "text-table", + "tiny-relative-date", + "treeverse", + "validate-npm-package-name", + "which", + "write-file-atomic" + ], + "dev": true, + "workspaces": [ + "docs", + "smoke-tests", + "workspaces/*" + ], + "dependencies": { + "@isaacs/string-locale-compare": "^1.1.0", + "@npmcli/arborist": "^5.6.3", + "@npmcli/ci-detect": "^2.0.0", + "@npmcli/config": "^4.2.1", + "@npmcli/fs": "^2.1.0", + "@npmcli/map-workspaces": "^2.0.3", + "@npmcli/package-json": "^2.0.0", + "@npmcli/run-script": "^4.2.1", + "abbrev": "~1.1.1", + "archy": "~1.0.0", + "cacache": "^16.1.3", + "chalk": "^4.1.2", + "chownr": "^2.0.0", + "cli-columns": "^4.0.0", + "cli-table3": "^0.6.2", + "columnify": "^1.6.0", + "fastest-levenshtein": "^1.0.12", + "fs-minipass": "^2.1.0", + "glob": "^8.0.1", + "graceful-fs": "^4.2.10", + "hosted-git-info": "^5.2.1", + "ini": "^3.0.1", + "init-package-json": "^3.0.2", + "is-cidr": "^4.0.2", + "json-parse-even-better-errors": "^2.3.1", + "libnpmaccess": "^6.0.4", + "libnpmdiff": "^4.0.5", + "libnpmexec": "^4.0.14", + "libnpmfund": "^3.0.5", + "libnpmhook": "^8.0.4", + "libnpmorg": "^4.0.4", + "libnpmpack": "^4.1.3", + "libnpmpublish": "^6.0.5", + "libnpmsearch": "^5.0.4", + "libnpmteam": "^4.0.4", + "libnpmversion": "^3.0.7", + "make-fetch-happen": "^10.2.0", + "minimatch": "^5.1.0", + "minipass": "^3.1.6", + "minipass-pipeline": "^1.2.4", + "mkdirp": "^1.0.4", + "mkdirp-infer-owner": "^2.0.0", + "ms": "^2.1.2", + "node-gyp": "^9.1.0", + "nopt": "^6.0.0", + "npm-audit-report": "^3.0.0", + "npm-install-checks": "^5.0.0", + "npm-package-arg": "^9.1.0", + "npm-pick-manifest": "^7.0.2", + "npm-profile": "^6.2.0", + "npm-registry-fetch": "^13.3.1", + "npm-user-validate": "^1.0.1", + "npmlog": "^6.0.2", + "opener": "^1.5.2", + "p-map": "^4.0.0", + "pacote": "^13.6.2", + "parse-conflict-json": "^2.0.2", + "proc-log": "^2.0.1", + "qrcode-terminal": "^0.12.0", + "read": "~1.0.7", + "read-package-json": "^5.0.2", + "read-package-json-fast": "^2.0.3", + "readdir-scoped-modules": "^1.1.0", + "rimraf": "^3.0.2", + "semver": "^7.3.7", + "ssri": "^9.0.1", + "tar": "^6.1.11", + "text-table": "~0.2.0", + "tiny-relative-date": "^1.3.0", + "treeverse": "^2.0.0", + "validate-npm-package-name": "^4.0.0", + "which": "^2.0.2", + "write-file-atomic": "^4.0.1" + }, + "bin": { + "npm": "bin/npm-cli.js", + "npx": "bin/npx-cli.js" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/@colors/colors": { + "version": "1.5.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.1.90" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/@gar/promisify": { + "version": "1.1.3", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/@isaacs/string-locale-compare": { + "version": "1.1.0", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/@npmcli/arborist": { + "version": "5.6.3", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "@isaacs/string-locale-compare": "^1.1.0", + "@npmcli/installed-package-contents": "^1.0.7", + "@npmcli/map-workspaces": "^2.0.3", + "@npmcli/metavuln-calculator": "^3.0.1", + "@npmcli/move-file": "^2.0.0", + "@npmcli/name-from-folder": "^1.0.1", + "@npmcli/node-gyp": "^2.0.0", + "@npmcli/package-json": "^2.0.0", + "@npmcli/query": "^1.2.0", + "@npmcli/run-script": "^4.1.3", + "bin-links": "^3.0.3", + "cacache": "^16.1.3", + "common-ancestor-path": "^1.0.1", + "hosted-git-info": "^5.2.1", + "json-parse-even-better-errors": "^2.3.1", + "json-stringify-nice": "^1.1.4", + "minimatch": "^5.1.0", + "mkdirp": "^1.0.4", + "mkdirp-infer-owner": "^2.0.0", + "nopt": "^6.0.0", + "npm-install-checks": "^5.0.0", + "npm-package-arg": "^9.0.0", + "npm-pick-manifest": "^7.0.2", + "npm-registry-fetch": "^13.0.0", + "npmlog": "^6.0.2", + "pacote": "^13.6.1", + "parse-conflict-json": "^2.0.1", + "proc-log": "^2.0.0", + "promise-all-reject-late": "^1.0.0", + "promise-call-limit": "^1.0.1", + "read-package-json-fast": "^2.0.2", + "readdir-scoped-modules": "^1.1.0", + "rimraf": "^3.0.2", + "semver": "^7.3.7", + "ssri": "^9.0.0", + "treeverse": "^2.0.0", + "walk-up-path": "^1.0.0" + }, + "bin": { + "arborist": "bin/index.js" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/@npmcli/ci-detect": { + "version": "2.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/@npmcli/config": { + "version": "4.2.2", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/map-workspaces": "^2.0.2", + "ini": "^3.0.0", + "mkdirp-infer-owner": "^2.0.0", + "nopt": "^6.0.0", + "proc-log": "^2.0.0", + "read-package-json-fast": "^2.0.3", + "semver": "^7.3.5", + "walk-up-path": "^1.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/@npmcli/disparity-colors": { + "version": "2.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "ansi-styles": "^4.3.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/@npmcli/fs": { + "version": "2.1.2", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "@gar/promisify": "^1.1.3", + "semver": "^7.3.5" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/@npmcli/git": { + "version": "3.0.2", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/promise-spawn": "^3.0.0", + "lru-cache": "^7.4.4", + "mkdirp": "^1.0.4", + "npm-pick-manifest": "^7.0.0", + "proc-log": "^2.0.0", + "promise-inflight": "^1.0.1", + "promise-retry": "^2.0.1", + "semver": "^7.3.5", + "which": "^2.0.2" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/@npmcli/installed-package-contents": { + "version": "1.0.7", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "npm-bundled": "^1.1.1", + "npm-normalize-package-bin": "^1.0.1" + }, + "bin": { + "installed-package-contents": "index.js" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/@npmcli/installed-package-contents/node_modules/npm-bundled": { + "version": "1.1.2", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "npm-normalize-package-bin": "^1.0.1" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/@npmcli/map-workspaces": { + "version": "2.0.4", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/name-from-folder": "^1.0.1", + "glob": "^8.0.1", + "minimatch": "^5.0.1", + "read-package-json-fast": "^2.0.3" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/@npmcli/metavuln-calculator": { + "version": "3.1.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "cacache": "^16.0.0", + "json-parse-even-better-errors": "^2.3.1", + "pacote": "^13.0.3", + "semver": "^7.3.5" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/@npmcli/move-file": { + "version": "2.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "mkdirp": "^1.0.4", + "rimraf": "^3.0.2" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/@npmcli/name-from-folder": { + "version": "1.0.1", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/@npmcli/node-gyp": { + "version": "2.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/@npmcli/package-json": { + "version": "2.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "json-parse-even-better-errors": "^2.3.1" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/@npmcli/promise-spawn": { + "version": "3.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "infer-owner": "^1.0.4" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/@npmcli/query": { + "version": "1.2.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "npm-package-arg": "^9.1.0", + "postcss-selector-parser": "^6.0.10", + "semver": "^7.3.7" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/@npmcli/run-script": { + "version": "4.2.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/node-gyp": "^2.0.0", + "@npmcli/promise-spawn": "^3.0.0", + "node-gyp": "^9.0.0", + "read-package-json-fast": "^2.0.3", + "which": "^2.0.2" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/@tootallnate/once": { + "version": "2.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">= 10" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/abbrev": { + "version": "1.1.1", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/agent-base": { + "version": "6.0.2", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/agentkeepalive": { + "version": "4.2.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "debug": "^4.1.0", + "depd": "^1.1.2", + "humanize-ms": "^1.2.1" + }, + "engines": { + "node": ">= 8.0.0" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/aggregate-error": { + "version": "3.1.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/ansi-regex": { + "version": "5.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/ansi-styles": { + "version": "4.3.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/aproba": { + "version": "2.0.0", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/archy": { + "version": "1.0.0", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/are-we-there-yet": { + "version": "3.0.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "delegates": "^1.0.0", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/asap": { + "version": "2.0.6", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/balanced-match": { + "version": "1.0.2", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/bin-links": { + "version": "3.0.3", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "cmd-shim": "^5.0.0", + "mkdirp-infer-owner": "^2.0.0", + "npm-normalize-package-bin": "^2.0.0", + "read-cmd-shim": "^3.0.0", + "rimraf": "^3.0.0", + "write-file-atomic": "^4.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/bin-links/node_modules/npm-normalize-package-bin": { + "version": "2.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/binary-extensions": { + "version": "2.2.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/brace-expansion": { + "version": "2.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/builtins": { + "version": "5.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "semver": "^7.0.0" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/cacache": { + "version": "16.1.3", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/fs": "^2.1.0", + "@npmcli/move-file": "^2.0.0", + "chownr": "^2.0.0", + "fs-minipass": "^2.1.0", + "glob": "^8.0.1", + "infer-owner": "^1.0.4", + "lru-cache": "^7.7.1", + "minipass": "^3.1.6", + "minipass-collect": "^1.0.2", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "mkdirp": "^1.0.4", + "p-map": "^4.0.0", + "promise-inflight": "^1.0.1", + "rimraf": "^3.0.2", + "ssri": "^9.0.0", + "tar": "^6.1.11", + "unique-filename": "^2.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/chalk": { + "version": "4.1.2", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/chownr": { + "version": "2.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/cidr-regex": { + "version": "3.1.1", + "dev": true, + "inBundle": true, + "license": "BSD-2-Clause", + "dependencies": { + "ip-regex": "^4.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/clean-stack": { + "version": "2.2.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/cli-columns": { + "version": "4.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/cli-table3": { + "version": "0.6.2", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "string-width": "^4.2.0" + }, + "engines": { + "node": "10.* || >= 12.*" + }, + "optionalDependencies": { + "@colors/colors": "1.5.0" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/clone": { + "version": "1.0.4", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/cmd-shim": { + "version": "5.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "mkdirp-infer-owner": "^2.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/color-convert": { + "version": "2.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/color-name": { + "version": "1.1.4", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/color-support": { + "version": "1.1.3", + "dev": true, + "inBundle": true, + "license": "ISC", + "bin": { + "color-support": "bin.js" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/columnify": { + "version": "1.6.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "strip-ansi": "^6.0.1", + "wcwidth": "^1.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/common-ancestor-path": { + "version": "1.0.1", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/concat-map": { + "version": "0.0.1", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/console-control-strings": { + "version": "1.1.0", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/cssesc": { + "version": "3.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/debug": { + "version": "4.3.4", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/debug/node_modules/ms": { + "version": "2.1.2", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/debuglog": { + "version": "1.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/defaults": { + "version": "1.0.3", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "clone": "^1.0.2" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/delegates": { + "version": "1.0.0", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/depd": { + "version": "1.1.2", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/dezalgo": { + "version": "1.0.4", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "asap": "^2.0.0", + "wrappy": "1" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/diff": { + "version": "5.1.0", + "dev": true, + "inBundle": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/emoji-regex": { + "version": "8.0.0", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/encoding": { + "version": "0.1.13", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true, + "dependencies": { + "iconv-lite": "^0.6.2" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/env-paths": { + "version": "2.2.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/err-code": { + "version": "2.0.3", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/fastest-levenshtein": { + "version": "1.0.12", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/fs-minipass": { + "version": "2.1.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/fs.realpath": { + "version": "1.0.0", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/function-bind": { + "version": "1.1.1", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/gauge": { + "version": "4.0.4", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "aproba": "^1.0.3 || ^2.0.0", + "color-support": "^1.1.3", + "console-control-strings": "^1.1.0", + "has-unicode": "^2.0.1", + "signal-exit": "^3.0.7", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1", + "wide-align": "^1.1.5" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/glob": { + "version": "8.0.3", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^5.0.1", + "once": "^1.3.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/graceful-fs": { + "version": "4.2.10", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/has": { + "version": "1.0.3", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/has-flag": { + "version": "4.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/has-unicode": { + "version": "2.0.1", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/hosted-git-info": { + "version": "5.2.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "lru-cache": "^7.5.1" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/http-cache-semantics": { + "version": "4.1.1", + "dev": true, + "inBundle": true, + "license": "BSD-2-Clause" + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/http-proxy-agent": { + "version": "5.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "@tootallnate/once": "2", + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/https-proxy-agent": { + "version": "5.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/humanize-ms": { + "version": "1.2.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "ms": "^2.0.0" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/iconv-lite": { + "version": "0.6.3", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/ignore-walk": { + "version": "5.0.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "minimatch": "^5.0.1" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/imurmurhash": { + "version": "0.1.4", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/indent-string": { + "version": "4.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/infer-owner": { + "version": "1.0.4", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/inflight": { + "version": "1.0.6", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/inherits": { + "version": "2.0.4", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/ini": { + "version": "3.0.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/init-package-json": { + "version": "3.0.2", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "npm-package-arg": "^9.0.1", + "promzard": "^0.3.0", + "read": "^1.0.7", + "read-package-json": "^5.0.0", + "semver": "^7.3.5", + "validate-npm-package-license": "^3.0.4", + "validate-npm-package-name": "^4.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/ip": { + "version": "2.0.0", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/ip-regex": { + "version": "4.3.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/is-cidr": { + "version": "4.0.2", + "dev": true, + "inBundle": true, + "license": "BSD-2-Clause", + "dependencies": { + "cidr-regex": "^3.1.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/is-core-module": { + "version": "2.10.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "has": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/is-lambda": { + "version": "1.0.1", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/isexe": { + "version": "2.0.0", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/json-stringify-nice": { + "version": "1.1.4", + "dev": true, + "inBundle": true, + "license": "ISC", + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/jsonparse": { + "version": "1.3.1", + "dev": true, + "engines": [ + "node >= 0.2.0" + ], + "inBundle": true, + "license": "MIT" + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/just-diff": { + "version": "5.1.1", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/just-diff-apply": { + "version": "5.4.1", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/libnpmaccess": { + "version": "6.0.4", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "aproba": "^2.0.0", + "minipass": "^3.1.1", + "npm-package-arg": "^9.0.1", + "npm-registry-fetch": "^13.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/libnpmdiff": { + "version": "4.0.5", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/disparity-colors": "^2.0.0", + "@npmcli/installed-package-contents": "^1.0.7", + "binary-extensions": "^2.2.0", + "diff": "^5.1.0", + "minimatch": "^5.0.1", + "npm-package-arg": "^9.0.1", + "pacote": "^13.6.1", + "tar": "^6.1.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/libnpmexec": { + "version": "4.0.14", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/arborist": "^5.6.3", + "@npmcli/ci-detect": "^2.0.0", + "@npmcli/fs": "^2.1.1", + "@npmcli/run-script": "^4.2.0", + "chalk": "^4.1.0", + "mkdirp-infer-owner": "^2.0.0", + "npm-package-arg": "^9.0.1", + "npmlog": "^6.0.2", + "pacote": "^13.6.1", + "proc-log": "^2.0.0", + "read": "^1.0.7", + "read-package-json-fast": "^2.0.2", + "semver": "^7.3.7", + "walk-up-path": "^1.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/libnpmfund": { + "version": "3.0.5", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/arborist": "^5.6.3" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/libnpmhook": { + "version": "8.0.4", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "aproba": "^2.0.0", + "npm-registry-fetch": "^13.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/libnpmorg": { + "version": "4.0.4", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "aproba": "^2.0.0", + "npm-registry-fetch": "^13.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/libnpmpack": { + "version": "4.1.3", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/run-script": "^4.1.3", + "npm-package-arg": "^9.0.1", + "pacote": "^13.6.1" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/libnpmpublish": { + "version": "6.0.5", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "normalize-package-data": "^4.0.0", + "npm-package-arg": "^9.0.1", + "npm-registry-fetch": "^13.0.0", + "semver": "^7.3.7", + "ssri": "^9.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/libnpmsearch": { + "version": "5.0.4", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "npm-registry-fetch": "^13.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/libnpmteam": { + "version": "4.0.4", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "aproba": "^2.0.0", + "npm-registry-fetch": "^13.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/libnpmversion": { + "version": "3.0.7", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/git": "^3.0.0", + "@npmcli/run-script": "^4.1.3", + "json-parse-even-better-errors": "^2.3.1", + "proc-log": "^2.0.0", + "semver": "^7.3.7" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/lru-cache": { + "version": "7.13.2", + "dev": true, + "inBundle": true, + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/make-fetch-happen": { + "version": "10.2.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "agentkeepalive": "^4.2.1", + "cacache": "^16.1.0", + "http-cache-semantics": "^4.1.0", + "http-proxy-agent": "^5.0.0", + "https-proxy-agent": "^5.0.0", + "is-lambda": "^1.0.1", + "lru-cache": "^7.7.1", + "minipass": "^3.1.6", + "minipass-collect": "^1.0.2", + "minipass-fetch": "^2.0.3", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "negotiator": "^0.6.3", + "promise-retry": "^2.0.1", + "socks-proxy-agent": "^7.0.0", + "ssri": "^9.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/minimatch": { + "version": "5.1.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/minipass": { + "version": "3.3.4", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/minipass-collect": { + "version": "1.0.2", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/minipass-fetch": { + "version": "2.1.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "minipass": "^3.1.6", + "minipass-sized": "^1.0.3", + "minizlib": "^2.1.2" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + }, + "optionalDependencies": { + "encoding": "^0.1.13" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/minipass-flush": { + "version": "1.0.5", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/minipass-json-stream": { + "version": "1.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "jsonparse": "^1.3.1", + "minipass": "^3.0.0" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/minipass-pipeline": { + "version": "1.2.4", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/minipass-sized": { + "version": "1.0.3", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/minizlib": { + "version": "2.1.2", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/mkdirp": { + "version": "1.0.4", + "dev": true, + "inBundle": true, + "license": "MIT", + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/mkdirp-infer-owner": { + "version": "2.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "chownr": "^2.0.0", + "infer-owner": "^1.0.4", + "mkdirp": "^1.0.3" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/ms": { + "version": "2.1.3", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/mute-stream": { + "version": "0.0.8", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/negotiator": { + "version": "0.6.3", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/node-gyp": { + "version": "9.1.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "env-paths": "^2.2.0", + "glob": "^7.1.4", + "graceful-fs": "^4.2.6", + "make-fetch-happen": "^10.0.3", + "nopt": "^5.0.0", + "npmlog": "^6.0.0", + "rimraf": "^3.0.2", + "semver": "^7.3.5", + "tar": "^6.1.2", + "which": "^2.0.2" + }, + "bin": { + "node-gyp": "bin/node-gyp.js" + }, + "engines": { + "node": "^12.22 || ^14.13 || >=16" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/node-gyp/node_modules/brace-expansion": { + "version": "1.1.11", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/node-gyp/node_modules/glob": { + "version": "7.2.3", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/node-gyp/node_modules/minimatch": { + "version": "3.1.2", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/node-gyp/node_modules/nopt": { + "version": "5.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "abbrev": "1" + }, + "bin": { + "nopt": "bin/nopt.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/nopt": { + "version": "6.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "abbrev": "^1.0.0" + }, + "bin": { + "nopt": "bin/nopt.js" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/normalize-package-data": { + "version": "4.0.1", + "dev": true, + "inBundle": true, + "license": "BSD-2-Clause", + "dependencies": { + "hosted-git-info": "^5.0.0", + "is-core-module": "^2.8.1", + "semver": "^7.3.5", + "validate-npm-package-license": "^3.0.4" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/npm-audit-report": { + "version": "3.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "chalk": "^4.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/npm-bundled": { + "version": "2.0.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "npm-normalize-package-bin": "^2.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/npm-bundled/node_modules/npm-normalize-package-bin": { + "version": "2.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/npm-install-checks": { + "version": "5.0.0", + "dev": true, + "inBundle": true, + "license": "BSD-2-Clause", + "dependencies": { + "semver": "^7.1.1" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/npm-normalize-package-bin": { + "version": "1.0.1", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/npm-package-arg": { + "version": "9.1.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "hosted-git-info": "^5.0.0", + "proc-log": "^2.0.1", + "semver": "^7.3.5", + "validate-npm-package-name": "^4.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/npm-packlist": { + "version": "5.1.3", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "glob": "^8.0.1", + "ignore-walk": "^5.0.1", + "npm-bundled": "^2.0.0", + "npm-normalize-package-bin": "^2.0.0" + }, + "bin": { + "npm-packlist": "bin/index.js" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/npm-packlist/node_modules/npm-normalize-package-bin": { + "version": "2.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/npm-pick-manifest": { + "version": "7.0.2", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "npm-install-checks": "^5.0.0", + "npm-normalize-package-bin": "^2.0.0", + "npm-package-arg": "^9.0.0", + "semver": "^7.3.5" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/npm-pick-manifest/node_modules/npm-normalize-package-bin": { + "version": "2.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/npm-profile": { + "version": "6.2.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "npm-registry-fetch": "^13.0.1", + "proc-log": "^2.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/npm-registry-fetch": { + "version": "13.3.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "make-fetch-happen": "^10.0.6", + "minipass": "^3.1.6", + "minipass-fetch": "^2.0.3", + "minipass-json-stream": "^1.0.1", + "minizlib": "^2.1.2", + "npm-package-arg": "^9.0.1", + "proc-log": "^2.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/npm-user-validate": { + "version": "1.0.1", + "dev": true, + "inBundle": true, + "license": "BSD-2-Clause" + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/npmlog": { + "version": "6.0.2", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "are-we-there-yet": "^3.0.0", + "console-control-strings": "^1.1.0", + "gauge": "^4.0.3", + "set-blocking": "^2.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/once": { + "version": "1.4.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/opener": { + "version": "1.5.2", + "dev": true, + "inBundle": true, + "license": "(WTFPL OR MIT)", + "bin": { + "opener": "bin/opener-bin.js" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/p-map": { + "version": "4.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "aggregate-error": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/pacote": { + "version": "13.6.2", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/git": "^3.0.0", + "@npmcli/installed-package-contents": "^1.0.7", + "@npmcli/promise-spawn": "^3.0.0", + "@npmcli/run-script": "^4.1.0", + "cacache": "^16.0.0", + "chownr": "^2.0.0", + "fs-minipass": "^2.1.0", + "infer-owner": "^1.0.4", + "minipass": "^3.1.6", + "mkdirp": "^1.0.4", + "npm-package-arg": "^9.0.0", + "npm-packlist": "^5.1.0", + "npm-pick-manifest": "^7.0.0", + "npm-registry-fetch": "^13.0.1", + "proc-log": "^2.0.0", + "promise-retry": "^2.0.1", + "read-package-json": "^5.0.0", + "read-package-json-fast": "^2.0.3", + "rimraf": "^3.0.2", + "ssri": "^9.0.0", + "tar": "^6.1.11" + }, + "bin": { + "pacote": "lib/bin.js" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/parse-conflict-json": { + "version": "2.0.2", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "json-parse-even-better-errors": "^2.3.1", + "just-diff": "^5.0.1", + "just-diff-apply": "^5.2.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/path-is-absolute": { + "version": "1.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/postcss-selector-parser": { + "version": "6.0.10", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/proc-log": { + "version": "2.0.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/promise-all-reject-late": { + "version": "1.0.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/promise-call-limit": { + "version": "1.0.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/promise-inflight": { + "version": "1.0.1", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/promise-retry": { + "version": "2.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "err-code": "^2.0.2", + "retry": "^0.12.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/promzard": { + "version": "0.3.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "read": "1" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/qrcode-terminal": { + "version": "0.12.0", + "dev": true, + "inBundle": true, + "bin": { + "qrcode-terminal": "bin/qrcode-terminal.js" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/read": { + "version": "1.0.7", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "mute-stream": "~0.0.4" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/read-cmd-shim": { + "version": "3.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/read-package-json": { + "version": "5.0.2", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "glob": "^8.0.1", + "json-parse-even-better-errors": "^2.3.1", + "normalize-package-data": "^4.0.0", + "npm-normalize-package-bin": "^2.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/read-package-json-fast": { + "version": "2.0.3", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "json-parse-even-better-errors": "^2.3.0", + "npm-normalize-package-bin": "^1.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/read-package-json/node_modules/npm-normalize-package-bin": { + "version": "2.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/readable-stream": { + "version": "3.6.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/readdir-scoped-modules": { + "version": "1.1.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "debuglog": "^1.0.1", + "dezalgo": "^1.0.0", + "graceful-fs": "^4.1.2", + "once": "^1.3.0" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/retry": { + "version": "0.12.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/rimraf": { + "version": "3.0.2", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/rimraf/node_modules/brace-expansion": { + "version": "1.1.11", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/rimraf/node_modules/glob": { + "version": "7.2.3", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/rimraf/node_modules/minimatch": { + "version": "3.1.2", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/safe-buffer": { + "version": "5.2.1", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "inBundle": true, + "license": "MIT" + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/safer-buffer": { + "version": "2.1.2", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/semver": { + "version": "7.3.7", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/semver/node_modules/lru-cache": { + "version": "6.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/set-blocking": { + "version": "2.0.0", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/signal-exit": { + "version": "3.0.7", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/smart-buffer": { + "version": "4.2.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">= 6.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/socks": { + "version": "2.7.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "ip": "^2.0.0", + "smart-buffer": "^4.2.0" + }, + "engines": { + "node": ">= 10.13.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/socks-proxy-agent": { + "version": "7.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "agent-base": "^6.0.2", + "debug": "^4.3.3", + "socks": "^2.6.2" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/spdx-correct": { + "version": "3.1.1", + "dev": true, + "inBundle": true, + "license": "Apache-2.0", + "dependencies": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/spdx-exceptions": { + "version": "2.3.0", + "dev": true, + "inBundle": true, + "license": "CC-BY-3.0" + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/spdx-expression-parse": { + "version": "3.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/spdx-license-ids": { + "version": "3.0.11", + "dev": true, + "inBundle": true, + "license": "CC0-1.0" + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/ssri": { + "version": "9.0.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "minipass": "^3.1.1" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/string_decoder": { + "version": "1.3.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/string-width": { + "version": "4.2.3", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/strip-ansi": { + "version": "6.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/supports-color": { + "version": "7.2.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/tar": { + "version": "6.1.11", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "minipass": "^3.0.0", + "minizlib": "^2.1.1", + "mkdirp": "^1.0.3", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/text-table": { + "version": "0.2.0", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/tiny-relative-date": { + "version": "1.3.0", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/treeverse": { + "version": "2.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/unique-filename": { + "version": "2.0.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "unique-slug": "^3.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/unique-slug": { + "version": "3.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "imurmurhash": "^0.1.4" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/util-deprecate": { + "version": "1.0.2", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/validate-npm-package-license": { + "version": "3.0.4", + "dev": true, + "inBundle": true, + "license": "Apache-2.0", + "dependencies": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/validate-npm-package-name": { + "version": "4.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "builtins": "^5.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/walk-up-path": { + "version": "1.0.0", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/wcwidth": { + "version": "1.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "defaults": "^1.0.3" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/which": { + "version": "2.0.2", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/wide-align": { + "version": "1.1.5", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "string-width": "^1.0.2 || 2 || 3 || 4" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/wrappy": { + "version": "1.0.2", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/write-file-atomic": { + "version": "4.0.2", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.7" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/npm/node_modules/yallist": { + "version": "4.0.0", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/scratch-semantic-release-config/node_modules/p-filter": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-filter/-/p-filter-2.1.0.tgz", + "integrity": "sha512-ZBxxZ5sL2HghephhpGAQdoskxplTwr7ICaehZwLIlfL6acuVgZPm8yBNuRAFBGEqtD/hmUeq9eqLg2ys9Xr/yw==", + "dev": true, + "dependencies": { + "p-map": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/p-map": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz", + "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/temp-dir": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/temp-dir/-/temp-dir-2.0.0.tgz", + "integrity": "sha512-aoBAniQmmwtcKp/7BzsH8Cxzv8OL736p7v1ihGb5e9DJ9kTwGWHrQrVB5+lfVDzfGrdRzXch+ig7LHaY1JTOrg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/tempy": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/tempy/-/tempy-1.0.1.tgz", + "integrity": "sha512-biM9brNqxSc04Ee71hzFbryD11nX7VPhQQY32AdDmjFvodsRFz/3ufeoTZ6uYkRFfGo188tENcASNs3vTdsM0w==", + "dev": true, + "dependencies": { + "del": "^6.0.0", + "is-stream": "^2.0.0", + "temp-dir": "^2.0.0", + "type-fest": "^0.16.0", + "unique-string": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/type-fest": { + "version": "0.16.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.16.0.tgz", + "integrity": "sha512-eaBzG6MxNzEn9kiwvtre90cXaNLkmadMWa1zQMs3XORCXNbsH/OewwbxC5ia9dCxIxnTAsSxXJaa/p5y8DlvJg==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/unique-string": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz", + "integrity": "sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==", + "dev": true, + "dependencies": { + "crypto-random-string": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/scratch-semantic-release-config/node_modules/url-join": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/url-join/-/url-join-4.0.1.tgz", + "integrity": "sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA==", + "dev": true + }, + "node_modules/select-hose": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", + "integrity": "sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg==", + "dev": true + }, + "node_modules/selfsigned": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-2.4.1.tgz", + "integrity": "sha512-th5B4L2U+eGLq1TVh7zNRGBapioSORUeymIydxgFpwww9d2qyKvtuPU2jJuHvYAwwqi2Y596QBL3eEqcPEYL8Q==", + "dev": true, + "dependencies": { + "@types/node-forge": "^1.3.0", + "node-forge": "^1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/semantic-release": { + "version": "22.0.12", + "resolved": "https://registry.npmjs.org/semantic-release/-/semantic-release-22.0.12.tgz", + "integrity": "sha512-0mhiCR/4sZb00RVFJIUlMuiBkW3NMpVIW2Gse7noqEMoFGkvfPPAImEQbkBV8xga4KOPP4FdTRYuLLy32R1fPw==", + "dev": true, + "dependencies": { + "@semantic-release/commit-analyzer": "^11.0.0", + "@semantic-release/error": "^4.0.0", + "@semantic-release/github": "^9.0.0", + "@semantic-release/npm": "^11.0.0", + "@semantic-release/release-notes-generator": "^12.0.0", + "aggregate-error": "^5.0.0", + "cosmiconfig": "^8.0.0", + "debug": "^4.0.0", + "env-ci": "^10.0.0", + "execa": "^8.0.0", + "figures": "^6.0.0", + "find-versions": "^5.1.0", + "get-stream": "^6.0.0", + "git-log-parser": "^1.2.0", + "hook-std": "^3.0.0", + "hosted-git-info": "^7.0.0", + "import-from-esm": "^1.3.1", + "lodash-es": "^4.17.21", + "marked": "^9.0.0", + "marked-terminal": "^6.0.0", + "micromatch": "^4.0.2", + "p-each-series": "^3.0.0", + "p-reduce": "^3.0.0", + "read-pkg-up": "^11.0.0", + "resolve-from": "^5.0.0", + "semver": "^7.3.2", + "semver-diff": "^4.0.0", + "signale": "^1.2.1", + "yargs": "^17.5.1" + }, + "bin": { + "semantic-release": "bin/semantic-release.js" + }, + "engines": { + "node": "^18.17 || >=20.6.1" + } + }, + "node_modules/semantic-release/node_modules/execa": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", + "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^8.0.1", + "human-signals": "^5.0.0", + "is-stream": "^3.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^5.1.0", + "onetime": "^6.0.0", + "signal-exit": "^4.1.0", + "strip-final-newline": "^3.0.0" + }, + "engines": { + "node": ">=16.17" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/semantic-release/node_modules/execa/node_modules/get-stream": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", + "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==", + "dev": true, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/semantic-release/node_modules/figures": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-6.1.0.tgz", + "integrity": "sha512-d+l3qxjSesT4V7v2fh+QnmFnUWv9lSpjarhShNTgBOfA0ttejbQUAlHLitbjkoRiDulW0OPoQPYIGhIC8ohejg==", + "dev": true, + "dependencies": { + "is-unicode-supported": "^2.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/semantic-release/node_modules/hosted-git-info": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-7.0.2.tgz", + "integrity": "sha512-puUZAUKT5m8Zzvs72XWy3HtvVbTWljRE66cP60bxJzAqf2DgICo7lYTY2IHUmLnNpjYvw5bvmoHvPc0QO2a62w==", + "dev": true, + "dependencies": { + "lru-cache": "^10.0.1" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/semantic-release/node_modules/human-signals": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz", + "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==", + "dev": true, + "engines": { + "node": ">=16.17.0" + } + }, + "node_modules/semantic-release/node_modules/is-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", + "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", + "dev": true, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/semantic-release/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true + }, + "node_modules/semantic-release/node_modules/mimic-fn": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", + "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/semantic-release/node_modules/normalize-package-data": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-6.0.2.tgz", + "integrity": "sha512-V6gygoYb/5EmNI+MEGrWkC+e6+Rr7mTmfHrxDbLzxQogBkgzo76rkok0Am6thgSF7Mv2nLOajAJj5vDJZEFn7g==", + "dev": true, + "dependencies": { + "hosted-git-info": "^7.0.0", + "semver": "^7.3.5", + "validate-npm-package-license": "^3.0.4" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/semantic-release/node_modules/npm-run-path": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.3.0.tgz", + "integrity": "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==", + "dev": true, + "dependencies": { + "path-key": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/semantic-release/node_modules/onetime": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", + "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", + "dev": true, + "dependencies": { + "mimic-fn": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/semantic-release/node_modules/parse-json": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-8.1.0.tgz", + "integrity": "sha512-rum1bPifK5SSar35Z6EKZuYPJx85pkNaFrxBK3mwdfSJ1/WKbYrjoW/zTPSjRRamfmVX1ACBIdFAO0VRErW/EA==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.22.13", + "index-to-position": "^0.1.2", + "type-fest": "^4.7.1" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/semantic-release/node_modules/path-key": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", + "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/semantic-release/node_modules/read-pkg": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-9.0.1.tgz", + "integrity": "sha512-9viLL4/n1BJUCT1NXVTdS1jtm80yDEgR5T4yCelII49Mbj0v1rZdKqj7zCiYdbB0CuCgdrvHcNogAKTFPBocFA==", + "dev": true, + "dependencies": { + "@types/normalize-package-data": "^2.4.3", + "normalize-package-data": "^6.0.0", + "parse-json": "^8.0.0", + "type-fest": "^4.6.0", + "unicorn-magic": "^0.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/semantic-release/node_modules/read-pkg-up": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-11.0.0.tgz", + "integrity": "sha512-LOVbvF1Q0SZdjClSefZ0Nz5z8u+tIE7mV5NibzmE9VYmDe9CaBbAVtz1veOSZbofrdsilxuDAYnFenukZVp8/Q==", + "deprecated": "Renamed to read-package-up", + "dev": true, + "dependencies": { + "find-up-simple": "^1.0.0", + "read-pkg": "^9.0.0", + "type-fest": "^4.6.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/semantic-release/node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/semantic-release/node_modules/strip-final-newline": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", + "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/semantic-release/node_modules/type-fest": { + "version": "4.26.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.26.1.tgz", + "integrity": "sha512-yOGpmOAL7CkKe/91I5O3gPICmJNLJ1G4zFYVAsRHg7M64biSnPtRj0WNQt++bRkjYOqjWXrhnUw1utzmVErAdg==", + "dev": true, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/semver-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-4.0.0.tgz", + "integrity": "sha512-0Ju4+6A8iOnpL/Thra7dZsSlOHYAHIeMxfhWQRI1/VLcT3WDBZKKtQt/QkBOsiIN9ZpuvHE6cGZ0x4glCMmfiA==", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^7.3.5" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/semver-regex": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/semver-regex/-/semver-regex-4.0.5.tgz", + "integrity": "sha512-hunMQrEy1T6Jr2uEVjrAIqjwWcQTgOAcIM52C8MY1EZSD3DDNft04XzvYKPqjED65bNVVko0YI38nYeEHCX3yw==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/send": { + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", + "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", + "dev": true, + "dependencies": { + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "2.4.1", + "range-parser": "~1.2.1", + "statuses": "2.0.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/send/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/send/node_modules/debug/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + }, + "node_modules/send/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + }, + "node_modules/serialize-javascript": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.1.tgz", + "integrity": "sha512-owoXEFjWRllis8/M1Q+Cw5k8ZH40e3zhp/ovX+Xr/vi1qj6QesbyXXViFbpNvWvPNAD62SutwEXavefrLJWj7w==", + "dev": true, + "dependencies": { + "randombytes": "^2.1.0" + } + }, + "node_modules/serve-index": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz", + "integrity": "sha512-pXHfKNP4qujrtteMrSBb0rc8HJ9Ms/GrXwcUtUtD5s4ewDJI8bT3Cz2zTVRMKtri49pLx2e0Ya8ziP5Ya2pZZw==", + "dev": true, + "dependencies": { + "accepts": "~1.3.4", + "batch": "0.6.1", + "debug": "2.6.9", + "escape-html": "~1.0.3", + "http-errors": "~1.6.2", + "mime-types": "~2.1.17", + "parseurl": "~1.3.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/serve-index/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/serve-index/node_modules/depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/serve-index/node_modules/http-errors": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", + "integrity": "sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A==", + "dev": true, + "dependencies": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.0", + "statuses": ">= 1.4.0 < 2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/serve-index/node_modules/inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==", + "dev": true + }, + "node_modules/serve-index/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + }, + "node_modules/serve-index/node_modules/setprototypeof": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", + "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==", + "dev": true + }, + "node_modules/serve-index/node_modules/statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/serve-static": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", + "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", + "dev": true, + "dependencies": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.18.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/set-function-length": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.1.1.tgz", + "integrity": "sha512-VoaqjbBJKiWtg4yRcKBQ7g7wnGnLV3M8oLvVWwOk2PdYY6PEFegR1vezXR0tw6fZGF9csVakIRjrJiy2veSBFQ==", + "dev": true, + "dependencies": { + "define-data-property": "^1.1.1", + "get-intrinsic": "^1.2.1", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", + "dev": true + }, + "node_modules/shallow-clone": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", + "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", + "dev": true, + "dependencies": { + "kind-of": "^6.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/shell-quote": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.1.tgz", + "integrity": "sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true + }, + "node_modules/signale": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/signale/-/signale-1.4.0.tgz", + "integrity": "sha512-iuh+gPf28RkltuJC7W5MRi6XAjTDCAPC/prJUpQoG4vIP3MJZ+GTydVnodXA7pwvTKb2cA0m9OFZW/cdWy/I/w==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^2.3.2", + "figures": "^2.0.0", + "pkg-conf": "^2.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/signale/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/signale/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/signale/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/signale/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true, + "license": "MIT" + }, + "node_modules/signale/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/signale/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/skin-tone": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/skin-tone/-/skin-tone-2.0.0.tgz", + "integrity": "sha512-kUMbT1oBJCpgrnKoSr0o6wPtvRWT9W9UKvGLwfJYO2WuahZRHOpEyL1ckyMGgMWh0UdpmaoFqKKD29WTomNEGA==", + "dev": true, + "dependencies": { + "unicode-emoji-modifier-base": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/slash": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-5.1.0.tgz", + "integrity": "sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==", + "dev": true, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/slice-ansi": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-1.0.0.tgz", + "integrity": "sha512-POqxBK6Lb3q6s047D/XsDVNPnF9Dl8JSaqe9h9lURl0OdNqy/ujDrOiIHtsqXMGbWWTIomRzAMaTyawAU//Reg==", + "dev": true, + "dependencies": { + "is-fullwidth-code-point": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/slice-ansi/node_modules/is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/sockjs": { + "version": "0.3.24", + "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.24.tgz", + "integrity": "sha512-GJgLTZ7vYb/JtPSSZ10hsOYIvEYsjbNU+zPdIHcUaWVNUEPivzxku31865sSSud0Da0W4lEeOPlmw93zLQchuQ==", + "dev": true, + "dependencies": { + "faye-websocket": "^0.11.3", + "uuid": "^8.3.2", + "websocket-driver": "^0.7.4" + } + }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-js": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", + "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-loader": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/source-map-loader/-/source-map-loader-4.0.1.tgz", + "integrity": "sha512-oqXpzDIByKONVY8g1NUPOTQhe0UTU5bWUl32GSkqK2LjJj0HmwTMVKxcUip0RgAYhY1mqgOxjbQM48a0mmeNfA==", + "dev": true, + "dependencies": { + "abab": "^2.0.6", + "iconv-lite": "^0.6.3", + "source-map-js": "^1.0.2" + }, + "engines": { + "node": ">= 14.15.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.72.1" + } + }, + "node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "dev": true, + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/spawn-error-forwarder": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/spawn-error-forwarder/-/spawn-error-forwarder-1.0.0.tgz", + "integrity": "sha512-gRjMgK5uFjbCvdibeGJuy3I5OYz6VLoVdsOJdA6wV0WlfQVLFueoqMxwwYD9RODdgb6oUIvlRlsyFSiQkMKu0g==", + "dev": true, + "license": "MIT" + }, + "node_modules/spdx-correct": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", + "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", + "dev": true, + "dependencies": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-exceptions": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz", + "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==", + "dev": true + }, + "node_modules/spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "dev": true, + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-license-ids": { + "version": "3.0.17", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.17.tgz", + "integrity": "sha512-sh8PWc/ftMqAAdFiBu6Fy6JUOYjqDJBJvIhpfDMyHrr0Rbp5liZqd4TjtQ/RgfLjKFZb+LMx5hpml5qOWy0qvg==", + "dev": true + }, + "node_modules/spdy": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.2.tgz", + "integrity": "sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA==", + "dev": true, + "dependencies": { + "debug": "^4.1.0", + "handle-thing": "^2.0.0", + "http-deceiver": "^1.2.7", + "select-hose": "^2.0.0", + "spdy-transport": "^3.0.0" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/spdy-transport": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/spdy-transport/-/spdy-transport-3.0.0.tgz", + "integrity": "sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==", + "dev": true, + "dependencies": { + "debug": "^4.1.0", + "detect-node": "^2.0.4", + "hpack.js": "^2.1.6", + "obuf": "^1.1.2", + "readable-stream": "^3.0.6", + "wbuf": "^1.7.3" + } + }, + "node_modules/split": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz", + "integrity": "sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==", + "dev": true, + "dependencies": { + "through": "2" + }, + "engines": { + "node": "*" + } + }, + "node_modules/split2": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/split2/-/split2-3.2.2.tgz", + "integrity": "sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg==", + "dev": true, + "dependencies": { + "readable-stream": "^3.0.0" + } + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "dev": true + }, + "node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/stream-combiner2": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/stream-combiner2/-/stream-combiner2-1.1.1.tgz", + "integrity": "sha512-3PnJbYgS56AeWgtKF5jtJRT6uFJe56Z0Hc5Ngg/6sI6rIt8iiMBTa9cvdyFfpMQjaVHr8dusbNeFGIIonxOvKw==", + "dev": true, + "license": "MIT", + "dependencies": { + "duplexer2": "~0.1.0", + "readable-stream": "^2.0.2" + } + }, + "node_modules/stream-combiner2/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dev": true, + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/stream-combiner2/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true, + "license": "MIT" + }, + "node_modules/stream-combiner2/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/strip-indent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", + "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", + "dev": true, + "dependencies": { + "min-indent": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/supports-hyperlinks": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-3.1.0.tgz", + "integrity": "sha512-2rn0BZ+/f7puLOHZm1HOJfwBggfaHXUpPUSSG/SWM4TWp5KCfmNYwnC3hruy2rZlMnmWZ+QAGpZfchu3f3695A==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0", + "supports-color": "^7.0.0" + }, + "engines": { + "node": ">=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/supports-hyperlinks/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/symbol-tree": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", + "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==" + }, + "node_modules/table": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/table/-/table-4.0.2.tgz", + "integrity": "sha512-UUkEAPdSGxtRpiV9ozJ5cMTtYiqz7Ni1OGqLXRCynrvzdtR1p+cfOWe2RJLwvUG8hNanaSRjecIqwOjqeatDsA==", + "dev": true, + "dependencies": { + "ajv": "^5.2.3", + "ajv-keywords": "^2.1.0", + "chalk": "^2.1.0", + "lodash": "^4.17.4", + "slice-ansi": "1.0.0", + "string-width": "^2.1.1" + } + }, + "node_modules/table/node_modules/ajv": { + "version": "5.5.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz", + "integrity": "sha512-Ajr4IcMXq/2QmMkEmSvxqfLN5zGmJ92gHXAeOXq1OekoH2rfDNsgdDoL2f7QaRCy7G/E6TpxBVdRuNraMztGHw==", + "dev": true, + "dependencies": { + "co": "^4.6.0", + "fast-deep-equal": "^1.0.0", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.3.0" + } + }, + "node_modules/table/node_modules/ajv-keywords": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-2.1.1.tgz", + "integrity": "sha512-ZFztHzVRdGLAzJmpUT9LNFLe1YiVOEylcaNpEutM26PVTCtOD919IMfD01CgbRouB42Dd9atjx1HseC15DgOZA==", + "dev": true, + "peerDependencies": { + "ajv": "^5.0.0" + } + }, + "node_modules/table/node_modules/ansi-regex": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz", + "integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/table/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/table/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/table/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/table/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "node_modules/table/node_modules/fast-deep-equal": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz", + "integrity": "sha512-fueX787WZKCV0Is4/T2cyAdM4+x1S3MXXOAhavE1ys/W42SHAPacLTQhucja22QBYrfGw50M2sRiXPtTGv9Ymw==", + "dev": true + }, + "node_modules/table/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/table/node_modules/is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/table/node_modules/json-schema-traverse": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz", + "integrity": "sha512-4JD/Ivzg7PoW8NzdrBSr3UFwC9mHgvI7Z6z3QGBsSHgKaRTUDmyZAAKJo2UbG1kUVfS9WS8bi36N49U1xw43DA==", + "dev": true + }, + "node_modules/table/node_modules/string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "dependencies": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/table/node_modules/strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==", + "dev": true, + "dependencies": { + "ansi-regex": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/table/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/tapable": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", + "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/temp-dir": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/temp-dir/-/temp-dir-3.0.0.tgz", + "integrity": "sha512-nHc6S/bwIilKHNRgK/3jlhDoIHcp45YgyiwcAk46Tr0LfEqGBVpmiAyuiuxeVE44m3mXnEeVhaipLOEWmH+Njw==", + "dev": true, + "engines": { + "node": ">=14.16" + } + }, + "node_modules/tempy": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/tempy/-/tempy-3.1.0.tgz", + "integrity": "sha512-7jDLIdD2Zp0bDe5r3D2qtkd1QOCacylBuL7oa4udvN6v2pqr4+LcCr67C8DR1zkpaZ8XosF5m1yQSabKAW6f2g==", + "dev": true, + "dependencies": { + "is-stream": "^3.0.0", + "temp-dir": "^3.0.0", + "type-fest": "^2.12.2", + "unique-string": "^3.0.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/tempy/node_modules/is-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", + "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", + "dev": true, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/tempy/node_modules/type-fest": { + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz", + "integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==", + "dev": true, + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/terser": { + "version": "5.26.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.26.0.tgz", + "integrity": "sha512-dytTGoE2oHgbNV9nTzgBEPaqAWvcJNl66VZ0BkJqlvp71IjO8CxdBx/ykCNb47cLnCmCvRZ6ZR0tLkqvZCdVBQ==", + "dev": true, + "dependencies": { + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.8.2", + "commander": "^2.20.0", + "source-map-support": "~0.5.20" + }, + "bin": { + "terser": "bin/terser" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/terser-webpack-plugin": { + "version": "5.3.9", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.9.tgz", + "integrity": "sha512-ZuXsqE07EcggTWQjXUj+Aot/OMcD0bMKGgF63f7UxYcu5/AJF53aIpK1YoP5xR9l6s/Hy2b+t1AM0bLNPRuhwA==", + "dev": true, + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.17", + "jest-worker": "^27.4.5", + "schema-utils": "^3.1.1", + "serialize-javascript": "^6.0.1", + "terser": "^5.16.8" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.1.0" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "uglify-js": { + "optional": true + } + } + }, + "node_modules/text-extensions": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/text-extensions/-/text-extensions-1.9.0.tgz", + "integrity": "sha512-wiBrwC1EhBelW12Zy26JeOUkQ5mRu+5o8rpsJk5+2t+Y5vE7e842qtZDQ2g1NpX/29HdyFeJ4nSIhI47ENSxlQ==", + "dev": true, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", + "dev": true + }, + "node_modules/through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", + "dev": true + }, + "node_modules/through2": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/through2/-/through2-4.0.2.tgz", + "integrity": "sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==", + "dev": true, + "dependencies": { + "readable-stream": "3" + } + }, + "node_modules/thunky": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz", + "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==", + "dev": true + }, + "node_modules/tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "dev": true, + "dependencies": { + "os-tmpdir": "~1.0.2" + }, + "engines": { + "node": ">=0.6.0" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "dev": true, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/tough-cookie": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.4.tgz", + "integrity": "sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==", + "dependencies": { + "psl": "^1.1.33", + "punycode": "^2.1.1", + "universalify": "^0.2.0", + "url-parse": "^1.5.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/tr46": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-5.0.0.tgz", + "integrity": "sha512-tk2G5R2KRwBd+ZN0zaEXpmzdKyOYksXwywulIX95MBODjSzMIuQnQ3m8JxgbhnL1LeVo7lqQKsYa1O3Htl7K5g==", + "dependencies": { + "punycode": "^2.3.1" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/traverse": { + "version": "0.6.8", + "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.6.8.tgz", + "integrity": "sha512-aXJDbk6SnumuaZSANd21XAo15ucCDE38H4fkqiGsc3MhCK+wOlZvLP9cB/TvpHT0mOyWgC4Z8EwRlzqYSUzdsA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/trim-newlines": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.1.tgz", + "integrity": "sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ts-loader": { + "version": "9.5.1", + "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-9.5.1.tgz", + "integrity": "sha512-rNH3sK9kGZcH9dYzC7CewQm4NtxJTjSEVRJ2DyBZR7f8/wcta+iV44UPCXc5+nzDzivKtlzV6c9P4e+oFhDLYg==", + "dev": true, + "dependencies": { + "chalk": "^4.1.0", + "enhanced-resolve": "^5.0.0", + "micromatch": "^4.0.0", + "semver": "^7.3.4", + "source-map": "^0.7.4" + }, + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "typescript": "*", + "webpack": "^5.0.0" + } + }, + "node_modules/ts-loader/node_modules/source-map": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", + "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/ts-node": { + "version": "10.9.2", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", + "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", + "dev": true, + "dependencies": { + "@cspotcode/source-map-support": "^0.8.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "v8-compile-cache-lib": "^3.0.1", + "yn": "3.1.1" + }, + "bin": { + "ts-node": "dist/bin.js", + "ts-node-cwd": "dist/bin-cwd.js", + "ts-node-esm": "dist/bin-esm.js", + "ts-node-script": "dist/bin-script.js", + "ts-node-transpile-only": "dist/bin-transpile.js", + "ts-script": "dist/bin-script-deprecated.js" + }, + "peerDependencies": { + "@swc/core": ">=1.2.50", + "@swc/wasm": ">=1.2.50", + "@types/node": "*", + "typescript": ">=2.7" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "@swc/wasm": { + "optional": true + } + } + }, + "node_modules/type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==", + "dev": true, + "dependencies": { + "prelude-ls": "~1.1.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-fest": { + "version": "0.18.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.18.1.tgz", + "integrity": "sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "dev": true, + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==", + "dev": true + }, + "node_modules/typescript": { + "version": "5.6.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.3.tgz", + "integrity": "sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/uglify-js": { + "version": "3.19.3", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.19.3.tgz", + "integrity": "sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ==", + "dev": true, + "optional": true, + "bin": { + "uglifyjs": "bin/uglifyjs" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "dev": true + }, + "node_modules/unicode-emoji-modifier-base": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unicode-emoji-modifier-base/-/unicode-emoji-modifier-base-1.0.0.tgz", + "integrity": "sha512-yLSH4py7oFH3oG/9K+XWrz1pSi3dfUrWEnInbxMfArOfc1+33BlGPQtLsOYwvdMy11AwUBetYuaRxSPqgkq+8g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/unicorn-magic": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.1.0.tgz", + "integrity": "sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/unique-string": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-3.0.0.tgz", + "integrity": "sha512-VGXBUVwxKMBUznyffQweQABPRRW1vHZAbadFZud4pLFAqRGvv/96vafgjWFqzourzr8YonlQiPgH0YCJfawoGQ==", + "dev": true, + "dependencies": { + "crypto-random-string": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/universal-user-agent": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.1.tgz", + "integrity": "sha512-yCzhz6FN2wU1NiiQRogkTQszlQSlpWaw8SvVegAc+bDxbzHgh1vX8uIe8OYyMH6DwH+sdTJsgMl36+mSMdRJIQ==", + "dev": true + }, + "node_modules/universalify": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", + "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==", + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.0.13", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", + "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "escalade": "^3.1.1", + "picocolors": "^1.0.0" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/url-join": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/url-join/-/url-join-5.0.0.tgz", + "integrity": "sha512-n2huDr9h9yzd6exQVnH/jU5mr+Pfx08LRXXZhkLLetAMESRj+anQsTAh940iMrIetKAmry9coFuZQ2jY8/p3WA==", + "dev": true, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + } + }, + "node_modules/url-parse": { + "version": "1.5.10", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", + "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", + "dependencies": { + "querystringify": "^2.1.1", + "requires-port": "^1.0.0" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "dev": true + }, + "node_modules/utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", + "dev": true, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "dev": true, + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/v8-compile-cache-lib": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", + "dev": true + }, + "node_modules/validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "dependencies": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/w3c-xmlserializer": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-5.0.0.tgz", + "integrity": "sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==", + "dependencies": { + "xml-name-validator": "^5.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/watchpack": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz", + "integrity": "sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg==", + "dev": true, + "dependencies": { + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.1.2" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/wbuf": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/wbuf/-/wbuf-1.7.3.tgz", + "integrity": "sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==", + "dev": true, + "dependencies": { + "minimalistic-assert": "^1.0.0" + } + }, + "node_modules/webidl-conversions": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", + "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", + "engines": { + "node": ">=12" + } + }, + "node_modules/webpack": { + "version": "5.89.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.89.0.tgz", + "integrity": "sha512-qyfIC10pOr70V+jkmud8tMfajraGCZMBWJtrmuBymQKCrLTRejBI8STDp1MCyZu/QTdZSeacCQYpYNQVOzX5kw==", + "dev": true, + "dependencies": { + "@types/eslint-scope": "^3.7.3", + "@types/estree": "^1.0.0", + "@webassemblyjs/ast": "^1.11.5", + "@webassemblyjs/wasm-edit": "^1.11.5", + "@webassemblyjs/wasm-parser": "^1.11.5", + "acorn": "^8.7.1", + "acorn-import-assertions": "^1.9.0", + "browserslist": "^4.14.5", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^5.15.0", + "es-module-lexer": "^1.2.1", + "eslint-scope": "5.1.1", + "events": "^3.2.0", + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.2.9", + "json-parse-even-better-errors": "^2.3.1", + "loader-runner": "^4.2.0", + "mime-types": "^2.1.27", + "neo-async": "^2.6.2", + "schema-utils": "^3.2.0", + "tapable": "^2.1.1", + "terser-webpack-plugin": "^5.3.7", + "watchpack": "^2.4.0", + "webpack-sources": "^3.2.3" + }, + "bin": { + "webpack": "bin/webpack.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependenciesMeta": { + "webpack-cli": { + "optional": true + } + } + }, + "node_modules/webpack-cli": { + "version": "4.10.0", + "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-4.10.0.tgz", + "integrity": "sha512-NLhDfH/h4O6UOy+0LSso42xvYypClINuMNBVVzX4vX98TmTaTUxwRbXdhucbFMd2qLaCTcLq/PdYrvi8onw90w==", + "dev": true, + "dependencies": { + "@discoveryjs/json-ext": "^0.5.0", + "@webpack-cli/configtest": "^1.2.0", + "@webpack-cli/info": "^1.5.0", + "@webpack-cli/serve": "^1.7.0", + "colorette": "^2.0.14", + "commander": "^7.0.0", + "cross-spawn": "^7.0.3", + "fastest-levenshtein": "^1.0.12", + "import-local": "^3.0.2", + "interpret": "^2.2.0", + "rechoir": "^0.7.0", + "webpack-merge": "^5.7.3" + }, + "bin": { + "webpack-cli": "bin/cli.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "4.x.x || 5.x.x" + }, + "peerDependenciesMeta": { + "@webpack-cli/generators": { + "optional": true + }, + "@webpack-cli/migrate": { + "optional": true + }, + "webpack-bundle-analyzer": { + "optional": true + }, + "webpack-dev-server": { + "optional": true + } + } + }, + "node_modules/webpack-cli/node_modules/commander": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "dev": true, + "engines": { + "node": ">= 10" + } + }, + "node_modules/webpack-dev-middleware": { + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-5.3.3.tgz", + "integrity": "sha512-hj5CYrY0bZLB+eTO+x/j67Pkrquiy7kWepMHmUMoPsmcUaeEnQJqFzHJOyxgWlq746/wUuA64p9ta34Kyb01pA==", + "dev": true, + "dependencies": { + "colorette": "^2.0.10", + "memfs": "^3.4.3", + "mime-types": "^2.1.31", + "range-parser": "^1.2.1", + "schema-utils": "^4.0.0" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^4.0.0 || ^5.0.0" + } + }, + "node_modules/webpack-dev-middleware/node_modules/ajv": { + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", + "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/webpack-dev-middleware/node_modules/ajv-keywords": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.3" + }, + "peerDependencies": { + "ajv": "^8.8.2" + } + }, + "node_modules/webpack-dev-middleware/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true + }, + "node_modules/webpack-dev-middleware/node_modules/schema-utils": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz", + "integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.9", + "ajv": "^8.9.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.1.0" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/webpack-dev-server": { + "version": "4.15.1", + "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-4.15.1.tgz", + "integrity": "sha512-5hbAst3h3C3L8w6W4P96L5vaV0PxSmJhxZvWKYIdgxOQm8pNZ5dEOmmSLBVpP85ReeyRt6AS1QJNyo/oFFPeVA==", + "dev": true, + "dependencies": { + "@types/bonjour": "^3.5.9", + "@types/connect-history-api-fallback": "^1.3.5", + "@types/express": "^4.17.13", + "@types/serve-index": "^1.9.1", + "@types/serve-static": "^1.13.10", + "@types/sockjs": "^0.3.33", + "@types/ws": "^8.5.5", + "ansi-html-community": "^0.0.8", + "bonjour-service": "^1.0.11", + "chokidar": "^3.5.3", + "colorette": "^2.0.10", + "compression": "^1.7.4", + "connect-history-api-fallback": "^2.0.0", + "default-gateway": "^6.0.3", + "express": "^4.17.3", + "graceful-fs": "^4.2.6", + "html-entities": "^2.3.2", + "http-proxy-middleware": "^2.0.3", + "ipaddr.js": "^2.0.1", + "launch-editor": "^2.6.0", + "open": "^8.0.9", + "p-retry": "^4.5.0", + "rimraf": "^3.0.2", + "schema-utils": "^4.0.0", + "selfsigned": "^2.1.1", + "serve-index": "^1.9.1", + "sockjs": "^0.3.24", + "spdy": "^4.0.2", + "webpack-dev-middleware": "^5.3.1", + "ws": "^8.13.0" + }, + "bin": { + "webpack-dev-server": "bin/webpack-dev-server.js" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^4.37.0 || ^5.0.0" + }, + "peerDependenciesMeta": { + "webpack": { + "optional": true + }, + "webpack-cli": { + "optional": true + } + } + }, + "node_modules/webpack-dev-server/node_modules/ajv": { + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", + "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/webpack-dev-server/node_modules/ajv-keywords": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.3" + }, + "peerDependencies": { + "ajv": "^8.8.2" + } + }, + "node_modules/webpack-dev-server/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true + }, + "node_modules/webpack-dev-server/node_modules/schema-utils": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz", + "integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.9", + "ajv": "^8.9.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.1.0" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/webpack-merge": { + "version": "5.10.0", + "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.10.0.tgz", + "integrity": "sha512-+4zXKdx7UnO+1jaN4l2lHVD+mFvnlZQP/6ljaJVb4SZiwIKeUnrT5l0gkT8z+n4hKpC+jpOv6O9R+gLtag7pSA==", + "dev": true, + "dependencies": { + "clone-deep": "^4.0.1", + "flat": "^5.0.2", + "wildcard": "^2.0.0" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/webpack-sources": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz", + "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==", + "dev": true, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/websocket-driver": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", + "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", + "dev": true, + "dependencies": { + "http-parser-js": ">=0.5.1", + "safe-buffer": ">=5.1.0", + "websocket-extensions": ">=0.1.1" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/websocket-extensions": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", + "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/whatwg-encoding": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz", + "integrity": "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==", + "dependencies": { + "iconv-lite": "0.6.3" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/whatwg-mimetype": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz", + "integrity": "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==", + "engines": { + "node": ">=18" + } + }, + "node_modules/whatwg-url": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-14.0.0.tgz", + "integrity": "sha512-1lfMEm2IEr7RIV+f4lUNPOqfFL+pO+Xw3fJSqmjX9AbXcXcYOkCe1P6+9VBZB6n94af16NfZf+sSk0JCBZC9aw==", + "dependencies": { + "tr46": "^5.0.0", + "webidl-conversions": "^7.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/wildcard": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.1.tgz", + "integrity": "sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==", + "dev": true + }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==", + "dev": true + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true + }, + "node_modules/write": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/write/-/write-0.2.1.tgz", + "integrity": "sha512-CJ17OoULEKXpA5pef3qLj5AxTJ6mSt7g84he2WIskKwqFO4T97d5V7Tadl0DYDk7qyUOQD5WlUlOMChaYrhxeA==", + "dev": true, + "dependencies": { + "mkdirp": "^0.5.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ws": { + "version": "8.15.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.15.1.tgz", + "integrity": "sha512-W5OZiCjXEmk0yZ66ZN82beM5Sz7l7coYxpRkzS+p9PP+ToQry8szKh+61eNktr7EA9DOwvFGhfC605jDHbP6QQ==", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/xml-name-validator": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-5.0.0.tgz", + "integrity": "sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==", + "engines": { + "node": ">=18" + } + }, + "node_modules/xmlchars": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", + "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==" + }, + "node_modules/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.4" + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "dev": true, + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs/node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + } + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.24.2", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.2.tgz", + "integrity": "sha512-y5+tLQyV8pg3fsiln67BVLD1P13Eg4lh5RW9mF0zUuvLrv9uIQ4MCL+CRT+FTsBlBjcIan6PGsLcBN0m3ClUyQ==", + "dev": true, + "requires": { + "@babel/highlight": "^7.24.2", + "picocolors": "^1.0.0" + } + }, + "@babel/helper-validator-identifier": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", + "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", + "dev": true + }, + "@babel/highlight": { + "version": "7.24.2", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.2.tgz", + "integrity": "sha512-Yac1ao4flkTxTteCDZLEvdxg2fZfz1v8M4QpaGypq/WPDqg3ijHYbDfs+LG5hvzSoqaSZ9/Z9lKSP3CjZjv+pA==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.22.20", + "chalk": "^2.4.2", + "js-tokens": "^4.0.0", + "picocolors": "^1.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "@blockly/continuous-toolbox": { + "version": "6.0.9", + "resolved": "https://registry.npmjs.org/@blockly/continuous-toolbox/-/continuous-toolbox-6.0.9.tgz", + "integrity": "sha512-b7WrMeZwxOJJ35aJggJ8ndBt8yUzm2i+HsfmQ78Ti7+xHHlJ2+DMLWORKoDc9HYVtYwiwZzjbJd3LucFm7mE2w==", + "requires": {} + }, + "@blockly/field-colour": { + "version": "5.0.9", + "resolved": "https://registry.npmjs.org/@blockly/field-colour/-/field-colour-5.0.9.tgz", + "integrity": "sha512-ebj4oGwrqkcGKTYjLDHLQYilZ1qfmiPIfi3QVv/ROfSut4VPEf4JEnTmc/AJJrKQgzygdbz02QLZ2DBlVkoWNg==", + "requires": {} + }, + "@colors/colors": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", + "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", + "dev": true, + "optional": true + }, + "@commitlint/cli": { + "version": "17.8.1", + "resolved": "https://registry.npmjs.org/@commitlint/cli/-/cli-17.8.1.tgz", + "integrity": "sha512-ay+WbzQesE0Rv4EQKfNbSMiJJ12KdKTDzIt0tcK4k11FdsWmtwP0Kp1NWMOUswfIWo6Eb7p7Ln721Nx9FLNBjg==", + "dev": true, + "requires": { + "@commitlint/format": "^17.8.1", + "@commitlint/lint": "^17.8.1", + "@commitlint/load": "^17.8.1", + "@commitlint/read": "^17.8.1", + "@commitlint/types": "^17.8.1", + "execa": "^5.0.0", + "lodash.isfunction": "^3.0.9", + "resolve-from": "5.0.0", + "resolve-global": "1.0.0", + "yargs": "^17.0.0" + } + }, + "@commitlint/config-conventional": { + "version": "17.8.1", + "resolved": "https://registry.npmjs.org/@commitlint/config-conventional/-/config-conventional-17.8.1.tgz", + "integrity": "sha512-NxCOHx1kgneig3VLauWJcDWS40DVjg7nKOpBEEK9E5fjJpQqLCilcnKkIIjdBH98kEO1q3NpE5NSrZ2kl/QGJg==", + "dev": true, + "requires": { + "conventional-changelog-conventionalcommits": "^6.1.0" + } + }, + "@commitlint/config-validator": { + "version": "17.8.1", + "resolved": "https://registry.npmjs.org/@commitlint/config-validator/-/config-validator-17.8.1.tgz", + "integrity": "sha512-UUgUC+sNiiMwkyiuIFR7JG2cfd9t/7MV8VB4TZ+q02ZFkHoduUS4tJGsCBWvBOGD9Btev6IecPMvlWUfJorkEA==", + "dev": true, + "requires": { + "@commitlint/types": "^17.8.1", + "ajv": "^8.11.0" + }, + "dependencies": { + "ajv": { + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", + "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + } + }, + "json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true + } + } + }, + "@commitlint/ensure": { + "version": "17.8.1", + "resolved": "https://registry.npmjs.org/@commitlint/ensure/-/ensure-17.8.1.tgz", + "integrity": "sha512-xjafwKxid8s1K23NFpL8JNo6JnY/ysetKo8kegVM7c8vs+kWLP8VrQq+NbhgVlmCojhEDbzQKp4eRXSjVOGsow==", + "dev": true, + "requires": { + "@commitlint/types": "^17.8.1", + "lodash.camelcase": "^4.3.0", + "lodash.kebabcase": "^4.1.1", + "lodash.snakecase": "^4.1.1", + "lodash.startcase": "^4.4.0", + "lodash.upperfirst": "^4.3.1" + } + }, + "@commitlint/execute-rule": { + "version": "17.8.1", + "resolved": "https://registry.npmjs.org/@commitlint/execute-rule/-/execute-rule-17.8.1.tgz", + "integrity": "sha512-JHVupQeSdNI6xzA9SqMF+p/JjrHTcrJdI02PwesQIDCIGUrv04hicJgCcws5nzaoZbROapPs0s6zeVHoxpMwFQ==", + "dev": true + }, + "@commitlint/format": { + "version": "17.8.1", + "resolved": "https://registry.npmjs.org/@commitlint/format/-/format-17.8.1.tgz", + "integrity": "sha512-f3oMTyZ84M9ht7fb93wbCKmWxO5/kKSbwuYvS867duVomoOsgrgljkGGIztmT/srZnaiGbaK8+Wf8Ik2tSr5eg==", + "dev": true, + "requires": { + "@commitlint/types": "^17.8.1", + "chalk": "^4.1.0" + } + }, + "@commitlint/is-ignored": { + "version": "17.8.1", + "resolved": "https://registry.npmjs.org/@commitlint/is-ignored/-/is-ignored-17.8.1.tgz", + "integrity": "sha512-UshMi4Ltb4ZlNn4F7WtSEugFDZmctzFpmbqvpyxD3la510J+PLcnyhf9chs7EryaRFJMdAKwsEKfNK0jL/QM4g==", + "dev": true, + "requires": { + "@commitlint/types": "^17.8.1", + "semver": "7.5.4" + } + }, + "@commitlint/lint": { + "version": "17.8.1", + "resolved": "https://registry.npmjs.org/@commitlint/lint/-/lint-17.8.1.tgz", + "integrity": "sha512-aQUlwIR1/VMv2D4GXSk7PfL5hIaFSfy6hSHV94O8Y27T5q+DlDEgd/cZ4KmVI+MWKzFfCTiTuWqjfRSfdRllCA==", + "dev": true, + "requires": { + "@commitlint/is-ignored": "^17.8.1", + "@commitlint/parse": "^17.8.1", + "@commitlint/rules": "^17.8.1", + "@commitlint/types": "^17.8.1" + } + }, + "@commitlint/load": { + "version": "17.8.1", + "resolved": "https://registry.npmjs.org/@commitlint/load/-/load-17.8.1.tgz", + "integrity": "sha512-iF4CL7KDFstP1kpVUkT8K2Wl17h2yx9VaR1ztTc8vzByWWcbO/WaKwxsnCOqow9tVAlzPfo1ywk9m2oJ9ucMqA==", + "dev": true, + "requires": { + "@commitlint/config-validator": "^17.8.1", + "@commitlint/execute-rule": "^17.8.1", + "@commitlint/resolve-extends": "^17.8.1", + "@commitlint/types": "^17.8.1", + "@types/node": "20.5.1", + "chalk": "^4.1.0", + "cosmiconfig": "^8.0.0", + "cosmiconfig-typescript-loader": "^4.0.0", + "lodash.isplainobject": "^4.0.6", + "lodash.merge": "^4.6.2", + "lodash.uniq": "^4.5.0", + "resolve-from": "^5.0.0", + "ts-node": "^10.8.1", + "typescript": "^4.6.4 || ^5.2.2" + }, + "dependencies": { + "@types/node": { + "version": "20.5.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.5.1.tgz", + "integrity": "sha512-4tT2UrL5LBqDwoed9wZ6N3umC4Yhz3W3FloMmiiG4JwmUJWpie0c7lcnUNd4gtMKuDEO4wRVS8B6Xa0uMRsMKg==", + "dev": true + } + } + }, + "@commitlint/message": { + "version": "17.8.1", + "resolved": "https://registry.npmjs.org/@commitlint/message/-/message-17.8.1.tgz", + "integrity": "sha512-6bYL1GUQsD6bLhTH3QQty8pVFoETfFQlMn2Nzmz3AOLqRVfNNtXBaSY0dhZ0dM6A2MEq4+2d7L/2LP8TjqGRkA==", + "dev": true + }, + "@commitlint/parse": { + "version": "17.8.1", + "resolved": "https://registry.npmjs.org/@commitlint/parse/-/parse-17.8.1.tgz", + "integrity": "sha512-/wLUickTo0rNpQgWwLPavTm7WbwkZoBy3X8PpkUmlSmQJyWQTj0m6bDjiykMaDt41qcUbfeFfaCvXfiR4EGnfw==", + "dev": true, + "requires": { + "@commitlint/types": "^17.8.1", + "conventional-changelog-angular": "^6.0.0", + "conventional-commits-parser": "^4.0.0" + } + }, + "@commitlint/read": { + "version": "17.8.1", + "resolved": "https://registry.npmjs.org/@commitlint/read/-/read-17.8.1.tgz", + "integrity": "sha512-Fd55Oaz9irzBESPCdMd8vWWgxsW3OWR99wOntBDHgf9h7Y6OOHjWEdS9Xzen1GFndqgyoaFplQS5y7KZe0kO2w==", + "dev": true, + "requires": { + "@commitlint/top-level": "^17.8.1", + "@commitlint/types": "^17.8.1", + "fs-extra": "^11.0.0", + "git-raw-commits": "^2.0.11", + "minimist": "^1.2.6" + } + }, + "@commitlint/resolve-extends": { + "version": "17.8.1", + "resolved": "https://registry.npmjs.org/@commitlint/resolve-extends/-/resolve-extends-17.8.1.tgz", + "integrity": "sha512-W/ryRoQ0TSVXqJrx5SGkaYuAaE/BUontL1j1HsKckvM6e5ZaG0M9126zcwL6peKSuIetJi7E87PRQF8O86EW0Q==", + "dev": true, + "requires": { + "@commitlint/config-validator": "^17.8.1", + "@commitlint/types": "^17.8.1", + "import-fresh": "^3.0.0", + "lodash.mergewith": "^4.6.2", + "resolve-from": "^5.0.0", + "resolve-global": "^1.0.0" + } + }, + "@commitlint/rules": { + "version": "17.8.1", + "resolved": "https://registry.npmjs.org/@commitlint/rules/-/rules-17.8.1.tgz", + "integrity": "sha512-2b7OdVbN7MTAt9U0vKOYKCDsOvESVXxQmrvuVUZ0rGFMCrCPJWWP1GJ7f0lAypbDAhaGb8zqtdOr47192LBrIA==", + "dev": true, + "requires": { + "@commitlint/ensure": "^17.8.1", + "@commitlint/message": "^17.8.1", + "@commitlint/to-lines": "^17.8.1", + "@commitlint/types": "^17.8.1", + "execa": "^5.0.0" + } + }, + "@commitlint/to-lines": { + "version": "17.8.1", + "resolved": "https://registry.npmjs.org/@commitlint/to-lines/-/to-lines-17.8.1.tgz", + "integrity": "sha512-LE0jb8CuR/mj6xJyrIk8VLz03OEzXFgLdivBytoooKO5xLt5yalc8Ma5guTWobw998sbR3ogDd+2jed03CFmJA==", + "dev": true + }, + "@commitlint/top-level": { + "version": "17.8.1", + "resolved": "https://registry.npmjs.org/@commitlint/top-level/-/top-level-17.8.1.tgz", + "integrity": "sha512-l6+Z6rrNf5p333SHfEte6r+WkOxGlWK4bLuZKbtf/2TXRN+qhrvn1XE63VhD8Oe9oIHQ7F7W1nG2k/TJFhx2yA==", + "dev": true, + "requires": { + "find-up": "^5.0.0" + }, + "dependencies": { + "find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "requires": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + } + }, + "locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "requires": { + "p-locate": "^5.0.0" + } + }, + "p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "requires": { + "yocto-queue": "^0.1.0" + } + }, + "p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "requires": { + "p-limit": "^3.0.2" + } + } + } + }, + "@commitlint/types": { + "version": "17.8.1", + "resolved": "https://registry.npmjs.org/@commitlint/types/-/types-17.8.1.tgz", + "integrity": "sha512-PXDQXkAmiMEG162Bqdh9ChML/GJZo6vU+7F03ALKDK8zYc6SuAr47LjG7hGYRqUOz+WK0dU7bQ0xzuqFMdxzeQ==", + "dev": true, + "requires": { + "chalk": "^4.1.0" + } + }, + "@cspotcode/source-map-support": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "dev": true, + "requires": { + "@jridgewell/trace-mapping": "0.3.9" + }, + "dependencies": { + "@jridgewell/trace-mapping": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "dev": true, + "requires": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + } + } + }, + "@discoveryjs/json-ext": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz", + "integrity": "sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==", + "dev": true + }, + "@jridgewell/gen-mapping": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", + "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", + "dev": true, + "requires": { + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + } + }, + "@jridgewell/resolve-uri": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", + "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==", + "dev": true + }, + "@jridgewell/set-array": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", + "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", + "dev": true + }, + "@jridgewell/source-map": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.5.tgz", + "integrity": "sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ==", + "dev": true, + "requires": { + "@jridgewell/gen-mapping": "^0.3.0", + "@jridgewell/trace-mapping": "^0.3.9" + } + }, + "@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", + "dev": true + }, + "@jridgewell/trace-mapping": { + "version": "0.3.20", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.20.tgz", + "integrity": "sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q==", + "dev": true, + "requires": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "@leichtgewicht/ip-codec": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.4.tgz", + "integrity": "sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A==", + "dev": true + }, + "@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "requires": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + } + }, + "@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true + }, + "@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "requires": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + } + }, + "@octokit/auth-token": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-4.0.0.tgz", + "integrity": "sha512-tY/msAuJo6ARbK6SPIxZrPBms3xPbfwBrulZe0Wtr/DIY9lje2HeV1uoebShn6mx7SjCHif6EjMvoREj+gZ+SA==", + "dev": true + }, + "@octokit/core": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@octokit/core/-/core-5.2.0.tgz", + "integrity": "sha512-1LFfa/qnMQvEOAdzlQymH0ulepxbxnCYAKJZfMci/5XJyIHWgEYnDmgnKakbTh7CH2tFQ5O60oYDvns4i9RAIg==", + "dev": true, + "requires": { + "@octokit/auth-token": "^4.0.0", + "@octokit/graphql": "^7.1.0", + "@octokit/request": "^8.3.1", + "@octokit/request-error": "^5.1.0", + "@octokit/types": "^13.0.0", + "before-after-hook": "^2.2.0", + "universal-user-agent": "^6.0.0" + } + }, + "@octokit/endpoint": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-9.0.5.tgz", + "integrity": "sha512-ekqR4/+PCLkEBF6qgj8WqJfvDq65RH85OAgrtnVp1mSxaXF03u2xW/hUdweGS5654IlC0wkNYC18Z50tSYTAFw==", + "dev": true, + "requires": { + "@octokit/types": "^13.1.0", + "universal-user-agent": "^6.0.0" + } + }, + "@octokit/graphql": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-7.1.0.tgz", + "integrity": "sha512-r+oZUH7aMFui1ypZnAvZmn0KSqAUgE1/tUXIWaqUCa1758ts/Jio84GZuzsvUkme98kv0WFY8//n0J1Z+vsIsQ==", + "dev": true, + "requires": { + "@octokit/request": "^8.3.0", + "@octokit/types": "^13.0.0", + "universal-user-agent": "^6.0.0" + } + }, + "@octokit/openapi-types": { + "version": "22.2.0", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-22.2.0.tgz", + "integrity": "sha512-QBhVjcUa9W7Wwhm6DBFu6ZZ+1/t/oYxqc2tp81Pi41YNuJinbFRx8B133qVOrAaBbF7D/m0Et6f9/pZt9Rc+tg==", + "dev": true + }, + "@octokit/plugin-paginate-rest": { + "version": "9.2.1", + "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-9.2.1.tgz", + "integrity": "sha512-wfGhE/TAkXZRLjksFXuDZdmGnJQHvtU/joFQdweXUgzo1XwvBCD4o4+75NtFfjfLK5IwLf9vHTfSiU3sLRYpRw==", + "dev": true, + "requires": { + "@octokit/types": "^12.6.0" + }, + "dependencies": { + "@octokit/openapi-types": { + "version": "20.0.0", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-20.0.0.tgz", + "integrity": "sha512-EtqRBEjp1dL/15V7WiX5LJMIxxkdiGJnabzYx5Apx4FkQIFgAfKumXeYAqqJCj1s+BMX4cPFIFC4OLCR6stlnA==", + "dev": true + }, + "@octokit/types": { + "version": "12.6.0", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-12.6.0.tgz", + "integrity": "sha512-1rhSOfRa6H9w4YwK0yrf5faDaDTb+yLyBUKOCV4xtCDB5VmIPqd/v9yr9o6SAzOAlRxMiRiCic6JVM1/kunVkw==", + "dev": true, + "requires": { + "@octokit/openapi-types": "^20.0.0" + } + } + } + }, + "@octokit/plugin-retry": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/@octokit/plugin-retry/-/plugin-retry-6.0.1.tgz", + "integrity": "sha512-SKs+Tz9oj0g4p28qkZwl/topGcb0k0qPNX/i7vBKmDsjoeqnVfFUquqrE/O9oJY7+oLzdCtkiWSXLpLjvl6uog==", + "dev": true, + "requires": { + "@octokit/request-error": "^5.0.0", + "@octokit/types": "^12.0.0", + "bottleneck": "^2.15.3" + }, + "dependencies": { + "@octokit/openapi-types": { + "version": "20.0.0", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-20.0.0.tgz", + "integrity": "sha512-EtqRBEjp1dL/15V7WiX5LJMIxxkdiGJnabzYx5Apx4FkQIFgAfKumXeYAqqJCj1s+BMX4cPFIFC4OLCR6stlnA==", + "dev": true + }, + "@octokit/types": { + "version": "12.6.0", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-12.6.0.tgz", + "integrity": "sha512-1rhSOfRa6H9w4YwK0yrf5faDaDTb+yLyBUKOCV4xtCDB5VmIPqd/v9yr9o6SAzOAlRxMiRiCic6JVM1/kunVkw==", + "dev": true, + "requires": { + "@octokit/openapi-types": "^20.0.0" + } + } + } + }, + "@octokit/plugin-throttling": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/@octokit/plugin-throttling/-/plugin-throttling-8.2.0.tgz", + "integrity": "sha512-nOpWtLayKFpgqmgD0y3GqXafMFuKcA4tRPZIfu7BArd2lEZeb1988nhWhwx4aZWmjDmUfdgVf7W+Tt4AmvRmMQ==", + "dev": true, + "requires": { + "@octokit/types": "^12.2.0", + "bottleneck": "^2.15.3" + }, + "dependencies": { + "@octokit/openapi-types": { + "version": "20.0.0", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-20.0.0.tgz", + "integrity": "sha512-EtqRBEjp1dL/15V7WiX5LJMIxxkdiGJnabzYx5Apx4FkQIFgAfKumXeYAqqJCj1s+BMX4cPFIFC4OLCR6stlnA==", + "dev": true + }, + "@octokit/types": { + "version": "12.6.0", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-12.6.0.tgz", + "integrity": "sha512-1rhSOfRa6H9w4YwK0yrf5faDaDTb+yLyBUKOCV4xtCDB5VmIPqd/v9yr9o6SAzOAlRxMiRiCic6JVM1/kunVkw==", + "dev": true, + "requires": { + "@octokit/openapi-types": "^20.0.0" + } + } + } + }, + "@octokit/request": { + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/@octokit/request/-/request-8.4.0.tgz", + "integrity": "sha512-9Bb014e+m2TgBeEJGEbdplMVWwPmL1FPtggHQRkV+WVsMggPtEkLKPlcVYm/o8xKLkpJ7B+6N8WfQMtDLX2Dpw==", + "dev": true, + "requires": { + "@octokit/endpoint": "^9.0.1", + "@octokit/request-error": "^5.1.0", + "@octokit/types": "^13.1.0", + "universal-user-agent": "^6.0.0" + } + }, + "@octokit/request-error": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-5.1.0.tgz", + "integrity": "sha512-GETXfE05J0+7H2STzekpKObFe765O5dlAKUTLNGeH+x47z7JjXHfsHKo5z21D/o/IOZTUEI6nyWyR+bZVP/n5Q==", + "dev": true, + "requires": { + "@octokit/types": "^13.1.0", + "deprecation": "^2.0.0", + "once": "^1.4.0" + } + }, + "@octokit/tsconfig": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@octokit/tsconfig/-/tsconfig-1.0.2.tgz", + "integrity": "sha512-I0vDR0rdtP8p2lGMzvsJzbhdOWy405HcGovrspJ8RRibHnyRgggUSNO5AIox5LmqiwmatHKYsvj6VGFHkqS7lA==", + "dev": true + }, + "@octokit/types": { + "version": "13.6.1", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.6.1.tgz", + "integrity": "sha512-PHZE9Z+kWXb23Ndik8MKPirBPziOc0D2/3KH1P+6jK5nGWe96kadZuE4jev2/Jq7FvIfTlT2Ltg8Fv2x1v0a5g==", + "dev": true, + "requires": { + "@octokit/openapi-types": "^22.2.0" + } + }, + "@pnpm/config.env-replace": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@pnpm/config.env-replace/-/config.env-replace-1.1.0.tgz", + "integrity": "sha512-htyl8TWnKL7K/ESFa1oW2UB5lVDxuF5DpM7tBi6Hu2LNL3mWkIzNLG6N4zoCUP1lCKNxWy/3iu8mS8MvToGd6w==", + "dev": true + }, + "@pnpm/network.ca-file": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@pnpm/network.ca-file/-/network.ca-file-1.0.2.tgz", + "integrity": "sha512-YcPQ8a0jwYU9bTdJDpXjMi7Brhkr1mXsXrUJvjqM2mQDgkRiz8jFaQGOdaLxgjtUfQgZhKy/O3cG/YwmgKaxLA==", + "dev": true, + "requires": { + "graceful-fs": "4.2.10" + }, + "dependencies": { + "graceful-fs": { + "version": "4.2.10", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", + "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", + "dev": true + } + } + }, + "@pnpm/npm-conf": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/@pnpm/npm-conf/-/npm-conf-2.3.1.tgz", + "integrity": "sha512-c83qWb22rNRuB0UaVCI0uRPNRr8Z0FWnEIvT47jiHAmOIUHbBOg5XvV7pM5x+rKn9HRpjxquDbXYSXr3fAKFcw==", + "dev": true, + "requires": { + "@pnpm/config.env-replace": "^1.1.0", + "@pnpm/network.ca-file": "^1.0.1", + "config-chain": "^1.1.11" + } + }, + "@semantic-release/changelog": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/@semantic-release/changelog/-/changelog-6.0.3.tgz", + "integrity": "sha512-dZuR5qByyfe3Y03TpmCvAxCyTnp7r5XwtHRf/8vD9EAn4ZWbavUX8adMtXYzE86EVh0gyLA7lm5yW4IV30XUag==", + "dev": true, + "requires": { + "@semantic-release/error": "^3.0.0", + "aggregate-error": "^3.0.0", + "fs-extra": "^11.0.0", + "lodash": "^4.17.4" + }, + "dependencies": { + "@semantic-release/error": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@semantic-release/error/-/error-3.0.0.tgz", + "integrity": "sha512-5hiM4Un+tpl4cKw3lV4UgzJj+SmfNIDCLLw0TepzQxz9ZGV5ixnqkzIVF+3tp0ZHgcMKE+VNGHJjEeyFG2dcSw==", + "dev": true + }, + "aggregate-error": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", + "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", + "dev": true, + "requires": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + } + }, + "clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "dev": true + } + } + }, + "@semantic-release/commit-analyzer": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/@semantic-release/commit-analyzer/-/commit-analyzer-11.1.0.tgz", + "integrity": "sha512-cXNTbv3nXR2hlzHjAMgbuiQVtvWHTlwwISt60B+4NZv01y/QRY7p2HcJm8Eh2StzcTJoNnflvKjHH/cjFS7d5g==", + "dev": true, + "requires": { + "conventional-changelog-angular": "^7.0.0", + "conventional-commits-filter": "^4.0.0", + "conventional-commits-parser": "^5.0.0", + "debug": "^4.0.0", + "import-from-esm": "^1.0.3", + "lodash-es": "^4.17.21", + "micromatch": "^4.0.2" + }, + "dependencies": { + "conventional-changelog-angular": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-7.0.0.tgz", + "integrity": "sha512-ROjNchA9LgfNMTTFSIWPzebCwOGFdgkEq45EnvvrmSLvCtAw0HSmrCs7/ty+wAeYUZyNay0YMUNYFTRL72PkBQ==", + "dev": true, + "requires": { + "compare-func": "^2.0.0" + } + }, + "conventional-commits-parser": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-5.0.0.tgz", + "integrity": "sha512-ZPMl0ZJbw74iS9LuX9YIAiW8pfM5p3yh2o/NbXHbkFuZzY5jvdi5jFycEOkmBW5H5I7nA+D6f3UcsCLP2vvSEA==", + "dev": true, + "requires": { + "is-text-path": "^2.0.0", + "JSONStream": "^1.3.5", + "meow": "^12.0.1", + "split2": "^4.0.0" + } + }, + "is-text-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-text-path/-/is-text-path-2.0.0.tgz", + "integrity": "sha512-+oDTluR6WEjdXEJMnC2z6A4FRwFoYuvShVVEGsS7ewc0UTi2QtAKMDJuL4BDEVt+5T7MjFo12RP8ghOM75oKJw==", + "dev": true, + "requires": { + "text-extensions": "^2.0.0" + } + }, + "meow": { + "version": "12.1.1", + "resolved": "https://registry.npmjs.org/meow/-/meow-12.1.1.tgz", + "integrity": "sha512-BhXM0Au22RwUneMPwSCnyhTOizdWoIEPU9sp0Aqa1PnDMR5Wv2FGXYDjuzJEIX+Eo2Rb8xuYe5jrnm5QowQFkw==", + "dev": true + }, + "split2": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", + "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==", + "dev": true + }, + "text-extensions": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/text-extensions/-/text-extensions-2.4.0.tgz", + "integrity": "sha512-te/NtwBwfiNRLf9Ijqx3T0nlqZiQ2XrrtBvu+cLL8ZRrGkO0NHTug8MYFKyoSrv/sHTaSKfilUkizV6XhxMJ3g==", + "dev": true + } + } + }, + "@semantic-release/error": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@semantic-release/error/-/error-4.0.0.tgz", + "integrity": "sha512-mgdxrHTLOjOddRVYIYDo0fR3/v61GNN1YGkfbrjuIKg/uMgCd+Qzo3UAXJ+woLQQpos4pl5Esuw5A7AoNlzjUQ==", + "dev": true + }, + "@semantic-release/git": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/@semantic-release/git/-/git-10.0.1.tgz", + "integrity": "sha512-eWrx5KguUcU2wUPaO6sfvZI0wPafUKAMNC18aXY4EnNcrZL86dEmpNVnC9uMpGZkmZJ9EfCVJBQx4pV4EMGT1w==", + "dev": true, + "requires": { + "@semantic-release/error": "^3.0.0", + "aggregate-error": "^3.0.0", + "debug": "^4.0.0", + "dir-glob": "^3.0.0", + "execa": "^5.0.0", + "lodash": "^4.17.4", + "micromatch": "^4.0.0", + "p-reduce": "^2.0.0" + }, + "dependencies": { + "@semantic-release/error": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@semantic-release/error/-/error-3.0.0.tgz", + "integrity": "sha512-5hiM4Un+tpl4cKw3lV4UgzJj+SmfNIDCLLw0TepzQxz9ZGV5ixnqkzIVF+3tp0ZHgcMKE+VNGHJjEeyFG2dcSw==", + "dev": true + }, + "aggregate-error": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", + "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", + "dev": true, + "requires": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + } + }, + "clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "dev": true + }, + "p-reduce": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-reduce/-/p-reduce-2.1.0.tgz", + "integrity": "sha512-2USApvnsutq8uoxZBGbbWM0JIYLiEMJ9RlaN7fAzVNb9OZN0SHjjTTfIcb667XynS5Y1VhwDJVDa72TnPzAYWw==", + "dev": true + } + } + }, + "@semantic-release/github": { + "version": "9.2.6", + "resolved": "https://registry.npmjs.org/@semantic-release/github/-/github-9.2.6.tgz", + "integrity": "sha512-shi+Lrf6exeNZF+sBhK+P011LSbhmIAoUEgEY6SsxF8irJ+J2stwI5jkyDQ+4gzYyDImzV6LCKdYB9FXnQRWKA==", + "dev": true, + "requires": { + "@octokit/core": "^5.0.0", + "@octokit/plugin-paginate-rest": "^9.0.0", + "@octokit/plugin-retry": "^6.0.0", + "@octokit/plugin-throttling": "^8.0.0", + "@semantic-release/error": "^4.0.0", + "aggregate-error": "^5.0.0", + "debug": "^4.3.4", + "dir-glob": "^3.0.1", + "globby": "^14.0.0", + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.0", + "issue-parser": "^6.0.0", + "lodash-es": "^4.17.21", + "mime": "^4.0.0", + "p-filter": "^4.0.0", + "url-join": "^5.0.0" + }, + "dependencies": { + "mime": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/mime/-/mime-4.0.4.tgz", + "integrity": "sha512-v8yqInVjhXyqP6+Kw4fV3ZzeMRqEW6FotRsKXjRS5VMTNIuXsdRoAvklpoRgSqXm6o9VNH4/C0mgedko9DdLsQ==", + "dev": true + } + } + }, + "@semantic-release/npm": { + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/@semantic-release/npm/-/npm-11.0.3.tgz", + "integrity": "sha512-KUsozQGhRBAnoVg4UMZj9ep436VEGwT536/jwSqB7vcEfA6oncCUU7UIYTRdLx7GvTtqn0kBjnkfLVkcnBa2YQ==", + "dev": true, + "requires": { + "@semantic-release/error": "^4.0.0", + "aggregate-error": "^5.0.0", + "execa": "^8.0.0", + "fs-extra": "^11.0.0", + "lodash-es": "^4.17.21", + "nerf-dart": "^1.0.0", + "normalize-url": "^8.0.0", + "npm": "^10.5.0", + "rc": "^1.2.8", + "read-pkg": "^9.0.0", + "registry-auth-token": "^5.0.0", + "semver": "^7.1.2", + "tempy": "^3.0.0" + }, + "dependencies": { + "execa": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", + "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==", + "dev": true, + "requires": { + "cross-spawn": "^7.0.3", + "get-stream": "^8.0.1", + "human-signals": "^5.0.0", + "is-stream": "^3.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^5.1.0", + "onetime": "^6.0.0", + "signal-exit": "^4.1.0", + "strip-final-newline": "^3.0.0" + } + }, + "get-stream": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", + "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==", + "dev": true + }, + "hosted-git-info": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-7.0.2.tgz", + "integrity": "sha512-puUZAUKT5m8Zzvs72XWy3HtvVbTWljRE66cP60bxJzAqf2DgICo7lYTY2IHUmLnNpjYvw5bvmoHvPc0QO2a62w==", + "dev": true, + "requires": { + "lru-cache": "^10.0.1" + } + }, + "human-signals": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz", + "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==", + "dev": true + }, + "is-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", + "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", + "dev": true + }, + "lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true + }, + "mimic-fn": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", + "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", + "dev": true + }, + "normalize-package-data": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-6.0.2.tgz", + "integrity": "sha512-V6gygoYb/5EmNI+MEGrWkC+e6+Rr7mTmfHrxDbLzxQogBkgzo76rkok0Am6thgSF7Mv2nLOajAJj5vDJZEFn7g==", + "dev": true, + "requires": { + "hosted-git-info": "^7.0.0", + "semver": "^7.3.5", + "validate-npm-package-license": "^3.0.4" + } + }, + "npm-run-path": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.3.0.tgz", + "integrity": "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==", + "dev": true, + "requires": { + "path-key": "^4.0.0" + } + }, + "onetime": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", + "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", + "dev": true, + "requires": { + "mimic-fn": "^4.0.0" + } + }, + "parse-json": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-8.1.0.tgz", + "integrity": "sha512-rum1bPifK5SSar35Z6EKZuYPJx85pkNaFrxBK3mwdfSJ1/WKbYrjoW/zTPSjRRamfmVX1ACBIdFAO0VRErW/EA==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.22.13", + "index-to-position": "^0.1.2", + "type-fest": "^4.7.1" + } + }, + "path-key": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", + "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", + "dev": true + }, + "read-pkg": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-9.0.1.tgz", + "integrity": "sha512-9viLL4/n1BJUCT1NXVTdS1jtm80yDEgR5T4yCelII49Mbj0v1rZdKqj7zCiYdbB0CuCgdrvHcNogAKTFPBocFA==", + "dev": true, + "requires": { + "@types/normalize-package-data": "^2.4.3", + "normalize-package-data": "^6.0.0", + "parse-json": "^8.0.0", + "type-fest": "^4.6.0", + "unicorn-magic": "^0.1.0" + } + }, + "signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true + }, + "strip-final-newline": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", + "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", + "dev": true + }, + "type-fest": { + "version": "4.26.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.26.1.tgz", + "integrity": "sha512-yOGpmOAL7CkKe/91I5O3gPICmJNLJ1G4zFYVAsRHg7M64biSnPtRj0WNQt++bRkjYOqjWXrhnUw1utzmVErAdg==", + "dev": true + } + } + }, + "@semantic-release/release-notes-generator": { + "version": "12.1.0", + "resolved": "https://registry.npmjs.org/@semantic-release/release-notes-generator/-/release-notes-generator-12.1.0.tgz", + "integrity": "sha512-g6M9AjUKAZUZnxaJZnouNBeDNTCUrJ5Ltj+VJ60gJeDaRRahcHsry9HW8yKrnKkKNkx5lbWiEP1FPMqVNQz8Kg==", + "dev": true, + "requires": { + "conventional-changelog-angular": "^7.0.0", + "conventional-changelog-writer": "^7.0.0", + "conventional-commits-filter": "^4.0.0", + "conventional-commits-parser": "^5.0.0", + "debug": "^4.0.0", + "get-stream": "^7.0.0", + "import-from-esm": "^1.0.3", + "into-stream": "^7.0.0", + "lodash-es": "^4.17.21", + "read-pkg-up": "^11.0.0" + }, + "dependencies": { + "conventional-changelog-angular": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-7.0.0.tgz", + "integrity": "sha512-ROjNchA9LgfNMTTFSIWPzebCwOGFdgkEq45EnvvrmSLvCtAw0HSmrCs7/ty+wAeYUZyNay0YMUNYFTRL72PkBQ==", + "dev": true, + "requires": { + "compare-func": "^2.0.0" + } + }, + "conventional-commits-parser": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-5.0.0.tgz", + "integrity": "sha512-ZPMl0ZJbw74iS9LuX9YIAiW8pfM5p3yh2o/NbXHbkFuZzY5jvdi5jFycEOkmBW5H5I7nA+D6f3UcsCLP2vvSEA==", + "dev": true, + "requires": { + "is-text-path": "^2.0.0", + "JSONStream": "^1.3.5", + "meow": "^12.0.1", + "split2": "^4.0.0" + } + }, + "get-stream": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-7.0.1.tgz", + "integrity": "sha512-3M8C1EOFN6r8AMUhwUAACIoXZJEOufDU5+0gFFN5uNs6XYOralD2Pqkl7m046va6x77FwposWXbAhPPIOus7mQ==", + "dev": true + }, + "hosted-git-info": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-7.0.2.tgz", + "integrity": "sha512-puUZAUKT5m8Zzvs72XWy3HtvVbTWljRE66cP60bxJzAqf2DgICo7lYTY2IHUmLnNpjYvw5bvmoHvPc0QO2a62w==", + "dev": true, + "requires": { + "lru-cache": "^10.0.1" + } + }, + "is-text-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-text-path/-/is-text-path-2.0.0.tgz", + "integrity": "sha512-+oDTluR6WEjdXEJMnC2z6A4FRwFoYuvShVVEGsS7ewc0UTi2QtAKMDJuL4BDEVt+5T7MjFo12RP8ghOM75oKJw==", + "dev": true, + "requires": { + "text-extensions": "^2.0.0" + } + }, + "lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true + }, + "meow": { + "version": "12.1.1", + "resolved": "https://registry.npmjs.org/meow/-/meow-12.1.1.tgz", + "integrity": "sha512-BhXM0Au22RwUneMPwSCnyhTOizdWoIEPU9sp0Aqa1PnDMR5Wv2FGXYDjuzJEIX+Eo2Rb8xuYe5jrnm5QowQFkw==", + "dev": true + }, + "normalize-package-data": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-6.0.2.tgz", + "integrity": "sha512-V6gygoYb/5EmNI+MEGrWkC+e6+Rr7mTmfHrxDbLzxQogBkgzo76rkok0Am6thgSF7Mv2nLOajAJj5vDJZEFn7g==", + "dev": true, + "requires": { + "hosted-git-info": "^7.0.0", + "semver": "^7.3.5", + "validate-npm-package-license": "^3.0.4" + } + }, + "parse-json": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-8.1.0.tgz", + "integrity": "sha512-rum1bPifK5SSar35Z6EKZuYPJx85pkNaFrxBK3mwdfSJ1/WKbYrjoW/zTPSjRRamfmVX1ACBIdFAO0VRErW/EA==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.22.13", + "index-to-position": "^0.1.2", + "type-fest": "^4.7.1" + } + }, + "read-pkg": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-9.0.1.tgz", + "integrity": "sha512-9viLL4/n1BJUCT1NXVTdS1jtm80yDEgR5T4yCelII49Mbj0v1rZdKqj7zCiYdbB0CuCgdrvHcNogAKTFPBocFA==", + "dev": true, + "requires": { + "@types/normalize-package-data": "^2.4.3", + "normalize-package-data": "^6.0.0", + "parse-json": "^8.0.0", + "type-fest": "^4.6.0", + "unicorn-magic": "^0.1.0" + } + }, + "read-pkg-up": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-11.0.0.tgz", + "integrity": "sha512-LOVbvF1Q0SZdjClSefZ0Nz5z8u+tIE7mV5NibzmE9VYmDe9CaBbAVtz1veOSZbofrdsilxuDAYnFenukZVp8/Q==", + "dev": true, + "requires": { + "find-up-simple": "^1.0.0", + "read-pkg": "^9.0.0", + "type-fest": "^4.6.0" + } + }, + "split2": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", + "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==", + "dev": true + }, + "text-extensions": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/text-extensions/-/text-extensions-2.4.0.tgz", + "integrity": "sha512-te/NtwBwfiNRLf9Ijqx3T0nlqZiQ2XrrtBvu+cLL8ZRrGkO0NHTug8MYFKyoSrv/sHTaSKfilUkizV6XhxMJ3g==", + "dev": true + }, + "type-fest": { + "version": "4.26.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.26.1.tgz", + "integrity": "sha512-yOGpmOAL7CkKe/91I5O3gPICmJNLJ1G4zFYVAsRHg7M64biSnPtRj0WNQt++bRkjYOqjWXrhnUw1utzmVErAdg==", + "dev": true + } + } + }, + "@sindresorhus/is": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz", + "integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==", + "dev": true + }, + "@sindresorhus/merge-streams": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/merge-streams/-/merge-streams-2.3.0.tgz", + "integrity": "sha512-LtoMMhxAlorcGhmFYI+LhPgbPZCkgP6ra1YL604EeF6U98pLlQ3iWIGMdWSC+vWmPBWBNgmDBAhnAobLROJmwg==", + "dev": true + }, + "@tsconfig/node10": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz", + "integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==", + "dev": true + }, + "@tsconfig/node12": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", + "dev": true + }, + "@tsconfig/node14": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", + "dev": true + }, + "@tsconfig/node16": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", + "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", + "dev": true + }, + "@types/body-parser": { + "version": "1.19.5", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz", + "integrity": "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==", + "dev": true, + "requires": { + "@types/connect": "*", + "@types/node": "*" + } + }, + "@types/bonjour": { + "version": "3.5.13", + "resolved": "https://registry.npmjs.org/@types/bonjour/-/bonjour-3.5.13.tgz", + "integrity": "sha512-z9fJ5Im06zvUL548KvYNecEVlA7cVDkGUi6kZusb04mpyEFKCIZJvloCcmpmLaIahDpOQGHaHmG6imtPMmPXGQ==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/connect": { + "version": "3.4.38", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", + "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/connect-history-api-fallback": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.5.4.tgz", + "integrity": "sha512-n6Cr2xS1h4uAulPRdlw6Jl6s1oG8KrVilPN2yUITEs+K48EzMJJ3W1xy8K5eWuFvjp3R74AOIGSmp2UfBJ8HFw==", + "dev": true, + "requires": { + "@types/express-serve-static-core": "*", + "@types/node": "*" + } + }, + "@types/eslint": { + "version": "8.56.0", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.0.tgz", + "integrity": "sha512-FlsN0p4FhuYRjIxpbdXovvHQhtlG05O1GG/RNWvdAxTboR438IOTwmrY/vLA+Xfgg06BTkP045M3vpFwTMv1dg==", + "dev": true, + "requires": { + "@types/estree": "*", + "@types/json-schema": "*" + } + }, + "@types/eslint-scope": { + "version": "3.7.7", + "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz", + "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==", + "dev": true, + "requires": { + "@types/eslint": "*", + "@types/estree": "*" + } + }, + "@types/estree": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", + "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", + "dev": true + }, + "@types/express": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz", + "integrity": "sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==", + "dev": true, + "requires": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "^4.17.33", + "@types/qs": "*", + "@types/serve-static": "*" + } + }, + "@types/express-serve-static-core": { + "version": "4.17.41", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.41.tgz", + "integrity": "sha512-OaJ7XLaelTgrvlZD8/aa0vvvxZdUmlCn6MtWeB7TkiKW70BQLc9XEPpDLPdbo52ZhXUCrznlWdCHWxJWtdyajA==", + "dev": true, + "requires": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*", + "@types/send": "*" + } + }, + "@types/http-errors": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz", + "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==", + "dev": true + }, + "@types/http-proxy": { + "version": "1.17.14", + "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.14.tgz", + "integrity": "sha512-SSrD0c1OQzlFX7pGu1eXxSEjemej64aaNPRhhVYUGqXh0BtldAAx37MG8btcumvpgKyZp1F5Gn3JkktdxiFv6w==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true + }, + "@types/mime": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", + "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==", + "dev": true + }, + "@types/minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-hov8bUuiLiyFPGyFPE1lwWhmzYbirOXQNNo40+y3zow8aFVTeyn3VWL0VFFfdNddA8S4Vf0Tc062rzyNr7Paag==", + "dev": true + }, + "@types/node": { + "version": "20.10.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.10.5.tgz", + "integrity": "sha512-nNPsNE65wjMxEKI93yOP+NPGGBJz/PoN3kZsVLee0XMiJolxSekEVD8wRwBUBqkwc7UWop0edW50yrCQW4CyRw==", + "dev": true, + "requires": { + "undici-types": "~5.26.4" + } + }, + "@types/node-forge": { + "version": "1.3.10", + "resolved": "https://registry.npmjs.org/@types/node-forge/-/node-forge-1.3.10.tgz", + "integrity": "sha512-y6PJDYN4xYBxwd22l+OVH35N+1fCYWiuC3aiP2SlXVE6Lo7SS+rSx9r89hLxrP4pn6n1lBGhHJ12pj3F3Mpttw==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/normalize-package-data": { + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.4.tgz", + "integrity": "sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==", + "dev": true + }, + "@types/qs": { + "version": "6.9.10", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.10.tgz", + "integrity": "sha512-3Gnx08Ns1sEoCrWssEgTSJs/rsT2vhGP+Ja9cnnk9k4ALxinORlQneLXFeFKOTJMOeZUFD1s7w+w2AphTpvzZw==", + "dev": true + }, + "@types/range-parser": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", + "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==", + "dev": true + }, + "@types/retry": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.0.tgz", + "integrity": "sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==", + "dev": true + }, + "@types/send": { + "version": "0.17.4", + "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz", + "integrity": "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==", + "dev": true, + "requires": { + "@types/mime": "^1", + "@types/node": "*" + } + }, + "@types/serve-index": { + "version": "1.9.4", + "resolved": "https://registry.npmjs.org/@types/serve-index/-/serve-index-1.9.4.tgz", + "integrity": "sha512-qLpGZ/c2fhSs5gnYsQxtDEq3Oy8SXPClIXkW5ghvAvsNuVSA8k+gCONcUCS/UjLEYvYps+e8uBtfgXgvhwfNug==", + "dev": true, + "requires": { + "@types/express": "*" + } + }, + "@types/serve-static": { + "version": "1.15.5", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.5.tgz", + "integrity": "sha512-PDRk21MnK70hja/YF8AHfC7yIsiQHn1rcXx7ijCFBX/k+XQJhQT/gw3xekXKJvx+5SXaMMS8oqQy09Mzvz2TuQ==", + "dev": true, + "requires": { + "@types/http-errors": "*", + "@types/mime": "*", + "@types/node": "*" + } + }, + "@types/sockjs": { + "version": "0.3.36", + "resolved": "https://registry.npmjs.org/@types/sockjs/-/sockjs-0.3.36.tgz", + "integrity": "sha512-MK9V6NzAS1+Ud7JV9lJLFqW85VbC9dq3LmwZCuBe4wBDgKC0Kj/jd8Xl+nSviU+Qc3+m7umHHyHg//2KSa0a0Q==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/ws": { + "version": "8.5.10", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.10.tgz", + "integrity": "sha512-vmQSUcfalpIq0R9q7uTo2lXs6eGIpt9wtnLdMv9LVpIjCA/+ufZRozlVoVelIYixx1ugCBKDhn89vnsEGOCx9A==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@webassemblyjs/ast": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.6.tgz", + "integrity": "sha512-IN1xI7PwOvLPgjcf180gC1bqn3q/QaOCwYUahIOhbYUu8KA/3tw2RT/T0Gidi1l7Hhj5D/INhJxiICObqpMu4Q==", + "dev": true, + "requires": { + "@webassemblyjs/helper-numbers": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6" + } + }, + "@webassemblyjs/floating-point-hex-parser": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz", + "integrity": "sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==", + "dev": true + }, + "@webassemblyjs/helper-api-error": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz", + "integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==", + "dev": true + }, + "@webassemblyjs/helper-buffer": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.6.tgz", + "integrity": "sha512-z3nFzdcp1mb8nEOFFk8DrYLpHvhKC3grJD2ardfKOzmbmJvEf/tPIqCY+sNcwZIY8ZD7IkB2l7/pqhUhqm7hLA==", + "dev": true + }, + "@webassemblyjs/helper-numbers": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz", + "integrity": "sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==", + "dev": true, + "requires": { + "@webassemblyjs/floating-point-hex-parser": "1.11.6", + "@webassemblyjs/helper-api-error": "1.11.6", + "@xtuc/long": "4.2.2" + } + }, + "@webassemblyjs/helper-wasm-bytecode": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz", + "integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==", + "dev": true + }, + "@webassemblyjs/helper-wasm-section": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.6.tgz", + "integrity": "sha512-LPpZbSOwTpEC2cgn4hTydySy1Ke+XEu+ETXuoyvuyezHO3Kjdu90KK95Sh9xTbmjrCsUwvWwCOQQNta37VrS9g==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-buffer": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/wasm-gen": "1.11.6" + } + }, + "@webassemblyjs/ieee754": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz", + "integrity": "sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==", + "dev": true, + "requires": { + "@xtuc/ieee754": "^1.2.0" + } + }, + "@webassemblyjs/leb128": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.6.tgz", + "integrity": "sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==", + "dev": true, + "requires": { + "@xtuc/long": "4.2.2" + } + }, + "@webassemblyjs/utf8": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.6.tgz", + "integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==", + "dev": true + }, + "@webassemblyjs/wasm-edit": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.6.tgz", + "integrity": "sha512-Ybn2I6fnfIGuCR+Faaz7YcvtBKxvoLV3Lebn1tM4o/IAJzmi9AWYIPWpyBfU8cC+JxAO57bk4+zdsTjJR+VTOw==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-buffer": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/helper-wasm-section": "1.11.6", + "@webassemblyjs/wasm-gen": "1.11.6", + "@webassemblyjs/wasm-opt": "1.11.6", + "@webassemblyjs/wasm-parser": "1.11.6", + "@webassemblyjs/wast-printer": "1.11.6" + } + }, + "@webassemblyjs/wasm-gen": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.6.tgz", + "integrity": "sha512-3XOqkZP/y6B4F0PBAXvI1/bky7GryoogUtfwExeP/v7Nzwo1QLcq5oQmpKlftZLbT+ERUOAZVQjuNVak6UXjPA==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/ieee754": "1.11.6", + "@webassemblyjs/leb128": "1.11.6", + "@webassemblyjs/utf8": "1.11.6" + } + }, + "@webassemblyjs/wasm-opt": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.6.tgz", + "integrity": "sha512-cOrKuLRE7PCe6AsOVl7WasYf3wbSo4CeOk6PkrjS7g57MFfVUF9u6ysQBBODX0LdgSvQqRiGz3CXvIDKcPNy4g==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-buffer": "1.11.6", + "@webassemblyjs/wasm-gen": "1.11.6", + "@webassemblyjs/wasm-parser": "1.11.6" + } + }, + "@webassemblyjs/wasm-parser": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.6.tgz", + "integrity": "sha512-6ZwPeGzMJM3Dqp3hCsLgESxBGtT/OeCvCZ4TA1JUPYgmhAx38tTPR9JaKy0S5H3evQpO/h2uWs2j6Yc/fjkpTQ==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-api-error": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/ieee754": "1.11.6", + "@webassemblyjs/leb128": "1.11.6", + "@webassemblyjs/utf8": "1.11.6" + } + }, + "@webassemblyjs/wast-printer": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.6.tgz", + "integrity": "sha512-JM7AhRcE+yW2GWYaKeHL5vt4xqee5N2WcezptmgyhNS+ScggqcT1OtXykhAb13Sn5Yas0j2uv9tHgrjwvzAP4A==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.11.6", + "@xtuc/long": "4.2.2" + } + }, + "@webpack-cli/configtest": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-1.2.0.tgz", + "integrity": "sha512-4FB8Tj6xyVkyqjj1OaTqCjXYULB9FMkqQ8yGrZjRDrYh0nOE+7Lhs45WioWQQMV+ceFlE368Ukhe6xdvJM9Egg==", + "dev": true, + "requires": {} + }, + "@webpack-cli/info": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-1.5.0.tgz", + "integrity": "sha512-e8tSXZpw2hPl2uMJY6fsMswaok5FdlGNRTktvFk2sD8RjH0hE2+XistawJx1vmKteh4NmGmNUrp+Tb2w+udPcQ==", + "dev": true, + "requires": { + "envinfo": "^7.7.3" + } + }, + "@webpack-cli/serve": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-1.7.0.tgz", + "integrity": "sha512-oxnCNGj88fL+xzV+dacXs44HcDwf1ovs3AuEzvP7mqXw7fQntqIhQ1BRmynh4qEKQSSSRSWVyXRjmTbZIX9V2Q==", + "dev": true, + "requires": {} + }, + "@xtuc/ieee754": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", + "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", + "dev": true + }, + "@xtuc/long": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", + "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", + "dev": true + }, + "abab": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz", + "integrity": "sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==", + "dev": true + }, + "accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "dev": true, + "requires": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + } + }, + "acorn": { + "version": "8.11.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.2.tgz", + "integrity": "sha512-nc0Axzp/0FILLEVsm4fNwLCwMttvhEI263QtVPQcbpfZZ3ts0hLsZGOpE6czNlid7CJ9MlyH8reXkpsf3YUY4w==", + "dev": true + }, + "acorn-import-assertions": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz", + "integrity": "sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==", + "dev": true, + "requires": {} + }, + "acorn-jsx": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz", + "integrity": "sha512-AU7pnZkguthwBjKgCg6998ByQNIMjbuDQZ8bb78QAFZwPfmKia8AIzgY/gWgqCjnht8JLdXmB4YxA0KaV60ncQ==", + "dev": true, + "requires": { + "acorn": "^3.0.4" + }, + "dependencies": { + "acorn": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz", + "integrity": "sha512-OLUyIIZ7mF5oaAUT1w0TFqQS81q3saT46x8t7ukpPjMNk+nbs4ZHhs7ToV8EWnLYLepjETXd4XaCE4uxkMeqUw==", + "dev": true + } + } + }, + "acorn-walk": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.2.tgz", + "integrity": "sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==", + "dev": true + }, + "agent-base": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz", + "integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==", + "requires": { + "debug": "^4.3.4" + } + }, + "aggregate-error": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-5.0.0.tgz", + "integrity": "sha512-gOsf2YwSlleG6IjRYG2A7k0HmBMEo6qVNk9Bp/EaLgAJT5ngH6PXbqa4ItvnEwCm/velL5jAnQgsHsWnjhGmvw==", + "dev": true, + "requires": { + "clean-stack": "^5.2.0", + "indent-string": "^5.0.0" + }, + "dependencies": { + "indent-string": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-5.0.0.tgz", + "integrity": "sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==", + "dev": true + } + } + }, + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ajv-formats": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", + "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", + "dev": true, + "requires": { + "ajv": "^8.0.0" + }, + "dependencies": { + "ajv": { + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", + "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + } + }, + "json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true + } + } + }, + "ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "dev": true, + "requires": {} + }, + "ansi-escapes": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz", + "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==", + "dev": true + }, + "ansi-html-community": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/ansi-html-community/-/ansi-html-community-0.0.8.tgz", + "integrity": "sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw==", + "dev": true + }, + "ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "ansicolors": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/ansicolors/-/ansicolors-0.3.2.tgz", + "integrity": "sha512-QXu7BPrP29VllRxH8GwB7x5iX5qWKAAMLqKQGWTeLWVlNHNOpVMJ91dsxQAIWXpjuW5wqvxu3Jd/nRjrJ+0pqg==", + "dev": true + }, + "anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, + "arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "dev": true + }, + "argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "argv-formatter": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/argv-formatter/-/argv-formatter-1.0.0.tgz", + "integrity": "sha512-F2+Hkm9xFaRg+GkaNnbwXNDV5O6pnCFEmqyhvfC/Ic5LbgOWjJh3L+mN/s91rxVL3znE7DYVpW0GJFT+4YBgWw==", + "dev": true + }, + "array-flatten": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-2.1.2.tgz", + "integrity": "sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ==", + "dev": true + }, + "array-ify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array-ify/-/array-ify-1.0.0.tgz", + "integrity": "sha512-c5AMf34bKdvPhQ7tBGhqkgKNUzMr4WUs+WDtC2ZUGOUncbxKMTvqxYctiseW3+L4bA8ec+GcZ6/A/FW4m8ukng==", + "dev": true + }, + "array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true + }, + "arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==", + "dev": true + }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + }, + "babel-code-frame": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", + "integrity": "sha512-XqYMR2dfdGMW+hd0IUZ2PwK+fGeFkOxZJ0wY+JaQAHzt1Zx8LcvpiZD2NiGkEG8qx0CfkAOr5xt76d1e8vG90g==", + "dev": true, + "requires": { + "chalk": "^1.1.3", + "esutils": "^2.0.2", + "js-tokens": "^3.0.2" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", + "dev": true + }, + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha512-kmCevFghRiWM7HB5zTPULl4r9bVFSWjz62MhqizDGUrq2NWuNMQyuv4tHHoKJHs69M/MF64lEcHdYIocrdWQYA==", + "dev": true + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha512-U3lRVLMSlsCfjqYPbLyVv11M9CPW4I728d6TCKMAOJueEeB9/8o+eSsMnxPJD+Q+K909sdESg7C+tIkoH6on1A==", + "dev": true, + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "js-tokens": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", + "integrity": "sha512-RjTcuD4xjtthQkaWH7dFlH85L+QaVtSoOyGdZ3g6HFhS9dFNDfLyqgm2NFe2X6cQpeFmt0452FJjFG5UameExg==", + "dev": true + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha512-KKNVtd6pCYgPIKU4cp2733HWYCpplQhddZLBUryaAHou723x+FRzQ5Df824Fj+IyyuiQTRoub4SnIFfIcrp70g==", + "dev": true + } + } + }, + "balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "batch": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", + "integrity": "sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==", + "dev": true + }, + "before-after-hook": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.3.tgz", + "integrity": "sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ==", + "dev": true + }, + "binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "dev": true + }, + "blockly": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/blockly/-/blockly-11.0.0.tgz", + "integrity": "sha512-6Ie7HuZWZLaETIVKFEP4FPDz267Pubn6+weQNZvXzqnkOYp9sKPSsPue8QIMCV9Qb5F4wYhqivgiDcZJcE1UlQ==", + "requires": { + "jsdom": "23.0.0" + } + }, + "body-parser": { + "version": "1.20.1", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", + "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", + "dev": true, + "requires": { + "bytes": "3.1.2", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.11.0", + "raw-body": "2.5.1", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + }, + "dependencies": { + "bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "dev": true + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + } + } + }, + "bonjour-service": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/bonjour-service/-/bonjour-service-1.1.1.tgz", + "integrity": "sha512-Z/5lQRMOG9k7W+FkeGTNjh7htqn/2LMnfOvBZ8pynNZCM9MwkQkI3zeI4oz09uWdcgmgHugVvBqxGg4VQJ5PCg==", + "dev": true, + "requires": { + "array-flatten": "^2.1.2", + "dns-equal": "^1.0.0", + "fast-deep-equal": "^3.1.3", + "multicast-dns": "^7.2.5" + } + }, + "bottleneck": { + "version": "2.19.5", + "resolved": "https://registry.npmjs.org/bottleneck/-/bottleneck-2.19.5.tgz", + "integrity": "sha512-VHiNCbI1lKdl44tGrhNfU3lup0Tj/ZBMJB5/2ZbNXRCPuRCO7ed2mgcK4r17y+KB2EfuYuRaVlwNbAeaWGSpbw==", + "dev": true + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "requires": { + "fill-range": "^7.0.1" + } + }, + "browserslist": { + "version": "4.22.2", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.2.tgz", + "integrity": "sha512-0UgcrvQmBDvZHFGdYUehrCNIazki7/lUP3kkoi/r3YB2amZbFM9J43ZRkJTXBUZK4gmx56+Sqk9+Vs9mwZx9+A==", + "dev": true, + "requires": { + "caniuse-lite": "^1.0.30001565", + "electron-to-chromium": "^1.4.601", + "node-releases": "^2.0.14", + "update-browserslist-db": "^1.0.13" + } + }, + "buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true + }, + "bytes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", + "integrity": "sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==", + "dev": true + }, + "call-bind": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.5.tgz", + "integrity": "sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ==", + "dev": true, + "requires": { + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.1", + "set-function-length": "^1.1.1" + } + }, + "caller-path": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz", + "integrity": "sha512-UJiE1otjXPF5/x+T3zTnSFiTOEmJoGTD9HmBoxnCUwho61a2eSNn/VwtwuIBDAo2SEOv1AJ7ARI5gCmohFLu/g==", + "dev": true, + "requires": { + "callsites": "^0.2.0" + }, + "dependencies": { + "callsites": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz", + "integrity": "sha512-Zv4Dns9IbXXmPkgRRUjAaJQgfN4xX5p6+RQFhWUqscdvvK2xK/ZL8b3IXIJsj+4sD+f24NwnWy2BY8AJ82JB0A==", + "dev": true + } + } + }, + "callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true + }, + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true + }, + "camelcase-keys": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-6.2.2.tgz", + "integrity": "sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==", + "dev": true, + "requires": { + "camelcase": "^5.3.1", + "map-obj": "^4.0.0", + "quick-lru": "^4.0.1" + } + }, + "caniuse-lite": { + "version": "1.0.30001570", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001570.tgz", + "integrity": "sha512-+3e0ASu4sw1SWaoCtvPeyXp+5PsjigkSt8OXZbF9StH5pQWbxEjLAZE3n8Aup5udop1uRiKA7a4utUk/uoSpUw==", + "dev": true + }, + "cardinal": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/cardinal/-/cardinal-2.1.1.tgz", + "integrity": "sha512-JSr5eOgoEymtYHBjNWyjrMqet9Am2miJhlfKNdqLp6zoeAh0KN5dRAcxlecj5mAJrmQomgiOBj35xHLrFjqBpw==", + "dev": true, + "requires": { + "ansicolors": "~0.3.2", + "redeyed": "~2.1.0" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "dependencies": { + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "char-regex": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", + "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", + "dev": true + }, + "chardet": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.4.2.tgz", + "integrity": "sha512-j/Toj7f1z98Hh2cYo2BVr85EpIRWqUi7rtRSGxh/cqUjqrnJe9l9UE7IUGd2vQ2p+kSHLkSzObQPZPLUC6TQwg==", + "dev": true + }, + "chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "dev": true, + "requires": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "fsevents": "~2.3.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + } + }, + "chrome-trace-event": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", + "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==", + "dev": true + }, + "circular-json": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz", + "integrity": "sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A==", + "dev": true + }, + "clean-stack": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-5.2.0.tgz", + "integrity": "sha512-TyUIUJgdFnCISzG5zu3291TAsE77ddchd0bepon1VVQrKLGKFED4iXFEDQ24mIPdPBbyE16PK3F8MYE1CmcBEQ==", + "dev": true, + "requires": { + "escape-string-regexp": "5.0.0" + }, + "dependencies": { + "escape-string-regexp": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", + "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", + "dev": true + } + } + }, + "cli-cursor": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", + "integrity": "sha512-8lgKz8LmCRYZZQDpRyT2m5rKJ08TnU4tR9FFFW2rxpxR1FzWi4PQ/NfyODchAatHaUgnSPVcx/R5w6NuTBzFiw==", + "dev": true, + "requires": { + "restore-cursor": "^2.0.0" + } + }, + "cli-table3": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.5.tgz", + "integrity": "sha512-+W/5efTR7y5HRD7gACw9yQjqMVvEMLBHmboM/kPWam+H+Hmyrgjh6YncVKK122YZkXrLudzTuAukUw9FnMf7IQ==", + "dev": true, + "requires": { + "@colors/colors": "1.5.0", + "string-width": "^4.2.0" + } + }, + "cli-width": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.1.tgz", + "integrity": "sha512-GRMWDxpOB6Dgk2E5Uo+3eEBvtOOlimMmpbFiKuLFnQzYDavtLFY3K5ona41jgN/WdRZtG7utuVSVTL4HbZHGkw==", + "dev": true + }, + "cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dev": true, + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + } + }, + "clone-deep": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", + "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", + "dev": true, + "requires": { + "is-plain-object": "^2.0.4", + "kind-of": "^6.0.2", + "shallow-clone": "^3.0.0" + } + }, + "co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", + "dev": true + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "colorette": { + "version": "2.0.20", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", + "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", + "dev": true + }, + "combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "requires": { + "delayed-stream": "~1.0.0" + } + }, + "commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true + }, + "compare-func": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/compare-func/-/compare-func-2.0.0.tgz", + "integrity": "sha512-zHig5N+tPWARooBnb0Zx1MFcdfpyJrfTJ3Y5L+IFvUm8rM74hHz66z0gw0x4tijh5CorKkKUCnW82R2vmpeCRA==", + "dev": true, + "requires": { + "array-ify": "^1.0.0", + "dot-prop": "^5.1.0" + } + }, + "compressible": { + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", + "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", + "dev": true, + "requires": { + "mime-db": ">= 1.43.0 < 2" + } + }, + "compression": { + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz", + "integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==", + "dev": true, + "requires": { + "accepts": "~1.3.5", + "bytes": "3.0.0", + "compressible": "~2.0.16", + "debug": "2.6.9", + "on-headers": "~1.0.2", + "safe-buffer": "5.1.2", + "vary": "~1.1.2" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + } + } + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true + }, + "concat-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", + "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + }, + "dependencies": { + "readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, + "config-chain": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.13.tgz", + "integrity": "sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==", + "dev": true, + "requires": { + "ini": "^1.3.4", + "proto-list": "~1.2.1" + } + }, + "connect-history-api-fallback": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-2.0.0.tgz", + "integrity": "sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA==", + "dev": true + }, + "content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "dev": true, + "requires": { + "safe-buffer": "5.2.1" + } + }, + "content-type": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "dev": true + }, + "conventional-changelog-angular": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-6.0.0.tgz", + "integrity": "sha512-6qLgrBF4gueoC7AFVHu51nHL9pF9FRjXrH+ceVf7WmAfH3gs+gEYOkvxhjMPjZu57I4AGUGoNTY8V7Hrgf1uqg==", + "dev": true, + "requires": { + "compare-func": "^2.0.0" + } + }, + "conventional-changelog-conventionalcommits": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/conventional-changelog-conventionalcommits/-/conventional-changelog-conventionalcommits-6.1.0.tgz", + "integrity": "sha512-3cS3GEtR78zTfMzk0AizXKKIdN4OvSh7ibNz6/DPbhWWQu7LqE/8+/GqSodV+sywUR2gpJAdP/1JFf4XtN7Zpw==", + "dev": true, + "requires": { + "compare-func": "^2.0.0" + } + }, + "conventional-changelog-writer": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/conventional-changelog-writer/-/conventional-changelog-writer-7.0.1.tgz", + "integrity": "sha512-Uo+R9neH3r/foIvQ0MKcsXkX642hdm9odUp7TqgFS7BsalTcjzRlIfWZrZR1gbxOozKucaKt5KAbjW8J8xRSmA==", + "dev": true, + "requires": { + "conventional-commits-filter": "^4.0.0", + "handlebars": "^4.7.7", + "json-stringify-safe": "^5.0.1", + "meow": "^12.0.1", + "semver": "^7.5.2", + "split2": "^4.0.0" + }, + "dependencies": { + "meow": { + "version": "12.1.1", + "resolved": "https://registry.npmjs.org/meow/-/meow-12.1.1.tgz", + "integrity": "sha512-BhXM0Au22RwUneMPwSCnyhTOizdWoIEPU9sp0Aqa1PnDMR5Wv2FGXYDjuzJEIX+Eo2Rb8xuYe5jrnm5QowQFkw==", + "dev": true + }, + "split2": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", + "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==", + "dev": true + } + } + }, + "conventional-commits-filter": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/conventional-commits-filter/-/conventional-commits-filter-4.0.0.tgz", + "integrity": "sha512-rnpnibcSOdFcdclpFwWa+pPlZJhXE7l+XK04zxhbWrhgpR96h33QLz8hITTXbcYICxVr3HZFtbtUAQ+4LdBo9A==", + "dev": true + }, + "conventional-commits-parser": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-4.0.0.tgz", + "integrity": "sha512-WRv5j1FsVM5FISJkoYMR6tPk07fkKT0UodruX4je86V4owk451yjXAKzKAPOs9l7y59E2viHUS9eQ+dfUA9NSg==", + "dev": true, + "requires": { + "is-text-path": "^1.0.1", + "JSONStream": "^1.3.5", + "meow": "^8.1.2", + "split2": "^3.2.2" + } + }, + "cookie": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", + "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", + "dev": true + }, + "cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", + "dev": true + }, + "core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", + "dev": true + }, + "cosmiconfig": { + "version": "8.3.6", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.3.6.tgz", + "integrity": "sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==", + "dev": true, + "requires": { + "import-fresh": "^3.3.0", + "js-yaml": "^4.1.0", + "parse-json": "^5.2.0", + "path-type": "^4.0.0" + } + }, + "cosmiconfig-typescript-loader": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/cosmiconfig-typescript-loader/-/cosmiconfig-typescript-loader-4.4.0.tgz", + "integrity": "sha512-BabizFdC3wBHhbI4kJh0VkQP9GkBfoHPydD0COMce1nJ1kJAB3F2TmJ/I7diULBKtmEWSwEbuN/KDtgnmUUVmw==", + "dev": true, + "requires": {} + }, + "create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", + "dev": true + }, + "cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } + }, + "crypto-random-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-4.0.0.tgz", + "integrity": "sha512-x8dy3RnvYdlUcPOjkEHqozhiwzKNSq7GcPuXFbnyMOCHxX8V3OgIg/pYuabl2sbUPfIJaeAQB7PMOK8DFIdoRA==", + "dev": true, + "requires": { + "type-fest": "^1.0.1" + }, + "dependencies": { + "type-fest": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-1.4.0.tgz", + "integrity": "sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==", + "dev": true + } + } + }, + "cssstyle": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-3.0.0.tgz", + "integrity": "sha512-N4u2ABATi3Qplzf0hWbVCdjenim8F3ojEXpBDF5hBpjzW182MjNGLqfmQ0SkSPeQ+V86ZXgeH8aXj6kayd4jgg==", + "requires": { + "rrweb-cssom": "^0.6.0" + } + }, + "dargs": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/dargs/-/dargs-7.0.0.tgz", + "integrity": "sha512-2iy1EkLdlBzQGvbweYRFxmFath8+K7+AKB0TlhHWkNuH+TmovaMH/Wp7V7R4u7f4SnX3OgLsU9t1NI9ioDnUpg==", + "dev": true + }, + "data-urls": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-5.0.0.tgz", + "integrity": "sha512-ZYP5VBHshaDAiVZxjbRVcFJpc+4xGgT0bK3vzy1HLN8jTO975HEbuYzZJcHoQEY5K1a0z8YayJkyVETa08eNTg==", + "requires": { + "whatwg-mimetype": "^4.0.0", + "whatwg-url": "^14.0.0" + } + }, + "dateformat": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-3.0.3.tgz", + "integrity": "sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q==", + "dev": true + }, + "debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "requires": { + "ms": "2.1.2" + } + }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", + "dev": true + }, + "decamelize-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.1.tgz", + "integrity": "sha512-WiPxgEirIV0/eIOMcnFBA3/IJZAZqKnwAwWyvvdi4lsr1WCN22nhdf/3db3DoZcUjTV2SqfzIwNyp6y2xs3nmg==", + "dev": true, + "requires": { + "decamelize": "^1.1.0", + "map-obj": "^1.0.0" + }, + "dependencies": { + "map-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", + "integrity": "sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==", + "dev": true + } + } + }, + "decimal.js": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.3.tgz", + "integrity": "sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==" + }, + "deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "dev": true + }, + "deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true + }, + "default-gateway": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-6.0.3.tgz", + "integrity": "sha512-fwSOJsbbNzZ/CUFpqFBqYfYNLj1NbMPm8MMCIzHjC83iSJRBEGmDUxU+WP661BaBQImeC2yHwXtz+P/O9o+XEg==", + "dev": true, + "requires": { + "execa": "^5.0.0" + } + }, + "define-data-property": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.1.tgz", + "integrity": "sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==", + "dev": true, + "requires": { + "get-intrinsic": "^1.2.1", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.0" + } + }, + "define-lazy-prop": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", + "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==", + "dev": true + }, + "del": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/del/-/del-6.1.1.tgz", + "integrity": "sha512-ua8BhapfP0JUJKC/zV9yHHDW/rDoDxP4Zhn3AkA6/xT6gY7jYXJiaeyBZznYVujhZZET+UgcbZiQ7sN3WqcImg==", + "dev": true, + "requires": { + "globby": "^11.0.1", + "graceful-fs": "^4.2.4", + "is-glob": "^4.0.1", + "is-path-cwd": "^2.2.0", + "is-path-inside": "^3.0.2", + "p-map": "^4.0.0", + "rimraf": "^3.0.2", + "slash": "^3.0.0" + }, + "dependencies": { + "aggregate-error": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", + "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", + "dev": true, + "requires": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + } + }, + "clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "dev": true + }, + "globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dev": true, + "requires": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + } + }, + "ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "dev": true + }, + "p-map": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", + "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", + "dev": true, + "requires": { + "aggregate-error": "^3.0.0" + } + }, + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true + } + } + }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==" + }, + "depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "dev": true + }, + "deprecation": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz", + "integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==", + "dev": true + }, + "destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "dev": true + }, + "detect-node": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", + "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==", + "dev": true + }, + "diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true + }, + "dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "requires": { + "path-type": "^4.0.0" + } + }, + "dns-equal": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/dns-equal/-/dns-equal-1.0.0.tgz", + "integrity": "sha512-z+paD6YUQsk+AbGCEM4PrOXSss5gd66QfcVBFTKR/HpFL9jCqikS94HYwKww6fQyO7IxrIIyUu+g0Ka9tUS2Cg==", + "dev": true + }, + "dns-packet": { + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-5.6.1.tgz", + "integrity": "sha512-l4gcSouhcgIKRvyy99RNVOgxXiicE+2jZoNmaNmZ6JXiGajBOJAesk1OBlJuM5k2c+eudGdLxDqXuPCKIj6kpw==", + "dev": true, + "requires": { + "@leichtgewicht/ip-codec": "^2.0.1" + } + }, + "doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "requires": { + "esutils": "^2.0.2" + } + }, + "dot-prop": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", + "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==", + "dev": true, + "requires": { + "is-obj": "^2.0.0" + } + }, + "duplexer2": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz", + "integrity": "sha512-asLFVfWWtJ90ZyOUHMqk7/S2w2guQKxUI2itj3d92ADHhxUSbCMGi1f1cBcJ7xM1To+pE/Khbwo1yuNbMEPKeA==", + "dev": true, + "requires": { + "readable-stream": "^2.0.2" + }, + "dependencies": { + "readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, + "ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", + "dev": true + }, + "electron-to-chromium": { + "version": "1.4.615", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.615.tgz", + "integrity": "sha512-/bKPPcgZVUziECqDc+0HkT87+0zhaWSZHNXqF8FLd2lQcptpmUFwoCSWjCdOng9Gdq+afKArPdEg/0ZW461Eng==", + "dev": true + }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "emojilib": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/emojilib/-/emojilib-2.4.0.tgz", + "integrity": "sha512-5U0rVMU5Y2n2+ykNLQqMoqklN9ICBT/KsvC1Gz6vqHbz2AXXGkG+Pm5rMWk/8Vjrr/mY9985Hi8DYzn1F09Nyw==", + "dev": true + }, + "encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "dev": true + }, + "enhanced-resolve": { + "version": "5.15.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.15.0.tgz", + "integrity": "sha512-LXYT42KJ7lpIKECr2mAXIaMldcNCh/7E0KBKOu4KSfkHmP+mZmSs+8V5gBAqisWBy0OO4W5Oyys0GO1Y8KtdKg==", + "dev": true, + "requires": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + } + }, + "entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==" + }, + "env-ci": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/env-ci/-/env-ci-10.0.0.tgz", + "integrity": "sha512-U4xcd/utDYFgMh0yWj07R1H6L5fwhVbmxBCpnL0DbVSDZVnsC82HONw0wxtxNkIAcua3KtbomQvIk5xFZGAQJw==", + "dev": true, + "requires": { + "execa": "^8.0.0", + "java-properties": "^1.0.2" + }, + "dependencies": { + "execa": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", + "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==", + "dev": true, + "requires": { + "cross-spawn": "^7.0.3", + "get-stream": "^8.0.1", + "human-signals": "^5.0.0", + "is-stream": "^3.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^5.1.0", + "onetime": "^6.0.0", + "signal-exit": "^4.1.0", + "strip-final-newline": "^3.0.0" + } + }, + "get-stream": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", + "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==", + "dev": true + }, + "human-signals": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz", + "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==", + "dev": true + }, + "is-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", + "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", + "dev": true + }, + "mimic-fn": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", + "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", + "dev": true + }, + "npm-run-path": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.3.0.tgz", + "integrity": "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==", + "dev": true, + "requires": { + "path-key": "^4.0.0" + } + }, + "onetime": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", + "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", + "dev": true, + "requires": { + "mimic-fn": "^4.0.0" + } + }, + "path-key": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", + "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", + "dev": true + }, + "signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true + }, + "strip-final-newline": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", + "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", + "dev": true + } + } + }, + "envinfo": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.11.0.tgz", + "integrity": "sha512-G9/6xF1FPbIw0TtalAMaVPpiq2aDEuKLXM314jPVAO9r2fo2a4BLqMNkmRS7O/xPPZ+COAhGIz3ETvHEV3eUcg==", + "dev": true + }, + "error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "requires": { + "is-arrayish": "^0.2.1" + } + }, + "es-module-lexer": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.4.1.tgz", + "integrity": "sha512-cXLGjP0c4T3flZJKQSuziYoq7MlT+rnvfZjfp7h+I7K9BNX54kP9nyWvdbwjQ4u1iWbOL4u96fgeZLToQlZC7w==", + "dev": true + }, + "escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true + }, + "escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", + "dev": true + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true + }, + "eslint": { + "version": "4.19.1", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-4.19.1.tgz", + "integrity": "sha512-bT3/1x1EbZB7phzYu7vCr1v3ONuzDtX8WjuM9c0iYxe+cq+pwcKEoQjl7zd3RpC6YOLgnSy3cTN58M2jcoPDIQ==", + "dev": true, + "requires": { + "ajv": "^5.3.0", + "babel-code-frame": "^6.22.0", + "chalk": "^2.1.0", + "concat-stream": "^1.6.0", + "cross-spawn": "^5.1.0", + "debug": "^3.1.0", + "doctrine": "^2.1.0", + "eslint-scope": "^3.7.1", + "eslint-visitor-keys": "^1.0.0", + "espree": "^3.5.4", + "esquery": "^1.0.0", + "esutils": "^2.0.2", + "file-entry-cache": "^2.0.0", + "functional-red-black-tree": "^1.0.1", + "glob": "^7.1.2", + "globals": "^11.0.1", + "ignore": "^3.3.3", + "imurmurhash": "^0.1.4", + "inquirer": "^3.0.6", + "is-resolvable": "^1.0.0", + "js-yaml": "^3.9.1", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.3.0", + "lodash": "^4.17.4", + "minimatch": "^3.0.2", + "mkdirp": "^0.5.1", + "natural-compare": "^1.4.0", + "optionator": "^0.8.2", + "path-is-inside": "^1.0.2", + "pluralize": "^7.0.0", + "progress": "^2.0.0", + "regexpp": "^1.0.1", + "require-uncached": "^1.0.3", + "semver": "^5.3.0", + "strip-ansi": "^4.0.0", + "strip-json-comments": "~2.0.1", + "table": "4.0.2", + "text-table": "~0.2.0" + }, + "dependencies": { + "ajv": { + "version": "5.5.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz", + "integrity": "sha512-Ajr4IcMXq/2QmMkEmSvxqfLN5zGmJ92gHXAeOXq1OekoH2rfDNsgdDoL2f7QaRCy7G/E6TpxBVdRuNraMztGHw==", + "dev": true, + "requires": { + "co": "^4.6.0", + "fast-deep-equal": "^1.0.0", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.3.0" + } + }, + "ansi-regex": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz", + "integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==", + "dev": true + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "cross-spawn": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", + "integrity": "sha512-pTgQJ5KC0d2hcY8eyL1IzlBPYjTkyH72XRZPnLyKus2mBfNjQs3klqbJU2VILqZryAZUt9JOb3h/mWMy23/f5A==", + "dev": true, + "requires": { + "lru-cache": "^4.0.1", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "eslint-scope": { + "version": "3.7.3", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-3.7.3.tgz", + "integrity": "sha512-W+B0SvF4gamyCTmUc+uITPY0989iXVfKvhwtmJocTaYoc/3khEHmEmvfY/Gn9HA9VV75jrQECsHizkNw1b68FA==", + "dev": true, + "requires": { + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" + } + }, + "fast-deep-equal": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz", + "integrity": "sha512-fueX787WZKCV0Is4/T2cyAdM4+x1S3MXXOAhavE1ys/W42SHAPacLTQhucja22QBYrfGw50M2sRiXPtTGv9Ymw==", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true + }, + "js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "json-schema-traverse": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz", + "integrity": "sha512-4JD/Ivzg7PoW8NzdrBSr3UFwC9mHgvI7Z6z3QGBsSHgKaRTUDmyZAAKJo2UbG1kUVfS9WS8bi36N49U1xw43DA==", + "dev": true + }, + "lru-cache": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", + "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", + "dev": true, + "requires": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + }, + "semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true + }, + "shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==", + "dev": true, + "requires": { + "shebang-regex": "^1.0.0" + } + }, + "shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==", + "dev": true + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==", + "dev": true + } + } + }, + "eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, + "requires": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + } + }, + "eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true + }, + "espree": { + "version": "3.5.4", + "resolved": "https://registry.npmjs.org/espree/-/espree-3.5.4.tgz", + "integrity": "sha512-yAcIQxtmMiB/jL32dzEp2enBeidsB7xWPLNiw3IIkpVds1P+h7qF9YwJq1yUNzp2OKXgAprs4F61ih66UsoD1A==", + "dev": true, + "requires": { + "acorn": "^5.5.0", + "acorn-jsx": "^3.0.0" + }, + "dependencies": { + "acorn": { + "version": "5.7.4", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.4.tgz", + "integrity": "sha512-1D++VG7BhrtvQpNbBzovKNc1FLGGEE/oGe7b9xJm/RFHMBeUaUGpluV9RLjZa47YFdPcDAenEYuq9pQPcMdLJg==", + "dev": true + } + } + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true + }, + "esquery": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", + "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", + "dev": true, + "requires": { + "estraverse": "^5.1.0" + }, + "dependencies": { + "estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true + } + } + }, + "esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "requires": { + "estraverse": "^5.2.0" + }, + "dependencies": { + "estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true + } + } + }, + "estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true + }, + "esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true + }, + "etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "dev": true + }, + "eventemitter3": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", + "dev": true + }, + "events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "dev": true + }, + "execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "dev": true, + "requires": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + } + }, + "express": { + "version": "4.18.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", + "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", + "dev": true, + "requires": { + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "1.20.1", + "content-disposition": "0.5.4", + "content-type": "~1.0.4", + "cookie": "0.5.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "2.0.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "1.2.0", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.7", + "qs": "6.11.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "0.18.0", + "serve-static": "1.15.0", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "dependencies": { + "array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", + "dev": true + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + } + } + }, + "external-editor": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-2.2.0.tgz", + "integrity": "sha512-bSn6gvGxKt+b7+6TKEv1ZycHleA7aHhRHyAqJyp5pbUFuYYNIzpZnQDk7AsYckyWdEnTeAnay0aCy2aV6iTk9A==", + "dev": true, + "requires": { + "chardet": "^0.4.0", + "iconv-lite": "^0.4.17", + "tmp": "^0.0.33" + }, + "dependencies": { + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + } + } + }, + "fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "fast-glob": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", + "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", + "dev": true, + "requires": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + } + }, + "fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true + }, + "fastest-levenshtein": { + "version": "1.0.16", + "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz", + "integrity": "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==", + "dev": true + }, + "fastq": { + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", + "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", + "dev": true, + "requires": { + "reusify": "^1.0.4" + } + }, + "faye-websocket": { + "version": "0.11.4", + "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz", + "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==", + "dev": true, + "requires": { + "websocket-driver": ">=0.5.1" + } + }, + "figures": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", + "integrity": "sha512-Oa2M9atig69ZkfwiApY8F2Yy+tzMbazyvqv21R0NsSC8floSOC09BbT1ITWAdoMGQvJ/aZnR1KMwdx9tvHnTNA==", + "dev": true, + "requires": { + "escape-string-regexp": "^1.0.5" + } + }, + "file-entry-cache": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-2.0.0.tgz", + "integrity": "sha512-uXP/zGzxxFvFfcZGgBIwotm+Tdc55ddPAzF7iHshP4YGaXMww7rSF9peD9D1sui5ebONg5UobsZv+FfgEpGv/w==", + "dev": true, + "requires": { + "flat-cache": "^1.2.1", + "object-assign": "^4.0.1" + } + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "finalhandler": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", + "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", + "dev": true, + "requires": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "statuses": "2.0.1", + "unpipe": "~1.0.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + } + } + }, + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "find-up-simple": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/find-up-simple/-/find-up-simple-1.0.0.tgz", + "integrity": "sha512-q7Us7kcjj2VMePAa02hDAF6d+MzsdsAWEwYyOpwUtlerRBkOEPBCRZrAV4XfcSN8fHAgaD0hP7miwoay6DCprw==", + "dev": true + }, + "find-versions": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/find-versions/-/find-versions-5.1.0.tgz", + "integrity": "sha512-+iwzCJ7C5v5KgcBuueqVoNiHVoQpwiUK5XFLjf0affFTep+Wcw93tPvmb8tqujDNmzhBDPddnWV/qgWSXgq+Hg==", + "dev": true, + "requires": { + "semver-regex": "^4.0.5" + } + }, + "flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "dev": true + }, + "flat-cache": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.3.4.tgz", + "integrity": "sha512-VwyB3Lkgacfik2vhqR4uv2rvebqmDvFu4jlN/C1RzWoJEo8I7z4Q404oiqYCkq41mni8EzQnm95emU9seckwtg==", + "dev": true, + "requires": { + "circular-json": "^0.3.1", + "graceful-fs": "^4.1.2", + "rimraf": "~2.6.2", + "write": "^0.2.1" + }, + "dependencies": { + "rimraf": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", + "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + } + } + }, + "follow-redirects": { + "version": "1.15.3", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.3.tgz", + "integrity": "sha512-1VzOtuEM8pC9SFU1E+8KfTjZyMztRsgEfwQl44z8A25uy13jSzTj6dyK2Df52iV0vgHCfBwLhDWevLn95w5v6Q==", + "dev": true + }, + "form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + } + }, + "forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "dev": true + }, + "fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "dev": true + }, + "from2": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", + "integrity": "sha512-OMcX/4IC/uqEPVgGeyfN22LJk6AZrMkRZHxcHBMBvHScDGgwTm2GT2Wkgtocyd3JfZffjj2kYUDXXII0Fk9W0g==", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "readable-stream": "^2.0.0" + }, + "dependencies": { + "readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, + "fs-extra": { + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz", + "integrity": "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==", + "dev": true, + "requires": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "dependencies": { + "universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "dev": true + } + } + }, + "fs-monkey": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.0.5.tgz", + "integrity": "sha512-8uMbBjrhzW76TYgEV27Y5E//W2f/lTFmx78P2w19FZSxarhI/798APGQyuGCwmkNxgwGRhrLfvWyLBvNtuOmew==", + "dev": true + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true + }, + "fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "optional": true + }, + "function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true + }, + "functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==", + "dev": true + }, + "get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true + }, + "get-intrinsic": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.2.tgz", + "integrity": "sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA==", + "dev": true, + "requires": { + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" + } + }, + "get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "dev": true + }, + "git-log-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/git-log-parser/-/git-log-parser-1.2.1.tgz", + "integrity": "sha512-PI+sPDvHXNPl5WNOErAK05s3j0lgwUzMN6o8cyQrDaKfT3qd7TmNJKeXX+SknI5I0QhG5fVPAEwSY4tRGDtYoQ==", + "dev": true, + "requires": { + "argv-formatter": "~1.0.0", + "spawn-error-forwarder": "~1.0.0", + "split2": "~1.0.0", + "stream-combiner2": "~1.1.1", + "through2": "~2.0.0", + "traverse": "0.6.8" + }, + "dependencies": { + "readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "split2": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/split2/-/split2-1.0.0.tgz", + "integrity": "sha512-NKywug4u4pX/AZBB1FCPzZ6/7O+Xhz1qMVbzTvvKvikjO99oPN87SkK08mEY9P63/5lWjK+wgOOgApnTg5r6qg==", + "dev": true, + "requires": { + "through2": "~2.0.0" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "through2": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", + "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "dev": true, + "requires": { + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" + } + } + } + }, + "git-raw-commits": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/git-raw-commits/-/git-raw-commits-2.0.11.tgz", + "integrity": "sha512-VnctFhw+xfj8Va1xtfEqCUD2XDrbAPSJx+hSrE5K7fGdjZruW7XV+QOrN7LF/RJyvspRiD2I0asWsxFp0ya26A==", + "dev": true, + "requires": { + "dargs": "^7.0.0", + "lodash": "^4.17.15", + "meow": "^8.0.0", + "split2": "^3.0.0", + "through2": "^4.0.0" + } + }, + "glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + }, + "glob-to-regexp": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", + "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", + "dev": true + }, + "global-dirs": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-0.1.1.tgz", + "integrity": "sha512-NknMLn7F2J7aflwFOlGdNIuCDpN3VGoSoB+aap3KABFWbHVn1TCgFC+np23J8W2BiZbjfEw3BFBycSMv1AFblg==", + "dev": true, + "requires": { + "ini": "^1.3.4" + } + }, + "globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true + }, + "globby": { + "version": "14.0.2", + "resolved": "https://registry.npmjs.org/globby/-/globby-14.0.2.tgz", + "integrity": "sha512-s3Fq41ZVh7vbbe2PN3nrW7yC7U7MFVc5c98/iTl9c2GawNMKx/J648KQRW6WKkuU8GIbbh2IXfIRQjOZnXcTnw==", + "dev": true, + "requires": { + "@sindresorhus/merge-streams": "^2.1.0", + "fast-glob": "^3.3.2", + "ignore": "^5.2.4", + "path-type": "^5.0.0", + "slash": "^5.1.0", + "unicorn-magic": "^0.1.0" + }, + "dependencies": { + "ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "dev": true + }, + "path-type": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-5.0.0.tgz", + "integrity": "sha512-5HviZNaZcfqP95rwpv+1HDgUamezbqdSYTyzjTvwtJSnIH+3vnbmWsItli8OFEndS984VT55M3jduxZbX351gg==", + "dev": true + } + } + }, + "gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "dev": true, + "requires": { + "get-intrinsic": "^1.1.3" + } + }, + "graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true + }, + "handle-thing": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz", + "integrity": "sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==", + "dev": true + }, + "handlebars": { + "version": "4.7.8", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.8.tgz", + "integrity": "sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==", + "dev": true, + "requires": { + "minimist": "^1.2.5", + "neo-async": "^2.6.2", + "source-map": "^0.6.1", + "uglify-js": "^3.1.4", + "wordwrap": "^1.0.0" + } + }, + "hard-rejection": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz", + "integrity": "sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==", + "dev": true + }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha512-C8vBJ8DwUCx19vhm7urhTuUsr4/IyP6l4VzNQDv+ryHQObW3TTTp9yB68WpYgRe2bbaGuZ/se74IqFeVnMnLZg==", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", + "dev": true + } + } + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "has-property-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz", + "integrity": "sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg==", + "dev": true, + "requires": { + "get-intrinsic": "^1.2.2" + } + }, + "has-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", + "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", + "dev": true + }, + "has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "dev": true + }, + "hasown": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz", + "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==", + "dev": true, + "requires": { + "function-bind": "^1.1.2" + } + }, + "hook-std": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/hook-std/-/hook-std-3.0.0.tgz", + "integrity": "sha512-jHRQzjSDzMtFy34AGj1DN+vq54WVuhSvKgrHf0OMiFQTwDD4L/qqofVEWjLOBMTn5+lCD3fPg32W9yOfnEJTTw==", + "dev": true + }, + "hosted-git-info": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz", + "integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + }, + "hpack.js": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz", + "integrity": "sha512-zJxVehUdMGIKsRaNt7apO2Gqp0BdqW5yaiGHXXmbpvxgBYVZnAql+BJb4RO5ad2MgpbZKn5G6nMnegrH1FcNYQ==", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "obuf": "^1.0.0", + "readable-stream": "^2.0.1", + "wbuf": "^1.1.0" + }, + "dependencies": { + "readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, + "html-encoding-sniffer": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-4.0.0.tgz", + "integrity": "sha512-Y22oTqIU4uuPgEemfz7NDJz6OeKf12Lsu+QC+s3BVpda64lTiMYCyGwg5ki4vFxkMwQdeZDl2adZoqUgdFuTgQ==", + "requires": { + "whatwg-encoding": "^3.1.1" + } + }, + "html-entities": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.4.0.tgz", + "integrity": "sha512-igBTJcNNNhvZFRtm8uA6xMY6xYleeDwn3PeBCkDz7tHttv4F2hsDI2aPgNERWzvRcNYHNT3ymRaQzllmXj4YsQ==", + "dev": true + }, + "http-deceiver": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz", + "integrity": "sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw==", + "dev": true + }, + "http-errors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "dev": true, + "requires": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + } + }, + "http-parser-js": { + "version": "0.5.8", + "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.8.tgz", + "integrity": "sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q==", + "dev": true + }, + "http-proxy": { + "version": "1.18.1", + "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", + "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", + "dev": true, + "requires": { + "eventemitter3": "^4.0.0", + "follow-redirects": "^1.0.0", + "requires-port": "^1.0.0" + } + }, + "http-proxy-agent": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", + "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", + "requires": { + "agent-base": "^7.1.0", + "debug": "^4.3.4" + } + }, + "http-proxy-middleware": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.6.tgz", + "integrity": "sha512-ya/UeJ6HVBYxrgYotAZo1KvPWlgB48kUJLDePFeneHsVujFaW5WNj2NgWCAE//B1Dl02BIfYlpNgBy8Kf8Rjmw==", + "dev": true, + "requires": { + "@types/http-proxy": "^1.17.8", + "http-proxy": "^1.18.1", + "is-glob": "^4.0.1", + "is-plain-obj": "^3.0.0", + "micromatch": "^4.0.2" + } + }, + "https-proxy-agent": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.4.tgz", + "integrity": "sha512-wlwpilI7YdjSkWaQ/7omYBMTliDcmCN8OLihO6I9B86g06lMyAoqgoDpV0XqoaPOKj+0DIdAvnsWfyAAhmimcg==", + "requires": { + "agent-base": "^7.0.2", + "debug": "4" + } + }, + "human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "dev": true + }, + "husky": { + "version": "9.1.6", + "resolved": "https://registry.npmjs.org/husky/-/husky-9.1.6.tgz", + "integrity": "sha512-sqbjZKK7kf44hfdE94EoX8MZNk0n7HeW37O4YrVGCF4wzgQjp+akPAkfUK5LZ6KuR/6sqeAVuXHji+RzQgOn5A==", + "dev": true + }, + "iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "requires": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + } + }, + "ignore": { + "version": "3.3.10", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.10.tgz", + "integrity": "sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug==", + "dev": true + }, + "import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "requires": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "dependencies": { + "resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true + } + } + }, + "import-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/import-from/-/import-from-4.0.0.tgz", + "integrity": "sha512-P9J71vT5nLlDeV8FHs5nNxaLbrpfAV5cF5srvbZfpwpcJoM/xZR3hiv+q+SAnuSmuGbXMWud063iIMx/V/EWZQ==", + "dev": true + }, + "import-from-esm": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/import-from-esm/-/import-from-esm-1.3.4.tgz", + "integrity": "sha512-7EyUlPFC0HOlBDpUFGfYstsU7XHxZJKAAMzCT8wZ0hMW7b+hG51LIKTDcsgtz8Pu6YC0HqRVbX+rVUtsGMUKvg==", + "dev": true, + "requires": { + "debug": "^4.3.4", + "import-meta-resolve": "^4.0.0" + } + }, + "import-local": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", + "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==", + "dev": true, + "requires": { + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.0.0" + } + }, + "import-meta-resolve": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/import-meta-resolve/-/import-meta-resolve-4.1.0.tgz", + "integrity": "sha512-I6fiaX09Xivtk+THaMfAwnA3MVA5Big1WHF1Dfx9hFuvNIWpXnorlkzhcQf6ehrqQiiZECRt1poOAkPmer3ruw==", + "dev": true + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true + }, + "indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "dev": true + }, + "index-to-position": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/index-to-position/-/index-to-position-0.1.2.tgz", + "integrity": "sha512-MWDKS3AS1bGCHLBA2VLImJz42f7bJh8wQsTGCzI3j519/CASStoDONUBVz2I/VID0MpiX3SGSnbOD2xUalbE5g==", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "dev": true + }, + "inquirer": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-3.3.0.tgz", + "integrity": "sha512-h+xtnyk4EwKvFWHrUYsWErEVR+igKtLdchu+o0Z1RL7VU/jVMFbYir2bp6bAj8efFNxWqHX0dIss6fJQ+/+qeQ==", + "dev": true, + "requires": { + "ansi-escapes": "^3.0.0", + "chalk": "^2.0.0", + "cli-cursor": "^2.1.0", + "cli-width": "^2.0.0", + "external-editor": "^2.0.4", + "figures": "^2.0.0", + "lodash": "^4.3.0", + "mute-stream": "0.0.7", + "run-async": "^2.2.0", + "rx-lite": "^4.0.8", + "rx-lite-aggregates": "^4.0.8", + "string-width": "^2.1.0", + "strip-ansi": "^4.0.0", + "through": "^2.3.6" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz", + "integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==", + "dev": true + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", + "dev": true + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + } + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "interpret": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-2.2.0.tgz", + "integrity": "sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw==", + "dev": true + }, + "into-stream": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/into-stream/-/into-stream-7.0.0.tgz", + "integrity": "sha512-2dYz766i9HprMBasCMvHMuazJ7u4WzhJwo5kb3iPSiW/iRYV6uPari3zHoqZlnuaR7V1bEiNMxikhp37rdBXbw==", + "dev": true, + "requires": { + "from2": "^2.3.0", + "p-is-promise": "^3.0.0" + } + }, + "ipaddr.js": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.1.0.tgz", + "integrity": "sha512-LlbxQ7xKzfBusov6UMi4MFpEg0m+mAm9xyNGEduwXMEDuf4WfzB/RZwMVYEd7IKGvh4IUkEXYxtAVu9T3OelJQ==", + "dev": true + }, + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "dev": true + }, + "is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "requires": { + "binary-extensions": "^2.0.0" + } + }, + "is-core-module": { + "version": "2.13.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", + "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", + "dev": true, + "requires": { + "hasown": "^2.0.0" + } + }, + "is-docker": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", + "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", + "dev": true + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, + "is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true + }, + "is-obj": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", + "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", + "dev": true + }, + "is-path-cwd": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz", + "integrity": "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==", + "dev": true + }, + "is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "dev": true + }, + "is-plain-obj": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-3.0.0.tgz", + "integrity": "sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==", + "dev": true + }, + "is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dev": true, + "requires": { + "isobject": "^3.0.1" + } + }, + "is-potential-custom-element-name": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", + "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==" + }, + "is-resolvable": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz", + "integrity": "sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==", + "dev": true + }, + "is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "dev": true + }, + "is-text-path": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-text-path/-/is-text-path-1.0.1.tgz", + "integrity": "sha512-xFuJpne9oFz5qDaodwmmG08e3CawH/2ZV8Qqza1Ko7Sk8POWbkRdwIoAWVhqvq0XeUzANEhKo2n0IXUGBm7A/w==", + "dev": true, + "requires": { + "text-extensions": "^1.0.0" + } + }, + "is-unicode-supported": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-2.1.0.tgz", + "integrity": "sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ==", + "dev": true + }, + "is-wsl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "dev": true, + "requires": { + "is-docker": "^2.0.0" + } + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "dev": true + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", + "dev": true + }, + "issue-parser": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/issue-parser/-/issue-parser-6.0.0.tgz", + "integrity": "sha512-zKa/Dxq2lGsBIXQ7CUZWTHfvxPC2ej0KfO7fIPqLlHB9J2hJ7rGhZ5rilhuufylr4RXYPzJUeFjKxz305OsNlA==", + "dev": true, + "requires": { + "lodash.capitalize": "^4.2.1", + "lodash.escaperegexp": "^4.1.2", + "lodash.isplainobject": "^4.0.6", + "lodash.isstring": "^4.0.1", + "lodash.uniqby": "^4.7.0" + } + }, + "java-properties": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/java-properties/-/java-properties-1.0.2.tgz", + "integrity": "sha512-qjdpeo2yKlYTH7nFdK0vbZWuTCesk4o63v5iVOlhMQPfuIZQfW/HI35SjfhA+4qpg36rnFSvUK5b1m+ckIblQQ==", + "dev": true + }, + "jest-worker": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", + "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", + "dev": true, + "requires": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + } + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "requires": { + "argparse": "^2.0.1" + } + }, + "jsdom": { + "version": "23.0.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-23.0.0.tgz", + "integrity": "sha512-cbL/UCtohJguhFC7c2/hgW6BeZCNvP7URQGnx9tSJRYKCdnfbfWOrtuLTMfiB2VxKsx5wPHVsh/J0aBy9lIIhQ==", + "requires": { + "cssstyle": "^3.0.0", + "data-urls": "^5.0.0", + "decimal.js": "^10.4.3", + "form-data": "^4.0.0", + "html-encoding-sniffer": "^4.0.0", + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.2", + "is-potential-custom-element-name": "^1.0.1", + "nwsapi": "^2.2.7", + "parse5": "^7.1.2", + "rrweb-cssom": "^0.6.0", + "saxes": "^6.0.0", + "symbol-tree": "^3.2.4", + "tough-cookie": "^4.1.3", + "w3c-xmlserializer": "^5.0.0", + "webidl-conversions": "^7.0.0", + "whatwg-encoding": "^3.1.1", + "whatwg-mimetype": "^4.0.0", + "whatwg-url": "^14.0.0", + "ws": "^8.14.2", + "xml-name-validator": "^5.0.0" + } + }, + "json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", + "dev": true + }, + "json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true + }, + "json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", + "dev": true + }, + "jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.6", + "universalify": "^2.0.0" + }, + "dependencies": { + "universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "dev": true + } + } + }, + "jsonparse": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", + "integrity": "sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==", + "dev": true + }, + "JSONStream": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz", + "integrity": "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==", + "dev": true, + "requires": { + "jsonparse": "^1.2.0", + "through": ">=2.2.7 <3" + } + }, + "kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true + }, + "launch-editor": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.6.1.tgz", + "integrity": "sha512-eB/uXmFVpY4zezmGp5XtU21kwo7GBbKB+EQ+UZeWtGb9yAM5xt/Evk+lYH3eRNAtId+ej4u7TYPFZ07w4s7rRw==", + "dev": true, + "requires": { + "picocolors": "^1.0.0", + "shell-quote": "^1.8.1" + } + }, + "levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==", + "dev": true, + "requires": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + } + }, + "lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true + }, + "load-json-file": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", + "integrity": "sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "parse-json": "^4.0.0", + "pify": "^3.0.0", + "strip-bom": "^3.0.0" + }, + "dependencies": { + "parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==", + "dev": true, + "requires": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + } + } + } + }, + "loader-runner": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", + "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==", + "dev": true + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "requires": { + "p-locate": "^4.1.0" + } + }, + "lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true + }, + "lodash-es": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz", + "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==", + "dev": true + }, + "lodash.camelcase": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", + "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==", + "dev": true + }, + "lodash.capitalize": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/lodash.capitalize/-/lodash.capitalize-4.2.1.tgz", + "integrity": "sha512-kZzYOKspf8XVX5AvmQF94gQW0lejFVgb80G85bU4ZWzoJ6C03PQg3coYAUpSTpQWelrZELd3XWgHzw4Ck5kaIw==", + "dev": true + }, + "lodash.escaperegexp": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.escaperegexp/-/lodash.escaperegexp-4.1.2.tgz", + "integrity": "sha512-TM9YBvyC84ZxE3rgfefxUWiQKLilstD6k7PTGt6wfbtXF8ixIJLOL3VYyV/z+ZiPLsVxAsKAFVwWlWeb2Y8Yyw==", + "dev": true + }, + "lodash.isfunction": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/lodash.isfunction/-/lodash.isfunction-3.0.9.tgz", + "integrity": "sha512-AirXNj15uRIMMPihnkInB4i3NHeb4iBtNg9WRWuK2o31S+ePwwNmDPaTL3o7dTJ+VXNZim7rFs4rxN4YU1oUJw==", + "dev": true + }, + "lodash.ismatch": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.ismatch/-/lodash.ismatch-4.4.0.tgz", + "integrity": "sha512-fPMfXjGQEV9Xsq/8MTSgUf255gawYRbjwMyDbcvDhXgV7enSZA0hynz6vMPnpAb5iONEzBHBPsT+0zes5Z301g==", + "dev": true + }, + "lodash.isplainobject": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", + "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==", + "dev": true + }, + "lodash.isstring": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", + "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==", + "dev": true + }, + "lodash.kebabcase": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.kebabcase/-/lodash.kebabcase-4.1.1.tgz", + "integrity": "sha512-N8XRTIMMqqDgSy4VLKPnJ/+hpGZN+PHQiJnSenYqPaVV/NCqEogTnAdZLQiGKhxX+JCs8waWq2t1XHWKOmlY8g==", + "dev": true + }, + "lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, + "lodash.mergewith": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.mergewith/-/lodash.mergewith-4.6.2.tgz", + "integrity": "sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ==", + "dev": true + }, + "lodash.snakecase": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.snakecase/-/lodash.snakecase-4.1.1.tgz", + "integrity": "sha512-QZ1d4xoBHYUeuouhEq3lk3Uq7ldgyFXGBhg04+oRLnIz8o9T65Eh+8YdroUwn846zchkA9yDsDl5CVVaV2nqYw==", + "dev": true + }, + "lodash.startcase": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.startcase/-/lodash.startcase-4.4.0.tgz", + "integrity": "sha512-+WKqsK294HMSc2jEbNgpHpd0JfIBhp7rEV4aqXWqFr6AlXov+SlcgB1Fv01y2kGe3Gc8nMW7VA0SrGuSkRfIEg==", + "dev": true + }, + "lodash.uniq": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", + "integrity": "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==", + "dev": true + }, + "lodash.uniqby": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/lodash.uniqby/-/lodash.uniqby-4.7.0.tgz", + "integrity": "sha512-e/zcLx6CSbmaEgFHCA7BnoQKyCtKMxnuWrJygbwPs/AIn+IMKl66L8/s+wBUn5LRw2pZx3bUHibiV1b6aTWIww==", + "dev": true + }, + "lodash.upperfirst": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/lodash.upperfirst/-/lodash.upperfirst-4.3.1.tgz", + "integrity": "sha512-sReKOYJIJf74dhJONhU4e0/shzi1trVbSWDOhKYE5XV2O+H7Sb2Dihwuc7xWxVl+DgFPyTqIN3zMfT9cq5iWDg==", + "dev": true + }, + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true + }, + "map-obj": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.3.0.tgz", + "integrity": "sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==", + "dev": true + }, + "marked": { + "version": "9.1.6", + "resolved": "https://registry.npmjs.org/marked/-/marked-9.1.6.tgz", + "integrity": "sha512-jcByLnIFkd5gSXZmjNvS1TlmRhCXZjIzHYlaGkPlLIekG55JDR2Z4va9tZwCiP+/RDERiNhMOFu01xd6O5ct1Q==", + "dev": true + }, + "marked-terminal": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/marked-terminal/-/marked-terminal-6.2.0.tgz", + "integrity": "sha512-ubWhwcBFHnXsjYNsu+Wndpg0zhY4CahSpPlA70PlO0rR9r2sZpkyU+rkCsOWH+KMEkx847UpALON+HWgxowFtw==", + "dev": true, + "requires": { + "ansi-escapes": "^6.2.0", + "cardinal": "^2.1.1", + "chalk": "^5.3.0", + "cli-table3": "^0.6.3", + "node-emoji": "^2.1.3", + "supports-hyperlinks": "^3.0.0" + }, + "dependencies": { + "ansi-escapes": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-6.2.1.tgz", + "integrity": "sha512-4nJ3yixlEthEJ9Rk4vPcdBRkZvQZlYyu8j4/Mqz5sgIkddmEnH2Yj2ZrnP9S3tQOvSNRUIgVNF/1yPpRAGNRig==", + "dev": true + }, + "chalk": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", + "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", + "dev": true + } + } + }, + "media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "dev": true + }, + "memfs": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.5.3.tgz", + "integrity": "sha512-UERzLsxzllchadvbPs5aolHh65ISpKpM+ccLbOJ8/vvpBKmAWf+la7dXFy7Mr0ySHbdHrFv5kGFCUHHe6GFEmw==", + "dev": true, + "requires": { + "fs-monkey": "^1.0.4" + } + }, + "meow": { + "version": "8.1.2", + "resolved": "https://registry.npmjs.org/meow/-/meow-8.1.2.tgz", + "integrity": "sha512-r85E3NdZ+mpYk1C6RjPFEMSE+s1iZMuHtsHAqY0DT3jZczl0diWUZ8g6oU7h0M9cD2EL+PzaYghhCLzR0ZNn5Q==", + "dev": true, + "requires": { + "@types/minimist": "^1.2.0", + "camelcase-keys": "^6.2.2", + "decamelize-keys": "^1.1.0", + "hard-rejection": "^2.1.0", + "minimist-options": "4.1.0", + "normalize-package-data": "^3.0.0", + "read-pkg-up": "^7.0.1", + "redent": "^3.0.0", + "trim-newlines": "^3.0.0", + "type-fest": "^0.18.0", + "yargs-parser": "^20.2.3" + } + }, + "merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==", + "dev": true + }, + "merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true + }, + "merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true + }, + "methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", + "dev": true + }, + "micromatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "dev": true, + "requires": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + } + }, + "mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "dev": true + }, + "mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==" + }, + "mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "requires": { + "mime-db": "1.52.0" + } + }, + "mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true + }, + "min-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", + "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", + "dev": true + }, + "minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", + "dev": true + }, + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true + }, + "minimist-options": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-4.1.0.tgz", + "integrity": "sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==", + "dev": true, + "requires": { + "arrify": "^1.0.1", + "is-plain-obj": "^1.1.0", + "kind-of": "^6.0.3" + }, + "dependencies": { + "is-plain-obj": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", + "integrity": "sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==", + "dev": true + } + } + }, + "mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "dev": true, + "requires": { + "minimist": "^1.2.6" + } + }, + "modify-values": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/modify-values/-/modify-values-1.0.1.tgz", + "integrity": "sha512-xV2bxeN6F7oYjZWTe/YPAy6MN2M+sL4u/Rlm2AHCIVGfo2p1yGmBHQ6vHehl4bRTZBdHu3TSkWdYgkwpYzAGSw==", + "dev": true + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "multicast-dns": { + "version": "7.2.5", + "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-7.2.5.tgz", + "integrity": "sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg==", + "dev": true, + "requires": { + "dns-packet": "^5.2.2", + "thunky": "^1.0.2" + } + }, + "mute-stream": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", + "integrity": "sha512-r65nCZhrbXXb6dXOACihYApHw2Q6pV0M3V0PSxd74N0+D8nzAdEAITq2oAjA1jVnKI+tGvEBUpqiMh0+rW6zDQ==", + "dev": true + }, + "natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true + }, + "negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "dev": true + }, + "neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "dev": true + }, + "nerf-dart": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/nerf-dart/-/nerf-dart-1.0.0.tgz", + "integrity": "sha512-EZSPZB70jiVsivaBLYDCyntd5eH8NTSMOn3rB+HxwdmKThGELLdYv8qVIMWvZEFy9w8ZZpW9h9OB32l1rGtj7g==", + "dev": true + }, + "node-emoji": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-2.1.3.tgz", + "integrity": "sha512-E2WEOVsgs7O16zsURJ/eH8BqhF029wGpEOnv7Urwdo2wmQanOACwJQh0devF9D9RhoZru0+9JXIS0dBXIAz+lA==", + "dev": true, + "requires": { + "@sindresorhus/is": "^4.6.0", + "char-regex": "^1.0.2", + "emojilib": "^2.4.0", + "skin-tone": "^2.0.0" + } + }, + "node-fetch": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "dev": true, + "requires": { + "whatwg-url": "^5.0.0" + }, + "dependencies": { + "tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", + "dev": true + }, + "webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", + "dev": true + }, + "whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "dev": true, + "requires": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + } + } + }, + "node-forge": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz", + "integrity": "sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==", + "dev": true + }, + "node-releases": { + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", + "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==", + "dev": true + }, + "normalize-package-data": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.3.tgz", + "integrity": "sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==", + "dev": true, + "requires": { + "hosted-git-info": "^4.0.1", + "is-core-module": "^2.5.0", + "semver": "^7.3.4", + "validate-npm-package-license": "^3.0.1" + } + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true + }, + "normalize-url": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-8.0.1.tgz", + "integrity": "sha512-IO9QvjUMWxPQQhs60oOu10CRkWCiZzSUkzbXGGV9pviYl1fXYcvkzQ5jV9z8Y6un8ARoVRl4EtC6v6jNqbaJ/w==", + "dev": true + }, + "npm": { + "version": "10.9.0", + "resolved": "https://registry.npmjs.org/npm/-/npm-10.9.0.tgz", + "integrity": "sha512-ZanDioFylI9helNhl2LNd+ErmVD+H5I53ry41ixlLyCBgkuYb+58CvbAp99hW+zr5L9W4X7CchSoeqKdngOLSw==", + "dev": true, + "requires": { + "@isaacs/string-locale-compare": "^1.1.0", + "@npmcli/arborist": "^8.0.0", + "@npmcli/config": "^9.0.0", + "@npmcli/fs": "^4.0.0", + "@npmcli/map-workspaces": "^4.0.1", + "@npmcli/package-json": "^6.0.1", + "@npmcli/promise-spawn": "^8.0.1", + "@npmcli/redact": "^3.0.0", + "@npmcli/run-script": "^9.0.1", + "@sigstore/tuf": "^2.3.4", + "abbrev": "^3.0.0", + "archy": "~1.0.0", + "cacache": "^19.0.1", + "chalk": "^5.3.0", + "ci-info": "^4.0.0", + "cli-columns": "^4.0.0", + "fastest-levenshtein": "^1.0.16", + "fs-minipass": "^3.0.3", + "glob": "^10.4.5", + "graceful-fs": "^4.2.11", + "hosted-git-info": "^8.0.0", + "ini": "^5.0.0", + "init-package-json": "^7.0.1", + "is-cidr": "^5.1.0", + "json-parse-even-better-errors": "^4.0.0", + "libnpmaccess": "^9.0.0", + "libnpmdiff": "^7.0.0", + "libnpmexec": "^9.0.0", + "libnpmfund": "^6.0.0", + "libnpmhook": "^11.0.0", + "libnpmorg": "^7.0.0", + "libnpmpack": "^8.0.0", + "libnpmpublish": "^10.0.0", + "libnpmsearch": "^8.0.0", + "libnpmteam": "^7.0.0", + "libnpmversion": "^7.0.0", + "make-fetch-happen": "^14.0.1", + "minimatch": "^9.0.5", + "minipass": "^7.1.1", + "minipass-pipeline": "^1.2.4", + "ms": "^2.1.2", + "node-gyp": "^10.2.0", + "nopt": "^8.0.0", + "normalize-package-data": "^7.0.0", + "npm-audit-report": "^6.0.0", + "npm-install-checks": "^7.1.0", + "npm-package-arg": "^12.0.0", + "npm-pick-manifest": "^10.0.0", + "npm-profile": "^11.0.1", + "npm-registry-fetch": "^18.0.1", + "npm-user-validate": "^3.0.0", + "p-map": "^4.0.0", + "pacote": "^19.0.0", + "parse-conflict-json": "^4.0.0", + "proc-log": "^5.0.0", + "qrcode-terminal": "^0.12.0", + "read": "^4.0.0", + "semver": "^7.6.3", + "spdx-expression-parse": "^4.0.0", + "ssri": "^12.0.0", + "supports-color": "^9.4.0", + "tar": "^6.2.1", + "text-table": "~0.2.0", + "tiny-relative-date": "^1.3.0", + "treeverse": "^3.0.0", + "validate-npm-package-name": "^6.0.0", + "which": "^5.0.0", + "write-file-atomic": "^6.0.0" + }, + "dependencies": { + "@isaacs/cliui": { + "version": "8.0.2", + "bundled": true, + "dev": true, + "requires": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "6.0.1", + "bundled": true, + "dev": true + }, + "emoji-regex": { + "version": "9.2.2", + "bundled": true, + "dev": true + }, + "string-width": { + "version": "5.1.2", + "bundled": true, + "dev": true, + "requires": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + } + }, + "strip-ansi": { + "version": "7.1.0", + "bundled": true, + "dev": true, + "requires": { + "ansi-regex": "^6.0.1" + } + } + } + }, + "@isaacs/fs-minipass": { + "version": "4.0.1", + "bundled": true, + "dev": true, + "requires": { + "minipass": "^7.0.4" + } + }, + "@isaacs/string-locale-compare": { + "version": "1.1.0", + "bundled": true, + "dev": true + }, + "@npmcli/agent": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "agent-base": "^7.1.0", + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.1", + "lru-cache": "^10.0.1", + "socks-proxy-agent": "^8.0.3" + } + }, + "@npmcli/arborist": { + "version": "8.0.0", + "bundled": true, + "dev": true, + "requires": { + "@isaacs/string-locale-compare": "^1.1.0", + "@npmcli/fs": "^4.0.0", + "@npmcli/installed-package-contents": "^3.0.0", + "@npmcli/map-workspaces": "^4.0.1", + "@npmcli/metavuln-calculator": "^8.0.0", + "@npmcli/name-from-folder": "^3.0.0", + "@npmcli/node-gyp": "^4.0.0", + "@npmcli/package-json": "^6.0.1", + "@npmcli/query": "^4.0.0", + "@npmcli/redact": "^3.0.0", + "@npmcli/run-script": "^9.0.1", + "bin-links": "^5.0.0", + "cacache": "^19.0.1", + "common-ancestor-path": "^1.0.1", + "hosted-git-info": "^8.0.0", + "json-parse-even-better-errors": "^4.0.0", + "json-stringify-nice": "^1.1.4", + "lru-cache": "^10.2.2", + "minimatch": "^9.0.4", + "nopt": "^8.0.0", + "npm-install-checks": "^7.1.0", + "npm-package-arg": "^12.0.0", + "npm-pick-manifest": "^10.0.0", + "npm-registry-fetch": "^18.0.1", + "pacote": "^19.0.0", + "parse-conflict-json": "^4.0.0", + "proc-log": "^5.0.0", + "proggy": "^3.0.0", + "promise-all-reject-late": "^1.0.0", + "promise-call-limit": "^3.0.1", + "read-package-json-fast": "^4.0.0", + "semver": "^7.3.7", + "ssri": "^12.0.0", + "treeverse": "^3.0.0", + "walk-up-path": "^3.0.1" + } + }, + "@npmcli/config": { + "version": "9.0.0", + "bundled": true, + "dev": true, + "requires": { + "@npmcli/map-workspaces": "^4.0.1", + "@npmcli/package-json": "^6.0.1", + "ci-info": "^4.0.0", + "ini": "^5.0.0", + "nopt": "^8.0.0", + "proc-log": "^5.0.0", + "semver": "^7.3.5", + "walk-up-path": "^3.0.1" + } + }, + "@npmcli/fs": { + "version": "4.0.0", + "bundled": true, + "dev": true, + "requires": { + "semver": "^7.3.5" + } + }, + "@npmcli/git": { + "version": "6.0.1", + "bundled": true, + "dev": true, + "requires": { + "@npmcli/promise-spawn": "^8.0.0", + "ini": "^5.0.0", + "lru-cache": "^10.0.1", + "npm-pick-manifest": "^10.0.0", + "proc-log": "^5.0.0", + "promise-inflight": "^1.0.1", + "promise-retry": "^2.0.1", + "semver": "^7.3.5", + "which": "^5.0.0" + } + }, + "@npmcli/installed-package-contents": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "npm-bundled": "^4.0.0", + "npm-normalize-package-bin": "^4.0.0" + } + }, + "@npmcli/map-workspaces": { + "version": "4.0.1", + "bundled": true, + "dev": true, + "requires": { + "@npmcli/name-from-folder": "^3.0.0", + "@npmcli/package-json": "^6.0.0", + "glob": "^10.2.2", + "minimatch": "^9.0.0" + } + }, + "@npmcli/metavuln-calculator": { + "version": "8.0.0", + "bundled": true, + "dev": true, + "requires": { + "cacache": "^19.0.0", + "json-parse-even-better-errors": "^4.0.0", + "pacote": "^19.0.0", + "proc-log": "^5.0.0", + "semver": "^7.3.5" + } + }, + "@npmcli/name-from-folder": { + "version": "3.0.0", + "bundled": true, + "dev": true + }, + "@npmcli/node-gyp": { + "version": "4.0.0", + "bundled": true, + "dev": true + }, + "@npmcli/package-json": { + "version": "6.0.1", + "bundled": true, + "dev": true, + "requires": { + "@npmcli/git": "^6.0.0", + "glob": "^10.2.2", + "hosted-git-info": "^8.0.0", + "json-parse-even-better-errors": "^4.0.0", + "normalize-package-data": "^7.0.0", + "proc-log": "^5.0.0", + "semver": "^7.5.3" + } + }, + "@npmcli/promise-spawn": { + "version": "8.0.1", + "bundled": true, + "dev": true, + "requires": { + "which": "^5.0.0" + } + }, + "@npmcli/query": { + "version": "4.0.0", + "bundled": true, + "dev": true, + "requires": { + "postcss-selector-parser": "^6.1.2" + } + }, + "@npmcli/redact": { + "version": "3.0.0", + "bundled": true, + "dev": true + }, + "@npmcli/run-script": { + "version": "9.0.1", + "bundled": true, + "dev": true, + "requires": { + "@npmcli/node-gyp": "^4.0.0", + "@npmcli/package-json": "^6.0.0", + "@npmcli/promise-spawn": "^8.0.0", + "node-gyp": "^10.0.0", + "proc-log": "^5.0.0", + "which": "^5.0.0" + } + }, + "@pkgjs/parseargs": { + "version": "0.11.0", + "bundled": true, + "dev": true, + "optional": true + }, + "@sigstore/bundle": { + "version": "2.3.2", + "bundled": true, + "dev": true, + "requires": { + "@sigstore/protobuf-specs": "^0.3.2" + } + }, + "@sigstore/core": { + "version": "1.1.0", + "bundled": true, + "dev": true + }, + "@sigstore/protobuf-specs": { + "version": "0.3.2", + "bundled": true, + "dev": true + }, + "@sigstore/sign": { + "version": "2.3.2", + "bundled": true, + "dev": true, + "requires": { + "@sigstore/bundle": "^2.3.2", + "@sigstore/core": "^1.0.0", + "@sigstore/protobuf-specs": "^0.3.2", + "make-fetch-happen": "^13.0.1", + "proc-log": "^4.2.0", + "promise-retry": "^2.0.1" + }, + "dependencies": { + "@npmcli/agent": { + "version": "2.2.2", + "bundled": true, + "dev": true, + "requires": { + "agent-base": "^7.1.0", + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.1", + "lru-cache": "^10.0.1", + "socks-proxy-agent": "^8.0.3" + } + }, + "@npmcli/fs": { + "version": "3.1.1", + "bundled": true, + "dev": true, + "requires": { + "semver": "^7.3.5" + } + }, + "cacache": { + "version": "18.0.4", + "bundled": true, + "dev": true, + "requires": { + "@npmcli/fs": "^3.1.0", + "fs-minipass": "^3.0.0", + "glob": "^10.2.2", + "lru-cache": "^10.0.1", + "minipass": "^7.0.3", + "minipass-collect": "^2.0.1", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "p-map": "^4.0.0", + "ssri": "^10.0.0", + "tar": "^6.1.11", + "unique-filename": "^3.0.0" + } + }, + "make-fetch-happen": { + "version": "13.0.1", + "bundled": true, + "dev": true, + "requires": { + "@npmcli/agent": "^2.0.0", + "cacache": "^18.0.0", + "http-cache-semantics": "^4.1.1", + "is-lambda": "^1.0.1", + "minipass": "^7.0.2", + "minipass-fetch": "^3.0.0", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "negotiator": "^0.6.3", + "proc-log": "^4.2.0", + "promise-retry": "^2.0.1", + "ssri": "^10.0.0" + } + }, + "minipass-fetch": { + "version": "3.0.5", + "bundled": true, + "dev": true, + "requires": { + "encoding": "^0.1.13", + "minipass": "^7.0.3", + "minipass-sized": "^1.0.3", + "minizlib": "^2.1.2" + } + }, + "proc-log": { + "version": "4.2.0", + "bundled": true, + "dev": true + }, + "ssri": { + "version": "10.0.6", + "bundled": true, + "dev": true, + "requires": { + "minipass": "^7.0.3" + } + }, + "unique-filename": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "unique-slug": "^4.0.0" + } + }, + "unique-slug": { + "version": "4.0.0", + "bundled": true, + "dev": true, + "requires": { + "imurmurhash": "^0.1.4" + } + } + } + }, + "@sigstore/tuf": { + "version": "2.3.4", + "bundled": true, + "dev": true, + "requires": { + "@sigstore/protobuf-specs": "^0.3.2", + "tuf-js": "^2.2.1" + } + }, + "@sigstore/verify": { + "version": "1.2.1", + "bundled": true, + "dev": true, + "requires": { + "@sigstore/bundle": "^2.3.2", + "@sigstore/core": "^1.1.0", + "@sigstore/protobuf-specs": "^0.3.2" + } + }, + "@tufjs/canonical-json": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "@tufjs/models": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "requires": { + "@tufjs/canonical-json": "2.0.0", + "minimatch": "^9.0.4" + } + }, + "abbrev": { + "version": "3.0.0", + "bundled": true, + "dev": true + }, + "agent-base": { + "version": "7.1.1", + "bundled": true, + "dev": true, + "requires": { + "debug": "^4.3.4" + } + }, + "aggregate-error": { + "version": "3.1.0", + "bundled": true, + "dev": true, + "requires": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + } + }, + "ansi-regex": { + "version": "5.0.1", + "bundled": true, + "dev": true + }, + "ansi-styles": { + "version": "6.2.1", + "bundled": true, + "dev": true + }, + "aproba": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "archy": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "balanced-match": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "bin-links": { + "version": "5.0.0", + "bundled": true, + "dev": true, + "requires": { + "cmd-shim": "^7.0.0", + "npm-normalize-package-bin": "^4.0.0", + "proc-log": "^5.0.0", + "read-cmd-shim": "^5.0.0", + "write-file-atomic": "^6.0.0" + } + }, + "binary-extensions": { + "version": "2.3.0", + "bundled": true, + "dev": true + }, + "brace-expansion": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "requires": { + "balanced-match": "^1.0.0" + } + }, + "cacache": { + "version": "19.0.1", + "bundled": true, + "dev": true, + "requires": { + "@npmcli/fs": "^4.0.0", + "fs-minipass": "^3.0.0", + "glob": "^10.2.2", + "lru-cache": "^10.0.1", + "minipass": "^7.0.3", + "minipass-collect": "^2.0.1", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "p-map": "^7.0.2", + "ssri": "^12.0.0", + "tar": "^7.4.3", + "unique-filename": "^4.0.0" + }, + "dependencies": { + "chownr": { + "version": "3.0.0", + "bundled": true, + "dev": true + }, + "minizlib": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "requires": { + "minipass": "^7.0.4", + "rimraf": "^5.0.5" + } + }, + "mkdirp": { + "version": "3.0.1", + "bundled": true, + "dev": true + }, + "p-map": { + "version": "7.0.2", + "bundled": true, + "dev": true + }, + "tar": { + "version": "7.4.3", + "bundled": true, + "dev": true, + "requires": { + "@isaacs/fs-minipass": "^4.0.0", + "chownr": "^3.0.0", + "minipass": "^7.1.2", + "minizlib": "^3.0.1", + "mkdirp": "^3.0.1", + "yallist": "^5.0.0" + } + }, + "yallist": { + "version": "5.0.0", + "bundled": true, + "dev": true + } + } + }, + "chalk": { + "version": "5.3.0", + "bundled": true, + "dev": true + }, + "chownr": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "ci-info": { + "version": "4.0.0", + "bundled": true, + "dev": true + }, + "cidr-regex": { + "version": "4.1.1", + "bundled": true, + "dev": true, + "requires": { + "ip-regex": "^5.0.0" + } + }, + "clean-stack": { + "version": "2.2.0", + "bundled": true, + "dev": true + }, + "cli-columns": { + "version": "4.0.0", + "bundled": true, + "dev": true, + "requires": { + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1" + } + }, + "cmd-shim": { + "version": "7.0.0", + "bundled": true, + "dev": true + }, + "color-convert": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "bundled": true, + "dev": true + }, + "common-ancestor-path": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "cross-spawn": { + "version": "7.0.3", + "bundled": true, + "dev": true, + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "dependencies": { + "which": { + "version": "2.0.2", + "bundled": true, + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + } + } + }, + "cssesc": { + "version": "3.0.0", + "bundled": true, + "dev": true + }, + "debug": { + "version": "4.3.6", + "bundled": true, + "dev": true, + "requires": { + "ms": "2.1.2" + }, + "dependencies": { + "ms": { + "version": "2.1.2", + "bundled": true, + "dev": true + } + } + }, + "diff": { + "version": "5.2.0", + "bundled": true, + "dev": true + }, + "eastasianwidth": { + "version": "0.2.0", + "bundled": true, + "dev": true + }, + "emoji-regex": { + "version": "8.0.0", + "bundled": true, + "dev": true + }, + "encoding": { + "version": "0.1.13", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "iconv-lite": "^0.6.2" + } + }, + "env-paths": { + "version": "2.2.1", + "bundled": true, + "dev": true + }, + "err-code": { + "version": "2.0.3", + "bundled": true, + "dev": true + }, + "exponential-backoff": { + "version": "3.1.1", + "bundled": true, + "dev": true + }, + "fastest-levenshtein": { + "version": "1.0.16", + "bundled": true, + "dev": true + }, + "foreground-child": { + "version": "3.3.0", + "bundled": true, + "dev": true, + "requires": { + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" + } + }, + "fs-minipass": { + "version": "3.0.3", + "bundled": true, + "dev": true, + "requires": { + "minipass": "^7.0.3" + } + }, + "glob": { + "version": "10.4.5", + "bundled": true, + "dev": true, + "requires": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + } + }, + "graceful-fs": { + "version": "4.2.11", + "bundled": true, + "dev": true + }, + "hosted-git-info": { + "version": "8.0.0", + "bundled": true, + "dev": true, + "requires": { + "lru-cache": "^10.0.1" + } + }, + "http-cache-semantics": { + "version": "4.1.1", + "bundled": true, + "dev": true + }, + "http-proxy-agent": { + "version": "7.0.2", + "bundled": true, + "dev": true, + "requires": { + "agent-base": "^7.1.0", + "debug": "^4.3.4" + } + }, + "https-proxy-agent": { + "version": "7.0.5", + "bundled": true, + "dev": true, + "requires": { + "agent-base": "^7.0.2", + "debug": "4" + } + }, + "iconv-lite": { + "version": "0.6.3", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + } + }, + "ignore-walk": { + "version": "7.0.0", + "bundled": true, + "dev": true, + "requires": { + "minimatch": "^9.0.0" + } + }, + "imurmurhash": { + "version": "0.1.4", + "bundled": true, + "dev": true + }, + "indent-string": { + "version": "4.0.0", + "bundled": true, + "dev": true + }, + "ini": { + "version": "5.0.0", + "bundled": true, + "dev": true + }, + "init-package-json": { + "version": "7.0.1", + "bundled": true, + "dev": true, + "requires": { + "@npmcli/package-json": "^6.0.0", + "npm-package-arg": "^12.0.0", + "promzard": "^2.0.0", + "read": "^4.0.0", + "semver": "^7.3.5", + "validate-npm-package-license": "^3.0.4", + "validate-npm-package-name": "^6.0.0" + } + }, + "ip-address": { + "version": "9.0.5", + "bundled": true, + "dev": true, + "requires": { + "jsbn": "1.1.0", + "sprintf-js": "^1.1.3" + } + }, + "ip-regex": { + "version": "5.0.0", + "bundled": true, + "dev": true + }, + "is-cidr": { + "version": "5.1.0", + "bundled": true, + "dev": true, + "requires": { + "cidr-regex": "^4.1.1" + } + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "bundled": true, + "dev": true + }, + "is-lambda": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "isexe": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "jackspeak": { + "version": "3.4.3", + "bundled": true, + "dev": true, + "requires": { + "@isaacs/cliui": "^8.0.2", + "@pkgjs/parseargs": "^0.11.0" + } + }, + "jsbn": { + "version": "1.1.0", + "bundled": true, + "dev": true + }, + "json-parse-even-better-errors": { + "version": "4.0.0", + "bundled": true, + "dev": true + }, + "json-stringify-nice": { + "version": "1.1.4", + "bundled": true, + "dev": true + }, + "jsonparse": { + "version": "1.3.1", + "bundled": true, + "dev": true + }, + "just-diff": { + "version": "6.0.2", + "bundled": true, + "dev": true + }, + "just-diff-apply": { + "version": "5.5.0", + "bundled": true, + "dev": true + }, + "libnpmaccess": { + "version": "9.0.0", + "bundled": true, + "dev": true, + "requires": { + "npm-package-arg": "^12.0.0", + "npm-registry-fetch": "^18.0.1" + } + }, + "libnpmdiff": { + "version": "7.0.0", + "bundled": true, + "dev": true, + "requires": { + "@npmcli/arborist": "^8.0.0", + "@npmcli/installed-package-contents": "^3.0.0", + "binary-extensions": "^2.3.0", + "diff": "^5.1.0", + "minimatch": "^9.0.4", + "npm-package-arg": "^12.0.0", + "pacote": "^19.0.0", + "tar": "^6.2.1" + } + }, + "libnpmexec": { + "version": "9.0.0", + "bundled": true, + "dev": true, + "requires": { + "@npmcli/arborist": "^8.0.0", + "@npmcli/run-script": "^9.0.1", + "ci-info": "^4.0.0", + "npm-package-arg": "^12.0.0", + "pacote": "^19.0.0", + "proc-log": "^5.0.0", + "read": "^4.0.0", + "read-package-json-fast": "^4.0.0", + "semver": "^7.3.7", + "walk-up-path": "^3.0.1" + } + }, + "libnpmfund": { + "version": "6.0.0", + "bundled": true, + "dev": true, + "requires": { + "@npmcli/arborist": "^8.0.0" + } + }, + "libnpmhook": { + "version": "11.0.0", + "bundled": true, + "dev": true, + "requires": { + "aproba": "^2.0.0", + "npm-registry-fetch": "^18.0.1" + } + }, + "libnpmorg": { + "version": "7.0.0", + "bundled": true, + "dev": true, + "requires": { + "aproba": "^2.0.0", + "npm-registry-fetch": "^18.0.1" + } + }, + "libnpmpack": { + "version": "8.0.0", + "bundled": true, + "dev": true, + "requires": { + "@npmcli/arborist": "^8.0.0", + "@npmcli/run-script": "^9.0.1", + "npm-package-arg": "^12.0.0", + "pacote": "^19.0.0" + } + }, + "libnpmpublish": { + "version": "10.0.0", + "bundled": true, + "dev": true, + "requires": { + "ci-info": "^4.0.0", + "normalize-package-data": "^7.0.0", + "npm-package-arg": "^12.0.0", + "npm-registry-fetch": "^18.0.1", + "proc-log": "^5.0.0", + "semver": "^7.3.7", + "sigstore": "^2.2.0", + "ssri": "^12.0.0" + } + }, + "libnpmsearch": { + "version": "8.0.0", + "bundled": true, + "dev": true, + "requires": { + "npm-registry-fetch": "^18.0.1" + } + }, + "libnpmteam": { + "version": "7.0.0", + "bundled": true, + "dev": true, + "requires": { + "aproba": "^2.0.0", + "npm-registry-fetch": "^18.0.1" + } + }, + "libnpmversion": { + "version": "7.0.0", + "bundled": true, + "dev": true, + "requires": { + "@npmcli/git": "^6.0.1", + "@npmcli/run-script": "^9.0.1", + "json-parse-even-better-errors": "^4.0.0", + "proc-log": "^5.0.0", + "semver": "^7.3.7" + } + }, + "lru-cache": { + "version": "10.4.3", + "bundled": true, + "dev": true + }, + "make-fetch-happen": { + "version": "14.0.1", + "bundled": true, + "dev": true, + "requires": { + "@npmcli/agent": "^3.0.0", + "cacache": "^19.0.1", + "http-cache-semantics": "^4.1.1", + "minipass": "^7.0.2", + "minipass-fetch": "^4.0.0", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "negotiator": "^0.6.3", + "proc-log": "^5.0.0", + "promise-retry": "^2.0.1", + "ssri": "^12.0.0" + } + }, + "minimatch": { + "version": "9.0.5", + "bundled": true, + "dev": true, + "requires": { + "brace-expansion": "^2.0.1" + } + }, + "minipass": { + "version": "7.1.2", + "bundled": true, + "dev": true + }, + "minipass-collect": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "requires": { + "minipass": "^7.0.3" + } + }, + "minipass-fetch": { + "version": "4.0.0", + "bundled": true, + "dev": true, + "requires": { + "encoding": "^0.1.13", + "minipass": "^7.0.3", + "minipass-sized": "^1.0.3", + "minizlib": "^3.0.1" + }, + "dependencies": { + "minizlib": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "requires": { + "minipass": "^7.0.4", + "rimraf": "^5.0.5" + } + } + } + }, + "minipass-flush": { + "version": "1.0.5", + "bundled": true, + "dev": true, + "requires": { + "minipass": "^3.0.0" + }, + "dependencies": { + "minipass": { + "version": "3.3.6", + "bundled": true, + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + } + } + }, + "minipass-pipeline": { + "version": "1.2.4", + "bundled": true, + "dev": true, + "requires": { + "minipass": "^3.0.0" + }, + "dependencies": { + "minipass": { + "version": "3.3.6", + "bundled": true, + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + } + } + }, + "minipass-sized": { + "version": "1.0.3", + "bundled": true, + "dev": true, + "requires": { + "minipass": "^3.0.0" + }, + "dependencies": { + "minipass": { + "version": "3.3.6", + "bundled": true, + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + } + } + }, + "minizlib": { + "version": "2.1.2", + "bundled": true, + "dev": true, + "requires": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + }, + "dependencies": { + "minipass": { + "version": "3.3.6", + "bundled": true, + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + } + } + }, + "mkdirp": { + "version": "1.0.4", + "bundled": true, + "dev": true + }, + "ms": { + "version": "2.1.3", + "bundled": true, + "dev": true + }, + "mute-stream": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "negotiator": { + "version": "0.6.3", + "bundled": true, + "dev": true + }, + "node-gyp": { + "version": "10.2.0", + "bundled": true, + "dev": true, + "requires": { + "env-paths": "^2.2.0", + "exponential-backoff": "^3.1.1", + "glob": "^10.3.10", + "graceful-fs": "^4.2.6", + "make-fetch-happen": "^13.0.0", + "nopt": "^7.0.0", + "proc-log": "^4.1.0", + "semver": "^7.3.5", + "tar": "^6.2.1", + "which": "^4.0.0" + }, + "dependencies": { + "@npmcli/agent": { + "version": "2.2.2", + "bundled": true, + "dev": true, + "requires": { + "agent-base": "^7.1.0", + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.1", + "lru-cache": "^10.0.1", + "socks-proxy-agent": "^8.0.3" + } + }, + "@npmcli/fs": { + "version": "3.1.1", + "bundled": true, + "dev": true, + "requires": { + "semver": "^7.3.5" + } + }, + "abbrev": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "cacache": { + "version": "18.0.4", + "bundled": true, + "dev": true, + "requires": { + "@npmcli/fs": "^3.1.0", + "fs-minipass": "^3.0.0", + "glob": "^10.2.2", + "lru-cache": "^10.0.1", + "minipass": "^7.0.3", + "minipass-collect": "^2.0.1", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "p-map": "^4.0.0", + "ssri": "^10.0.0", + "tar": "^6.1.11", + "unique-filename": "^3.0.0" + } + }, + "isexe": { + "version": "3.1.1", + "bundled": true, + "dev": true + }, + "make-fetch-happen": { + "version": "13.0.1", + "bundled": true, + "dev": true, + "requires": { + "@npmcli/agent": "^2.0.0", + "cacache": "^18.0.0", + "http-cache-semantics": "^4.1.1", + "is-lambda": "^1.0.1", + "minipass": "^7.0.2", + "minipass-fetch": "^3.0.0", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "negotiator": "^0.6.3", + "proc-log": "^4.2.0", + "promise-retry": "^2.0.1", + "ssri": "^10.0.0" + } + }, + "minipass-fetch": { + "version": "3.0.5", + "bundled": true, + "dev": true, + "requires": { + "encoding": "^0.1.13", + "minipass": "^7.0.3", + "minipass-sized": "^1.0.3", + "minizlib": "^2.1.2" + } + }, + "nopt": { + "version": "7.2.1", + "bundled": true, + "dev": true, + "requires": { + "abbrev": "^2.0.0" + } + }, + "proc-log": { + "version": "4.2.0", + "bundled": true, + "dev": true + }, + "ssri": { + "version": "10.0.6", + "bundled": true, + "dev": true, + "requires": { + "minipass": "^7.0.3" + } + }, + "unique-filename": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "unique-slug": "^4.0.0" + } + }, + "unique-slug": { + "version": "4.0.0", + "bundled": true, + "dev": true, + "requires": { + "imurmurhash": "^0.1.4" + } + }, + "which": { + "version": "4.0.0", + "bundled": true, + "dev": true, + "requires": { + "isexe": "^3.1.1" + } + } + } + }, + "nopt": { + "version": "8.0.0", + "bundled": true, + "dev": true, + "requires": { + "abbrev": "^2.0.0" + }, + "dependencies": { + "abbrev": { + "version": "2.0.0", + "bundled": true, + "dev": true + } + } + }, + "normalize-package-data": { + "version": "7.0.0", + "bundled": true, + "dev": true, + "requires": { + "hosted-git-info": "^8.0.0", + "semver": "^7.3.5", + "validate-npm-package-license": "^3.0.4" + } + }, + "npm-audit-report": { + "version": "6.0.0", + "bundled": true, + "dev": true + }, + "npm-bundled": { + "version": "4.0.0", + "bundled": true, + "dev": true, + "requires": { + "npm-normalize-package-bin": "^4.0.0" + } + }, + "npm-install-checks": { + "version": "7.1.0", + "bundled": true, + "dev": true, + "requires": { + "semver": "^7.1.1" + } + }, + "npm-normalize-package-bin": { + "version": "4.0.0", + "bundled": true, + "dev": true + }, + "npm-package-arg": { + "version": "12.0.0", + "bundled": true, + "dev": true, + "requires": { + "hosted-git-info": "^8.0.0", + "proc-log": "^5.0.0", + "semver": "^7.3.5", + "validate-npm-package-name": "^6.0.0" + } + }, + "npm-packlist": { + "version": "9.0.0", + "bundled": true, + "dev": true, + "requires": { + "ignore-walk": "^7.0.0" + } + }, + "npm-pick-manifest": { + "version": "10.0.0", + "bundled": true, + "dev": true, + "requires": { + "npm-install-checks": "^7.1.0", + "npm-normalize-package-bin": "^4.0.0", + "npm-package-arg": "^12.0.0", + "semver": "^7.3.5" + } + }, + "npm-profile": { + "version": "11.0.1", + "bundled": true, + "dev": true, + "requires": { + "npm-registry-fetch": "^18.0.0", + "proc-log": "^5.0.0" + } + }, + "npm-registry-fetch": { + "version": "18.0.1", + "bundled": true, + "dev": true, + "requires": { + "@npmcli/redact": "^3.0.0", + "jsonparse": "^1.3.1", + "make-fetch-happen": "^14.0.0", + "minipass": "^7.0.2", + "minipass-fetch": "^4.0.0", + "minizlib": "^3.0.1", + "npm-package-arg": "^12.0.0", + "proc-log": "^5.0.0" + }, + "dependencies": { + "minizlib": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "requires": { + "minipass": "^7.0.4", + "rimraf": "^5.0.5" + } + } + } + }, + "npm-user-validate": { + "version": "3.0.0", + "bundled": true, + "dev": true + }, + "p-map": { + "version": "4.0.0", + "bundled": true, + "dev": true, + "requires": { + "aggregate-error": "^3.0.0" + } + }, + "package-json-from-dist": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "pacote": { + "version": "19.0.0", + "bundled": true, + "dev": true, + "requires": { + "@npmcli/git": "^6.0.0", + "@npmcli/installed-package-contents": "^3.0.0", + "@npmcli/package-json": "^6.0.0", + "@npmcli/promise-spawn": "^8.0.0", + "@npmcli/run-script": "^9.0.0", + "cacache": "^19.0.0", + "fs-minipass": "^3.0.0", + "minipass": "^7.0.2", + "npm-package-arg": "^12.0.0", + "npm-packlist": "^9.0.0", + "npm-pick-manifest": "^10.0.0", + "npm-registry-fetch": "^18.0.0", + "proc-log": "^5.0.0", + "promise-retry": "^2.0.1", + "sigstore": "^2.2.0", + "ssri": "^12.0.0", + "tar": "^6.1.11" + } + }, + "parse-conflict-json": { + "version": "4.0.0", + "bundled": true, + "dev": true, + "requires": { + "json-parse-even-better-errors": "^4.0.0", + "just-diff": "^6.0.0", + "just-diff-apply": "^5.2.0" + } + }, + "path-key": { + "version": "3.1.1", + "bundled": true, + "dev": true + }, + "path-scurry": { + "version": "1.11.1", + "bundled": true, + "dev": true, + "requires": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + } + }, + "postcss-selector-parser": { + "version": "6.1.2", + "bundled": true, + "dev": true, + "requires": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + } + }, + "proc-log": { + "version": "5.0.0", + "bundled": true, + "dev": true + }, + "proggy": { + "version": "3.0.0", + "bundled": true, + "dev": true + }, + "promise-all-reject-late": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "promise-call-limit": { + "version": "3.0.1", + "bundled": true, + "dev": true + }, + "promise-inflight": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "promise-retry": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "requires": { + "err-code": "^2.0.2", + "retry": "^0.12.0" + } + }, + "promzard": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "requires": { + "read": "^4.0.0" + } + }, + "qrcode-terminal": { + "version": "0.12.0", + "bundled": true, + "dev": true + }, + "read": { + "version": "4.0.0", + "bundled": true, + "dev": true, + "requires": { + "mute-stream": "^2.0.0" + } + }, + "read-cmd-shim": { + "version": "5.0.0", + "bundled": true, + "dev": true + }, + "read-package-json-fast": { + "version": "4.0.0", + "bundled": true, + "dev": true, + "requires": { + "json-parse-even-better-errors": "^4.0.0", + "npm-normalize-package-bin": "^4.0.0" + } + }, + "retry": { + "version": "0.12.0", + "bundled": true, + "dev": true + }, + "rimraf": { + "version": "5.0.10", + "bundled": true, + "dev": true, + "requires": { + "glob": "^10.3.7" + } + }, + "safer-buffer": { + "version": "2.1.2", + "bundled": true, + "dev": true, + "optional": true + }, + "semver": { + "version": "7.6.3", + "bundled": true, + "dev": true + }, + "shebang-command": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "bundled": true, + "dev": true + }, + "signal-exit": { + "version": "4.1.0", + "bundled": true, + "dev": true + }, + "sigstore": { + "version": "2.3.1", + "bundled": true, + "dev": true, + "requires": { + "@sigstore/bundle": "^2.3.2", + "@sigstore/core": "^1.0.0", + "@sigstore/protobuf-specs": "^0.3.2", + "@sigstore/sign": "^2.3.2", + "@sigstore/tuf": "^2.3.4", + "@sigstore/verify": "^1.2.1" + } + }, + "smart-buffer": { + "version": "4.2.0", + "bundled": true, + "dev": true + }, + "socks": { + "version": "2.8.3", + "bundled": true, + "dev": true, + "requires": { + "ip-address": "^9.0.5", + "smart-buffer": "^4.2.0" + } + }, + "socks-proxy-agent": { + "version": "8.0.4", + "bundled": true, + "dev": true, + "requires": { + "agent-base": "^7.1.1", + "debug": "^4.3.4", + "socks": "^2.8.3" + } + }, + "spdx-correct": { + "version": "3.2.0", + "bundled": true, + "dev": true, + "requires": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + }, + "dependencies": { + "spdx-expression-parse": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "requires": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + } + } + }, + "spdx-exceptions": { + "version": "2.5.0", + "bundled": true, + "dev": true + }, + "spdx-expression-parse": { + "version": "4.0.0", + "bundled": true, + "dev": true, + "requires": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-license-ids": { + "version": "3.0.18", + "bundled": true, + "dev": true + }, + "sprintf-js": { + "version": "1.1.3", + "bundled": true, + "dev": true + }, + "ssri": { + "version": "12.0.0", + "bundled": true, + "dev": true, + "requires": { + "minipass": "^7.0.3" + } + }, + "string-width": { + "version": "4.2.3", + "bundled": true, + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + } + }, + "string-width-cjs": { + "version": "npm:string-width@4.2.3", + "bundled": true, + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + } + }, + "strip-ansi": { + "version": "6.0.1", + "bundled": true, + "dev": true, + "requires": { + "ansi-regex": "^5.0.1" + } + }, + "strip-ansi-cjs": { + "version": "npm:strip-ansi@6.0.1", + "bundled": true, "dev": true, "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" + "ansi-regex": "^5.0.1" } }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "supports-color": { + "version": "9.4.0", + "bundled": true, "dev": true }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "tar": { + "version": "6.2.1", + "bundled": true, "dev": true, "requires": { - "safe-buffer": "~5.1.0" + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "minipass": "^5.0.0", + "minizlib": "^2.1.1", + "mkdirp": "^1.0.3", + "yallist": "^4.0.0" + }, + "dependencies": { + "fs-minipass": { + "version": "2.1.0", + "bundled": true, + "dev": true, + "requires": { + "minipass": "^3.0.0" + }, + "dependencies": { + "minipass": { + "version": "3.3.6", + "bundled": true, + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + } + } + }, + "minipass": { + "version": "5.0.0", + "bundled": true, + "dev": true + } } - } - } - }, - "html-encoding-sniffer": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-4.0.0.tgz", - "integrity": "sha512-Y22oTqIU4uuPgEemfz7NDJz6OeKf12Lsu+QC+s3BVpda64lTiMYCyGwg5ki4vFxkMwQdeZDl2adZoqUgdFuTgQ==", - "requires": { - "whatwg-encoding": "^3.1.1" - } - }, - "html-entities": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.4.0.tgz", - "integrity": "sha512-igBTJcNNNhvZFRtm8uA6xMY6xYleeDwn3PeBCkDz7tHttv4F2hsDI2aPgNERWzvRcNYHNT3ymRaQzllmXj4YsQ==", - "dev": true - }, - "http-deceiver": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz", - "integrity": "sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw==", - "dev": true - }, - "http-errors": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", - "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", - "dev": true, - "requires": { - "depd": "2.0.0", - "inherits": "2.0.4", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "toidentifier": "1.0.1" - } - }, - "http-parser-js": { - "version": "0.5.8", - "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.8.tgz", - "integrity": "sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q==", - "dev": true - }, - "http-proxy": { - "version": "1.18.1", - "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", - "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", - "dev": true, - "requires": { - "eventemitter3": "^4.0.0", - "follow-redirects": "^1.0.0", - "requires-port": "^1.0.0" - } - }, - "http-proxy-agent": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", - "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", - "requires": { - "agent-base": "^7.1.0", - "debug": "^4.3.4" - } - }, - "http-proxy-middleware": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.6.tgz", - "integrity": "sha512-ya/UeJ6HVBYxrgYotAZo1KvPWlgB48kUJLDePFeneHsVujFaW5WNj2NgWCAE//B1Dl02BIfYlpNgBy8Kf8Rjmw==", - "dev": true, - "requires": { - "@types/http-proxy": "^1.17.8", - "http-proxy": "^1.18.1", - "is-glob": "^4.0.1", - "is-plain-obj": "^3.0.0", - "micromatch": "^4.0.2" - } - }, - "https-proxy-agent": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.4.tgz", - "integrity": "sha512-wlwpilI7YdjSkWaQ/7omYBMTliDcmCN8OLihO6I9B86g06lMyAoqgoDpV0XqoaPOKj+0DIdAvnsWfyAAhmimcg==", - "requires": { - "agent-base": "^7.0.2", - "debug": "4" - } - }, - "human-signals": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", - "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", - "dev": true - }, - "husky": { - "version": "9.1.6", - "resolved": "https://registry.npmjs.org/husky/-/husky-9.1.6.tgz", - "integrity": "sha512-sqbjZKK7kf44hfdE94EoX8MZNk0n7HeW37O4YrVGCF4wzgQjp+akPAkfUK5LZ6KuR/6sqeAVuXHji+RzQgOn5A==", - "dev": true - }, - "iconv-lite": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", - "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", - "requires": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - } - }, - "ignore": { - "version": "3.3.10", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.10.tgz", - "integrity": "sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug==", - "dev": true - }, - "import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "dev": true, - "requires": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - }, - "dependencies": { - "resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + }, + "text-table": { + "version": "0.2.0", + "bundled": true, "dev": true - } - } - }, - "import-local": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", - "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==", - "dev": true, - "requires": { - "pkg-dir": "^4.2.0", - "resolve-cwd": "^3.0.0" - } - }, - "imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", - "dev": true - }, - "indent-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", - "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", - "dev": true - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "dev": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true - }, - "ini": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", - "dev": true - }, - "inquirer": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-3.3.0.tgz", - "integrity": "sha512-h+xtnyk4EwKvFWHrUYsWErEVR+igKtLdchu+o0Z1RL7VU/jVMFbYir2bp6bAj8efFNxWqHX0dIss6fJQ+/+qeQ==", - "dev": true, - "requires": { - "ansi-escapes": "^3.0.0", - "chalk": "^2.0.0", - "cli-cursor": "^2.1.0", - "cli-width": "^2.0.0", - "external-editor": "^2.0.4", - "figures": "^2.0.0", - "lodash": "^4.3.0", - "mute-stream": "0.0.7", - "run-async": "^2.2.0", - "rx-lite": "^4.0.8", - "rx-lite-aggregates": "^4.0.8", - "string-width": "^2.1.0", - "strip-ansi": "^4.0.0", - "through": "^2.3.6" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz", - "integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==", + }, + "tiny-relative-date": { + "version": "1.3.0", + "bundled": true, "dev": true }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "treeverse": { + "version": "3.0.0", + "bundled": true, + "dev": true + }, + "tuf-js": { + "version": "2.2.1", + "bundled": true, "dev": true, "requires": { - "color-convert": "^1.9.0" + "@tufjs/models": "2.0.1", + "debug": "^4.3.4", + "make-fetch-happen": "^13.0.1" + }, + "dependencies": { + "@npmcli/agent": { + "version": "2.2.2", + "bundled": true, + "dev": true, + "requires": { + "agent-base": "^7.1.0", + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.1", + "lru-cache": "^10.0.1", + "socks-proxy-agent": "^8.0.3" + } + }, + "@npmcli/fs": { + "version": "3.1.1", + "bundled": true, + "dev": true, + "requires": { + "semver": "^7.3.5" + } + }, + "cacache": { + "version": "18.0.4", + "bundled": true, + "dev": true, + "requires": { + "@npmcli/fs": "^3.1.0", + "fs-minipass": "^3.0.0", + "glob": "^10.2.2", + "lru-cache": "^10.0.1", + "minipass": "^7.0.3", + "minipass-collect": "^2.0.1", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "p-map": "^4.0.0", + "ssri": "^10.0.0", + "tar": "^6.1.11", + "unique-filename": "^3.0.0" + } + }, + "make-fetch-happen": { + "version": "13.0.1", + "bundled": true, + "dev": true, + "requires": { + "@npmcli/agent": "^2.0.0", + "cacache": "^18.0.0", + "http-cache-semantics": "^4.1.1", + "is-lambda": "^1.0.1", + "minipass": "^7.0.2", + "minipass-fetch": "^3.0.0", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "negotiator": "^0.6.3", + "proc-log": "^4.2.0", + "promise-retry": "^2.0.1", + "ssri": "^10.0.0" + } + }, + "minipass-fetch": { + "version": "3.0.5", + "bundled": true, + "dev": true, + "requires": { + "encoding": "^0.1.13", + "minipass": "^7.0.3", + "minipass-sized": "^1.0.3", + "minizlib": "^2.1.2" + } + }, + "proc-log": { + "version": "4.2.0", + "bundled": true, + "dev": true + }, + "ssri": { + "version": "10.0.6", + "bundled": true, + "dev": true, + "requires": { + "minipass": "^7.0.3" + } + }, + "unique-filename": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "unique-slug": "^4.0.0" + } + }, + "unique-slug": { + "version": "4.0.0", + "bundled": true, + "dev": true, + "requires": { + "imurmurhash": "^0.1.4" + } + } } }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "unique-filename": { + "version": "4.0.0", + "bundled": true, "dev": true, "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" + "unique-slug": "^5.0.0" } }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "unique-slug": { + "version": "5.0.0", + "bundled": true, "dev": true, "requires": { - "color-name": "1.1.3" + "imurmurhash": "^0.1.4" + } + }, + "util-deprecate": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "validate-npm-package-license": { + "version": "3.0.4", + "bundled": true, + "dev": true, + "requires": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + }, + "dependencies": { + "spdx-expression-parse": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "requires": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + } } }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "validate-npm-package-name": { + "version": "6.0.0", + "bundled": true, "dev": true }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "walk-up-path": { + "version": "3.0.1", + "bundled": true, "dev": true }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", - "dev": true + "which": { + "version": "5.0.0", + "bundled": true, + "dev": true, + "requires": { + "isexe": "^3.1.1" + }, + "dependencies": { + "isexe": { + "version": "3.1.1", + "bundled": true, + "dev": true + } + } }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "wrap-ansi": { + "version": "8.1.0", + "bundled": true, "dev": true, "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "dependencies": { + "ansi-regex": { + "version": "6.0.1", + "bundled": true, + "dev": true + }, + "emoji-regex": { + "version": "9.2.2", + "bundled": true, + "dev": true + }, + "string-width": { + "version": "5.1.2", + "bundled": true, + "dev": true, + "requires": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + } + }, + "strip-ansi": { + "version": "7.1.0", + "bundled": true, + "dev": true, + "requires": { + "ansi-regex": "^6.0.1" + } + } } }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==", + "wrap-ansi-cjs": { + "version": "npm:wrap-ansi@7.0.0", + "bundled": true, "dev": true, "requires": { - "ansi-regex": "^3.0.0" + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "bundled": true, + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + } } }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "write-file-atomic": { + "version": "6.0.0", + "bundled": true, "dev": true, "requires": { - "has-flag": "^3.0.0" + "imurmurhash": "^0.1.4", + "signal-exit": "^4.0.1" } + }, + "yallist": { + "version": "4.0.0", + "bundled": true, + "dev": true } } }, - "interpret": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-2.2.0.tgz", - "integrity": "sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw==", - "dev": true - }, - "ipaddr.js": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.1.0.tgz", - "integrity": "sha512-LlbxQ7xKzfBusov6UMi4MFpEg0m+mAm9xyNGEduwXMEDuf4WfzB/RZwMVYEd7IKGvh4IUkEXYxtAVu9T3OelJQ==", - "dev": true - }, - "is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", - "dev": true - }, - "is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, - "requires": { - "binary-extensions": "^2.0.0" - } - }, - "is-core-module": { - "version": "2.13.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", - "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", - "dev": true, - "requires": { - "hasown": "^2.0.0" - } - }, - "is-docker": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", - "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", - "dev": true - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true - }, - "is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true - }, - "is-obj": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", - "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", - "dev": true - }, - "is-plain-obj": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-3.0.0.tgz", - "integrity": "sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==", - "dev": true - }, - "is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "requires": { - "isobject": "^3.0.1" - } - }, - "is-potential-custom-element-name": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", - "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==" - }, - "is-resolvable": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz", - "integrity": "sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==", - "dev": true - }, - "is-stream": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", - "dev": true - }, - "is-text-path": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-text-path/-/is-text-path-1.0.1.tgz", - "integrity": "sha512-xFuJpne9oFz5qDaodwmmG08e3CawH/2ZV8Qqza1Ko7Sk8POWbkRdwIoAWVhqvq0XeUzANEhKo2n0IXUGBm7A/w==", - "dev": true, - "requires": { - "text-extensions": "^1.0.0" - } - }, - "is-wsl": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", - "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", - "dev": true, - "requires": { - "is-docker": "^2.0.0" - } - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", - "dev": true - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", - "dev": true - }, - "jest-worker": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", - "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", - "dev": true, - "requires": { - "@types/node": "*", - "merge-stream": "^2.0.0", - "supports-color": "^8.0.0" - } - }, - "js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true - }, - "js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", "dev": true, "requires": { - "argparse": "^2.0.1" + "path-key": "^3.0.0" } }, - "jsdom": { - "version": "23.0.0", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-23.0.0.tgz", - "integrity": "sha512-cbL/UCtohJguhFC7c2/hgW6BeZCNvP7URQGnx9tSJRYKCdnfbfWOrtuLTMfiB2VxKsx5wPHVsh/J0aBy9lIIhQ==", - "requires": { - "cssstyle": "^3.0.0", - "data-urls": "^5.0.0", - "decimal.js": "^10.4.3", - "form-data": "^4.0.0", - "html-encoding-sniffer": "^4.0.0", - "http-proxy-agent": "^7.0.0", - "https-proxy-agent": "^7.0.2", - "is-potential-custom-element-name": "^1.0.1", - "nwsapi": "^2.2.7", - "parse5": "^7.1.2", - "rrweb-cssom": "^0.6.0", - "saxes": "^6.0.0", - "symbol-tree": "^3.2.4", - "tough-cookie": "^4.1.3", - "w3c-xmlserializer": "^5.0.0", - "webidl-conversions": "^7.0.0", - "whatwg-encoding": "^3.1.1", - "whatwg-mimetype": "^4.0.0", - "whatwg-url": "^14.0.0", - "ws": "^8.14.2", - "xml-name-validator": "^5.0.0" - } + "nwsapi": { + "version": "2.2.9", + "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.9.tgz", + "integrity": "sha512-2f3F0SEEer8bBu0dsNCFF50N0cTThV1nWFYcEYFZttdW0lDAoybv9cQoK7X7/68Z89S7FoRrVjP1LPX4XRf9vg==" }, - "json-parse-even-better-errors": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", - "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", "dev": true }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "object-inspect": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", + "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", "dev": true }, - "json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "obuf": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", + "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==", "dev": true }, - "jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", "dev": true, "requires": { - "graceful-fs": "^4.1.6", - "universalify": "^2.0.0" - }, - "dependencies": { - "universalify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", - "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", - "dev": true - } + "ee-first": "1.1.1" } }, - "jsonparse": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", - "integrity": "sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==", + "on-headers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", + "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", "dev": true }, - "JSONStream": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz", - "integrity": "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==", + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", "dev": true, "requires": { - "jsonparse": "^1.2.0", - "through": ">=2.2.7 <3" + "wrappy": "1" } }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true + "onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "requires": { + "mimic-fn": "^2.1.0" + } }, - "launch-editor": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.6.1.tgz", - "integrity": "sha512-eB/uXmFVpY4zezmGp5XtU21kwo7GBbKB+EQ+UZeWtGb9yAM5xt/Evk+lYH3eRNAtId+ej4u7TYPFZ07w4s7rRw==", + "open": { + "version": "8.4.2", + "resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz", + "integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==", "dev": true, "requires": { - "picocolors": "^1.0.0", - "shell-quote": "^1.8.1" + "define-lazy-prop": "^2.0.0", + "is-docker": "^2.1.1", + "is-wsl": "^2.2.0" } }, - "levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==", + "optionator": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", + "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", "dev": true, "requires": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.6", + "levn": "~0.3.0", "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" + "type-check": "~0.3.2", + "word-wrap": "~1.2.3" } }, - "lines-and-columns": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", - "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", "dev": true }, - "loader-runner": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", - "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==", + "p-each-series": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-each-series/-/p-each-series-3.0.0.tgz", + "integrity": "sha512-lastgtAdoH9YaLyDa5i5z64q+kzOcQHsQ5SsZJD3q0VEyI8mq872S3geuNbRUQLVAE9siMfgKrpj7MloKFHruw==", "dev": true }, - "locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "p-filter": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-filter/-/p-filter-4.1.0.tgz", + "integrity": "sha512-37/tPdZ3oJwHaS3gNJdenCDB3Tz26i9sjhnguBtvN0vYlRIiDNnvTWkuh+0hETV9rLPdJ3rlL3yVOYPIAnM8rw==", "dev": true, "requires": { - "p-locate": "^4.1.0" + "p-map": "^7.0.1" } }, - "lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true - }, - "lodash.camelcase": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", - "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==", + "p-is-promise": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-3.0.0.tgz", + "integrity": "sha512-Wo8VsW4IRQSKVXsJCn7TomUaVtyfjVDn3nUP7kE967BQk0CwFpdbZs0X0uk5sW9mkBa9eNM7hCMaG93WUAwxYQ==", "dev": true }, - "lodash.isfunction": { - "version": "3.0.9", - "resolved": "https://registry.npmjs.org/lodash.isfunction/-/lodash.isfunction-3.0.9.tgz", - "integrity": "sha512-AirXNj15uRIMMPihnkInB4i3NHeb4iBtNg9WRWuK2o31S+ePwwNmDPaTL3o7dTJ+VXNZim7rFs4rxN4YU1oUJw==", - "dev": true + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } }, - "lodash.isplainobject": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", - "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==", - "dev": true + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "requires": { + "p-limit": "^2.2.0" + } }, - "lodash.kebabcase": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/lodash.kebabcase/-/lodash.kebabcase-4.1.1.tgz", - "integrity": "sha512-N8XRTIMMqqDgSy4VLKPnJ/+hpGZN+PHQiJnSenYqPaVV/NCqEogTnAdZLQiGKhxX+JCs8waWq2t1XHWKOmlY8g==", + "p-map": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-7.0.2.tgz", + "integrity": "sha512-z4cYYMMdKHzw4O5UkWJImbZynVIo0lSGTXc7bzB1e/rrDqkgGUNysK/o4bTr+0+xKvvLoTyGqYC4Fgljy9qe1Q==", "dev": true }, - "lodash.merge": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "p-reduce": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-reduce/-/p-reduce-3.0.0.tgz", + "integrity": "sha512-xsrIUgI0Kn6iyDYm9StOpOeK29XM1aboGji26+QEortiFST1hGZaUQOLhtEbqHErPpGW/aSz6allwK2qcptp0Q==", "dev": true }, - "lodash.mergewith": { + "p-retry": { "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.mergewith/-/lodash.mergewith-4.6.2.tgz", - "integrity": "sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ==", - "dev": true - }, - "lodash.snakecase": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/lodash.snakecase/-/lodash.snakecase-4.1.1.tgz", - "integrity": "sha512-QZ1d4xoBHYUeuouhEq3lk3Uq7ldgyFXGBhg04+oRLnIz8o9T65Eh+8YdroUwn846zchkA9yDsDl5CVVaV2nqYw==", - "dev": true - }, - "lodash.startcase": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.startcase/-/lodash.startcase-4.4.0.tgz", - "integrity": "sha512-+WKqsK294HMSc2jEbNgpHpd0JfIBhp7rEV4aqXWqFr6AlXov+SlcgB1Fv01y2kGe3Gc8nMW7VA0SrGuSkRfIEg==", - "dev": true - }, - "lodash.uniq": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", - "integrity": "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==", - "dev": true - }, - "lodash.upperfirst": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/lodash.upperfirst/-/lodash.upperfirst-4.3.1.tgz", - "integrity": "sha512-sReKOYJIJf74dhJONhU4e0/shzi1trVbSWDOhKYE5XV2O+H7Sb2Dihwuc7xWxVl+DgFPyTqIN3zMfT9cq5iWDg==", - "dev": true - }, - "lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-4.6.2.tgz", + "integrity": "sha512-312Id396EbJdvRONlngUx0NydfrIQ5lsYu0znKVUzVvArzEIt08V1qhtyESbGVd1FGX7UKtiFp5uwKZdM8wIuQ==", "dev": true, "requires": { - "yallist": "^4.0.0" + "@types/retry": "0.12.0", + "retry": "^0.13.1" } }, - "make-error": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", - "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", - "dev": true - }, - "map-obj": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.3.0.tgz", - "integrity": "sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==", - "dev": true - }, - "media-typer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", "dev": true }, - "memfs": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.5.3.tgz", - "integrity": "sha512-UERzLsxzllchadvbPs5aolHh65ISpKpM+ccLbOJ8/vvpBKmAWf+la7dXFy7Mr0ySHbdHrFv5kGFCUHHe6GFEmw==", + "parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", "dev": true, "requires": { - "fs-monkey": "^1.0.4" + "callsites": "^3.0.0" } }, - "meow": { - "version": "8.1.2", - "resolved": "https://registry.npmjs.org/meow/-/meow-8.1.2.tgz", - "integrity": "sha512-r85E3NdZ+mpYk1C6RjPFEMSE+s1iZMuHtsHAqY0DT3jZczl0diWUZ8g6oU7h0M9cD2EL+PzaYghhCLzR0ZNn5Q==", + "parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", "dev": true, "requires": { - "@types/minimist": "^1.2.0", - "camelcase-keys": "^6.2.2", - "decamelize-keys": "^1.1.0", - "hard-rejection": "^2.1.0", - "minimist-options": "4.1.0", - "normalize-package-data": "^3.0.0", - "read-pkg-up": "^7.0.1", - "redent": "^3.0.0", - "trim-newlines": "^3.0.0", - "type-fest": "^0.18.0", - "yargs-parser": "^20.2.3" + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + } + }, + "parse5": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz", + "integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==", + "requires": { + "entities": "^4.4.0" } }, - "merge-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==", + "parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", "dev": true }, - "merge-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "dev": true }, - "methods": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", "dev": true }, - "micromatch": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", - "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", - "dev": true, - "requires": { - "braces": "^3.0.2", - "picomatch": "^2.3.1" - } - }, - "mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "path-is-inside": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", + "integrity": "sha512-DUWJr3+ULp4zXmol/SZkFf3JGsS9/SIv+Y3Rt93/UjPpDpklB5f1er4O3POIbUuUJ3FXgqte2Q7SrU6zAqwk8w==", "dev": true }, - "mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==" + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true }, - "mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "requires": { - "mime-db": "1.52.0" - } + "path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true }, - "mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==", "dev": true }, - "min-indent": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", - "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", + "path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", "dev": true }, - "minimalistic-assert": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", + "picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", "dev": true }, - "minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } + "picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true }, - "minimist": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==", "dev": true }, - "minimist-options": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-4.1.0.tgz", - "integrity": "sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==", + "pkg-conf": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/pkg-conf/-/pkg-conf-2.1.0.tgz", + "integrity": "sha512-C+VUP+8jis7EsQZIhDYmS5qlNtjv2yP4SNtjXK9AP1ZcTRlnSfuumaTnRfYZnYgUUYVIKqL0fRvmUGDV2fmp6g==", "dev": true, "requires": { - "arrify": "^1.0.1", - "is-plain-obj": "^1.1.0", - "kind-of": "^6.0.3" + "find-up": "^2.0.0", + "load-json-file": "^4.0.0" }, "dependencies": { - "is-plain-obj": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", - "integrity": "sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==", + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==", + "dev": true, + "requires": { + "locate-path": "^2.0.0" + } + }, + "locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==", + "dev": true, + "requires": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + } + }, + "p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "requires": { + "p-try": "^1.0.0" + } + }, + "p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==", + "dev": true, + "requires": { + "p-limit": "^1.1.0" + } + }, + "p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==", + "dev": true + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", "dev": true } } }, - "mkdirp": { - "version": "0.5.6", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", - "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", "dev": true, "requires": { - "minimist": "^1.2.6" + "find-up": "^4.0.0" } }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + "pluralize": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-7.0.0.tgz", + "integrity": "sha512-ARhBOdzS3e41FbkW/XWrTEtukqqLoK5+Z/4UeDaLuSW+39JPeFgs4gCGqsrJHVZX0fUrx//4OF0K1CUGwlIFow==", + "dev": true }, - "multicast-dns": { - "version": "7.2.5", - "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-7.2.5.tgz", - "integrity": "sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg==", + "prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==", + "dev": true + }, + "process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "dev": true + }, + "progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "dev": true + }, + "proto-list": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz", + "integrity": "sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==", + "dev": true + }, + "proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", "dev": true, "requires": { - "dns-packet": "^5.2.2", - "thunky": "^1.0.2" + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "dependencies": { + "ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "dev": true + } } }, - "mute-stream": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", - "integrity": "sha512-r65nCZhrbXXb6dXOACihYApHw2Q6pV0M3V0PSxd74N0+D8nzAdEAITq2oAjA1jVnKI+tGvEBUpqiMh0+rW6zDQ==", + "pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==", "dev": true }, - "natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", - "dev": true + "psl": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", + "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==" }, - "negotiator": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", - "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", - "dev": true + "punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==" }, - "neo-async": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", - "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "q": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", + "integrity": "sha512-kV/CThkXo6xyFEZUugw/+pIOywXcDbFYgSct5cT3gqlbkBE1SJdwy6UQoZvodiWF/ckQLZyDE/Bu1M6gVu5lVw==", "dev": true }, - "node-forge": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz", - "integrity": "sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==", + "qs": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", + "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", + "dev": true, + "requires": { + "side-channel": "^1.0.4" + } + }, + "querystringify": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", + "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==" + }, + "queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", "dev": true }, - "node-releases": { - "version": "2.0.14", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", - "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==", + "quick-lru": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz", + "integrity": "sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==", "dev": true }, - "normalize-package-data": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.3.tgz", - "integrity": "sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==", + "randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", "dev": true, "requires": { - "hosted-git-info": "^4.0.1", - "is-core-module": "^2.5.0", - "semver": "^7.3.4", - "validate-npm-package-license": "^3.0.1" + "safe-buffer": "^5.1.0" } }, - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", "dev": true }, - "npm-run-path": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", - "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "raw-body": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", + "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", "dev": true, "requires": { - "path-key": "^3.0.0" + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "dependencies": { + "bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "dev": true + }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + } } }, - "nwsapi": { - "version": "2.2.9", - "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.9.tgz", - "integrity": "sha512-2f3F0SEEer8bBu0dsNCFF50N0cTThV1nWFYcEYFZttdW0lDAoybv9cQoK7X7/68Z89S7FoRrVjP1LPX4XRf9vg==" - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "dev": true + "rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "dev": true, + "requires": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + } }, - "object-inspect": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", - "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", - "dev": true + "read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "dev": true, + "requires": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "dependencies": { + "hosted-git-info": { + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", + "dev": true + }, + "normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "requires": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true + }, + "type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "dev": true + } + } }, - "obuf": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", - "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==", - "dev": true + "read-pkg-up": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", + "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "dev": true, + "requires": { + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" + }, + "dependencies": { + "type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true + } + } }, - "on-finished": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", - "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", "dev": true, "requires": { - "ee-first": "1.1.1" + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" } }, - "on-headers": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", - "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", - "dev": true + "readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "requires": { + "picomatch": "^2.2.1" + } }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "rechoir": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.7.1.tgz", + "integrity": "sha512-/njmZ8s1wVeR6pjTZ+0nCnv8SpZNRMT2D1RLOJQESlYFDBvwpTA4KWJpZ+sBJ4+vhjILRcK7JIFdGCdxEAAitg==", "dev": true, "requires": { - "wrappy": "1" + "resolve": "^1.9.0" } }, - "onetime": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "redent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", + "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", "dev": true, "requires": { - "mimic-fn": "^2.1.0" + "indent-string": "^4.0.0", + "strip-indent": "^3.0.0" } }, - "open": { - "version": "8.4.2", - "resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz", - "integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==", + "redeyed": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/redeyed/-/redeyed-2.1.1.tgz", + "integrity": "sha512-FNpGGo1DycYAdnrKFxCMmKYgo/mILAqtRYbkdQD8Ep/Hk2PQ5+aEAEx+IU713RTDmuBaH0c8P5ZozurNu5ObRQ==", "dev": true, "requires": { - "define-lazy-prop": "^2.0.0", - "is-docker": "^2.1.1", - "is-wsl": "^2.2.0" + "esprima": "~4.0.0" } }, - "optionator": { - "version": "0.8.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", - "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", + "regexpp": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-1.1.0.tgz", + "integrity": "sha512-LOPw8FpgdQF9etWMaAfG/WRthIdXJGYp4mJ2Jgn/2lpkbod9jPn0t9UqN7AxBOKNfzRbYyVfgc7Vk4t/MpnXgw==", + "dev": true + }, + "registry-auth-token": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-5.0.2.tgz", + "integrity": "sha512-o/3ikDxtXaA59BmZuZrJZDJv8NMDGSj+6j6XaeBmHw8eY1i1qd9+6H+LjVvQXx3HN6aRCGa1cUdJ9RaJZUugnQ==", "dev": true, "requires": { - "deep-is": "~0.1.3", - "fast-levenshtein": "~2.0.6", - "levn": "~0.3.0", - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2", - "word-wrap": "~1.2.3" + "@pnpm/npm-conf": "^2.1.0" } }, - "os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", "dev": true }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true + }, + "require-uncached": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz", + "integrity": "sha512-Xct+41K3twrbBHdxAgMoOS+cNcoqIjfM2/VxBF4LL2hVph7YsF8VSKyQ3BDFZwEVbok9yeDl2le/qo0S77WG2w==", "dev": true, "requires": { - "p-try": "^2.0.0" + "caller-path": "^0.1.0", + "resolve-from": "^1.0.0" + }, + "dependencies": { + "resolve-from": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-1.0.1.tgz", + "integrity": "sha512-kT10v4dhrlLNcnO084hEjvXCI1wUG9qZLoz2RogxqDQQYy7IxjI/iMUkOtQTNEh6rzHxvdQWHsJyel1pKOVCxg==", + "dev": true + } } }, - "p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==" + }, + "resolve": { + "version": "1.22.8", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", + "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", "dev": true, "requires": { - "p-limit": "^2.2.0" + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" } }, - "p-retry": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-4.6.2.tgz", - "integrity": "sha512-312Id396EbJdvRONlngUx0NydfrIQ5lsYu0znKVUzVvArzEIt08V1qhtyESbGVd1FGX7UKtiFp5uwKZdM8wIuQ==", + "resolve-cwd": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", + "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", "dev": true, "requires": { - "@types/retry": "0.12.0", - "retry": "^0.13.1" + "resolve-from": "^5.0.0" } }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", "dev": true }, - "parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "resolve-global": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/resolve-global/-/resolve-global-1.0.0.tgz", + "integrity": "sha512-zFa12V4OLtT5XUX/Q4VLvTfBf+Ok0SPc1FNGM/z9ctUdiU618qwKpWnd0CHs3+RqROfyEg/DhuHbMWYqcgljEw==", "dev": true, "requires": { - "callsites": "^3.0.0" + "global-dirs": "^0.1.1" } }, - "parse-json": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", - "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "restore-cursor": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", + "integrity": "sha512-6IzJLuGi4+R14vwagDHX+JrXmPVtPpn4mffDJ1UdR7/Edm87fl6yi8mMBIVvFtJaNTUvjughmW4hwLhRG7gC1Q==", "dev": true, "requires": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-even-better-errors": "^2.3.0", - "lines-and-columns": "^1.1.6" - } - }, - "parse5": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz", - "integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==", - "requires": { - "entities": "^4.4.0" + "onetime": "^2.0.0", + "signal-exit": "^3.0.2" + }, + "dependencies": { + "mimic-fn": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", + "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", + "dev": true + }, + "onetime": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", + "integrity": "sha512-oyyPpiMaKARvvcgip+JV+7zci5L8D1W9RZIz2l1o08AM3pfspitVWnPt3mzHcBPp12oYMTy0pqrFs/C+m3EwsQ==", + "dev": true, + "requires": { + "mimic-fn": "^1.0.0" + } + } } }, - "parseurl": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", - "dev": true - }, - "path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "dev": true - }, - "path-is-inside": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", - "integrity": "sha512-DUWJr3+ULp4zXmol/SZkFf3JGsS9/SIv+Y3Rt93/UjPpDpklB5f1er4O3POIbUuUJ3FXgqte2Q7SrU6zAqwk8w==", - "dev": true - }, - "path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true - }, - "path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "dev": true - }, - "path-to-regexp": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==", - "dev": true - }, - "path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "dev": true - }, - "picocolors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "retry": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", + "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", "dev": true }, - "picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", "dev": true }, - "pkg-dir": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", - "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", "dev": true, "requires": { - "find-up": "^4.0.0" + "glob": "^7.1.3" } }, - "pluralize": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-7.0.0.tgz", - "integrity": "sha512-ARhBOdzS3e41FbkW/XWrTEtukqqLoK5+Z/4UeDaLuSW+39JPeFgs4gCGqsrJHVZX0fUrx//4OF0K1CUGwlIFow==", - "dev": true - }, - "prelude-ls": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==", - "dev": true - }, - "process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true + "rrweb-cssom": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.6.0.tgz", + "integrity": "sha512-APM0Gt1KoXBz0iIkkdB/kfvGOwC4UuJFeG/c+yV7wSc7q96cG/kJ0HiYCnzivD9SB53cLV1MlHFNfOuPaadYSw==" }, - "progress": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "run-async": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", + "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==", "dev": true }, - "proxy-addr": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", - "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", "dev": true, "requires": { - "forwarded": "0.2.0", - "ipaddr.js": "1.9.1" - }, - "dependencies": { - "ipaddr.js": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", - "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", - "dev": true - } + "queue-microtask": "^1.2.2" } }, - "pseudomap": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", - "integrity": "sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==", + "rx-lite": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-4.0.8.tgz", + "integrity": "sha512-Cun9QucwK6MIrp3mry/Y7hqD1oFqTYLQ4pGxaHTjIdaFDWRGGLikqp6u8LcWJnzpoALg9hap+JGk8sFIUuEGNA==", "dev": true }, - "psl": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", - "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==" - }, - "punycode": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", - "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==" - }, - "qs": { - "version": "6.11.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", - "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", + "rx-lite-aggregates": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/rx-lite-aggregates/-/rx-lite-aggregates-4.0.8.tgz", + "integrity": "sha512-3xPNZGW93oCjiO7PtKxRK6iOVYBWBvtf9QHDfU23Oc+dLIQmAV//UnyXV/yihv81VS/UqoQPk4NegS8EFi55Hg==", "dev": true, "requires": { - "side-channel": "^1.0.4" + "rx-lite": "*" } }, - "querystringify": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", - "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==" - }, - "quick-lru": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz", - "integrity": "sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==", + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", "dev": true }, - "randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "saxes": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz", + "integrity": "sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==", + "requires": { + "xmlchars": "^2.2.0" + } + }, + "schema-utils": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", + "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", "dev": true, "requires": { - "safe-buffer": "^5.1.0" + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" } }, - "range-parser": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", - "dev": true - }, - "raw-body": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", - "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", + "scratch-semantic-release-config": { + "version": "1.0.16", + "resolved": "https://registry.npmjs.org/scratch-semantic-release-config/-/scratch-semantic-release-config-1.0.16.tgz", + "integrity": "sha512-gY2f+aL0t7WyHWsV9vWDJk1VGPm1m2fuRQB4iqZ7XOZY88lH7Mws9/pvFDBSNCEQVDWC7TQxsMudFSUrhSljxA==", "dev": true, "requires": { - "bytes": "3.1.2", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - }, - "dependencies": { - "bytes": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "@semantic-release/changelog": "^6.0.1", + "@semantic-release/commit-analyzer": "^9.0.2", + "@semantic-release/git": "^10.0.1", + "@semantic-release/github": "^8.0.4", + "@semantic-release/npm": "^9.0.1", + "@semantic-release/release-notes-generator": "^10.0.3" + }, + "dependencies": { + "@octokit/auth-token": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-3.0.4.tgz", + "integrity": "sha512-TWFX7cZF2LXoCvdmJWY7XVPi74aSY0+FfBZNSXEXFkMpjcqsQwDSYVv5FhRFaI0V1ECnwbz4j59T/G+rXNWaIQ==", "dev": true }, - "iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "@octokit/core": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/@octokit/core/-/core-4.2.4.tgz", + "integrity": "sha512-rYKilwgzQ7/imScn3M9/pFfUf4I1AZEH3KhyJmtPdE2zfaXAn2mFfUy4FbKewzc2We5y/LlKLj36fWJLKC2SIQ==", "dev": true, "requires": { - "safer-buffer": ">= 2.1.2 < 3" + "@octokit/auth-token": "^3.0.0", + "@octokit/graphql": "^5.0.0", + "@octokit/request": "^6.0.0", + "@octokit/request-error": "^3.0.0", + "@octokit/types": "^9.0.0", + "before-after-hook": "^2.2.0", + "universal-user-agent": "^6.0.0" } - } - } - }, - "read-pkg": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", - "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", - "dev": true, - "requires": { - "@types/normalize-package-data": "^2.4.0", - "normalize-package-data": "^2.5.0", - "parse-json": "^5.0.0", - "type-fest": "^0.6.0" - }, - "dependencies": { - "hosted-git-info": { - "version": "2.8.9", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", - "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", + }, + "@octokit/endpoint": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-7.0.6.tgz", + "integrity": "sha512-5L4fseVRUsDFGR00tMWD/Trdeeihn999rTMGRMC1G/Ldi1uWlWJzI98H4Iak5DB/RVvQuyMYKqSK/R6mbSOQyg==", + "dev": true, + "requires": { + "@octokit/types": "^9.0.0", + "is-plain-object": "^5.0.0", + "universal-user-agent": "^6.0.0" + } + }, + "@octokit/graphql": { + "version": "5.0.6", + "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-5.0.6.tgz", + "integrity": "sha512-Fxyxdy/JH0MnIB5h+UQ3yCoh1FG4kWXfFKkpWqjZHw/p+Kc8Y44Hu/kCgNBT6nU1shNumEchmW/sUO1JuQnPcw==", + "dev": true, + "requires": { + "@octokit/request": "^6.0.0", + "@octokit/types": "^9.0.0", + "universal-user-agent": "^6.0.0" + } + }, + "@octokit/openapi-types": { + "version": "18.1.1", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-18.1.1.tgz", + "integrity": "sha512-VRaeH8nCDtF5aXWnjPuEMIYf1itK/s3JYyJcWFJT8X9pSNnBtriDf7wlEWsGuhPLl4QIH4xM8fqTXDwJ3Mu6sw==", "dev": true }, - "normalize-package-data": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", - "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "@octokit/plugin-paginate-rest": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-6.1.2.tgz", + "integrity": "sha512-qhrmtQeHU/IivxucOV1bbI/xZyC/iOBhclokv7Sut5vnejAIAEXVcGQeRpQlU39E0WwK9lNvJHphHri/DB6lbQ==", + "dev": true, + "requires": { + "@octokit/tsconfig": "^1.0.2", + "@octokit/types": "^9.2.3" + } + }, + "@octokit/plugin-retry": { + "version": "4.1.6", + "resolved": "https://registry.npmjs.org/@octokit/plugin-retry/-/plugin-retry-4.1.6.tgz", + "integrity": "sha512-obkYzIgEC75r8+9Pnfiiqy3y/x1bc3QLE5B7qvv9wi9Kj0R5tGQFC6QMBg1154WQ9lAVypuQDGyp3hNpp15gQQ==", + "dev": true, + "requires": { + "@octokit/types": "^9.0.0", + "bottleneck": "^2.15.3" + } + }, + "@octokit/plugin-throttling": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/@octokit/plugin-throttling/-/plugin-throttling-5.2.3.tgz", + "integrity": "sha512-C9CFg9mrf6cugneKiaI841iG8DOv6P5XXkjmiNNut+swePxQ7RWEdAZRp5rJoE1hjsIqiYcKa/ZkOQ+ujPI39Q==", + "dev": true, + "requires": { + "@octokit/types": "^9.0.0", + "bottleneck": "^2.15.3" + } + }, + "@octokit/request": { + "version": "6.2.8", + "resolved": "https://registry.npmjs.org/@octokit/request/-/request-6.2.8.tgz", + "integrity": "sha512-ow4+pkVQ+6XVVsekSYBzJC0VTVvh/FCTUUgTsboGq+DTeWdyIFV8WSCdo0RIxk6wSkBTHqIK1mYuY7nOBXOchw==", + "dev": true, + "requires": { + "@octokit/endpoint": "^7.0.0", + "@octokit/request-error": "^3.0.0", + "@octokit/types": "^9.0.0", + "is-plain-object": "^5.0.0", + "node-fetch": "^2.6.7", + "universal-user-agent": "^6.0.0" + } + }, + "@octokit/request-error": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-3.0.3.tgz", + "integrity": "sha512-crqw3V5Iy2uOU5Np+8M/YexTlT8zxCfI+qu+LxUB7SZpje4Qmx3mub5DfEKSO8Ylyk0aogi6TYdf6kxzh2BguQ==", + "dev": true, + "requires": { + "@octokit/types": "^9.0.0", + "deprecation": "^2.0.0", + "once": "^1.4.0" + } + }, + "@octokit/types": { + "version": "9.3.2", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-9.3.2.tgz", + "integrity": "sha512-D4iHGTdAnEEVsB8fl95m1hiz7D5YiRdQ9b/OEb3BYRVwbLsGHcRVPz+u+BgRLNk0Q0/4iZCBqDN96j2XNxfXrA==", + "dev": true, + "requires": { + "@octokit/openapi-types": "^18.0.0" + } + }, + "@semantic-release/commit-analyzer": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/@semantic-release/commit-analyzer/-/commit-analyzer-9.0.2.tgz", + "integrity": "sha512-E+dr6L+xIHZkX4zNMe6Rnwg4YQrWNXK+rNsvwOPpdFppvZO1olE2fIgWhv89TkQErygevbjsZFSIxp+u6w2e5g==", + "dev": true, + "requires": { + "conventional-changelog-angular": "^5.0.0", + "conventional-commits-filter": "^2.0.0", + "conventional-commits-parser": "^3.2.3", + "debug": "^4.0.0", + "import-from": "^4.0.0", + "lodash": "^4.17.4", + "micromatch": "^4.0.2" + } + }, + "@semantic-release/error": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@semantic-release/error/-/error-3.0.0.tgz", + "integrity": "sha512-5hiM4Un+tpl4cKw3lV4UgzJj+SmfNIDCLLw0TepzQxz9ZGV5ixnqkzIVF+3tp0ZHgcMKE+VNGHJjEeyFG2dcSw==", + "dev": true + }, + "@semantic-release/github": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@semantic-release/github/-/github-8.1.0.tgz", + "integrity": "sha512-erR9E5rpdsz0dW1I7785JtndQuMWN/iDcemcptf67tBNOmBUN0b2YNOgcjYUnBpgRpZ5ozfBHrK7Bz+2ets/Dg==", + "dev": true, + "requires": { + "@octokit/core": "^4.2.1", + "@octokit/plugin-paginate-rest": "^6.1.2", + "@octokit/plugin-retry": "^4.1.3", + "@octokit/plugin-throttling": "^5.2.3", + "@semantic-release/error": "^3.0.0", + "aggregate-error": "^3.0.0", + "debug": "^4.0.0", + "dir-glob": "^3.0.0", + "fs-extra": "^11.0.0", + "globby": "^11.0.0", + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.0", + "issue-parser": "^6.0.0", + "lodash": "^4.17.4", + "mime": "^3.0.0", + "p-filter": "^2.0.0", + "url-join": "^4.0.0" + } + }, + "@semantic-release/npm": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/@semantic-release/npm/-/npm-9.0.2.tgz", + "integrity": "sha512-zgsynF6McdzxPnFet+a4iO9HpAlARXOM5adz7VGVCvj0ne8wtL2ZOQoDV2wZPDmdEotDIbVeJjafhelZjs9j6g==", + "dev": true, + "requires": { + "@semantic-release/error": "^3.0.0", + "aggregate-error": "^3.0.0", + "execa": "^5.0.0", + "fs-extra": "^11.0.0", + "lodash": "^4.17.15", + "nerf-dart": "^1.0.0", + "normalize-url": "^6.0.0", + "npm": "^8.3.0", + "rc": "^1.2.8", + "read-pkg": "^5.0.0", + "registry-auth-token": "^5.0.0", + "semver": "^7.1.2", + "tempy": "^1.0.0" + } + }, + "@semantic-release/release-notes-generator": { + "version": "10.0.3", + "resolved": "https://registry.npmjs.org/@semantic-release/release-notes-generator/-/release-notes-generator-10.0.3.tgz", + "integrity": "sha512-k4x4VhIKneOWoBGHkx0qZogNjCldLPRiAjnIpMnlUh6PtaWXp/T+C9U7/TaNDDtgDa5HMbHl4WlREdxHio6/3w==", + "dev": true, + "requires": { + "conventional-changelog-angular": "^5.0.0", + "conventional-changelog-writer": "^5.0.0", + "conventional-commits-filter": "^2.0.0", + "conventional-commits-parser": "^3.2.3", + "debug": "^4.0.0", + "get-stream": "^6.0.0", + "import-from": "^4.0.0", + "into-stream": "^6.0.0", + "lodash": "^4.17.4", + "read-pkg-up": "^7.0.0" + } + }, + "aggregate-error": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", + "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", + "dev": true, + "requires": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + } + }, + "clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "dev": true + }, + "conventional-changelog-angular": { + "version": "5.0.13", + "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-5.0.13.tgz", + "integrity": "sha512-i/gipMxs7s8L/QeuavPF2hLnJgH6pEZAttySB6aiQLWcX3puWDL3ACVmvBhJGxnAy52Qc15ua26BufY6KpmrVA==", + "dev": true, + "requires": { + "compare-func": "^2.0.0", + "q": "^1.5.1" + } + }, + "conventional-changelog-writer": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/conventional-changelog-writer/-/conventional-changelog-writer-5.0.1.tgz", + "integrity": "sha512-5WsuKUfxW7suLblAbFnxAcrvf6r+0b7GvNaWUwUIk0bXMnENP/PEieGKVUQrjPqwPT4o3EPAASBXiY6iHooLOQ==", + "dev": true, + "requires": { + "conventional-commits-filter": "^2.0.7", + "dateformat": "^3.0.0", + "handlebars": "^4.7.7", + "json-stringify-safe": "^5.0.1", + "lodash": "^4.17.15", + "meow": "^8.0.0", + "semver": "^6.0.0", + "split": "^1.0.0", + "through2": "^4.0.0" + }, + "dependencies": { + "semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true + } + } + }, + "conventional-commits-filter": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/conventional-commits-filter/-/conventional-commits-filter-2.0.7.tgz", + "integrity": "sha512-ASS9SamOP4TbCClsRHxIHXRfcGCnIoQqkvAzCSbZzTFLfcTqJVugB0agRgsEELsqaeWgsXv513eS116wnlSSPA==", + "dev": true, + "requires": { + "lodash.ismatch": "^4.4.0", + "modify-values": "^1.0.0" + } + }, + "conventional-commits-parser": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-3.2.4.tgz", + "integrity": "sha512-nK7sAtfi+QXbxHCYfhpZsfRtaitZLIA6889kFIouLvz6repszQDgxBu7wf2WbU+Dco7sAnNCJYERCwt54WPC2Q==", + "dev": true, + "requires": { + "is-text-path": "^1.0.1", + "JSONStream": "^1.0.4", + "lodash": "^4.17.15", + "meow": "^8.0.0", + "split2": "^3.0.0", + "through2": "^4.0.0" + } + }, + "crypto-random-string": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz", + "integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==", + "dev": true + }, + "globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dev": true, + "requires": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + } + }, + "ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "dev": true + }, + "into-stream": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/into-stream/-/into-stream-6.0.0.tgz", + "integrity": "sha512-XHbaOAvP+uFKUFsOgoNPRjLkwB+I22JFPFe5OjTkQ0nwgj6+pSjb4NmB6VMxaPshLiOf+zcpOCBQuLwC1KHhZA==", + "dev": true, + "requires": { + "from2": "^2.3.0", + "p-is-promise": "^3.0.0" + } + }, + "is-plain-object": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", + "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", + "dev": true + }, + "mime": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-3.0.0.tgz", + "integrity": "sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==", + "dev": true + }, + "normalize-url": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", + "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==", + "dev": true + }, + "npm": { + "version": "8.19.4", + "resolved": "https://registry.npmjs.org/npm/-/npm-8.19.4.tgz", + "integrity": "sha512-3HANl8i9DKnUA89P4KEgVNN28EjSeDCmvEqbzOAuxCFDzdBZzjUl99zgnGpOUumvW5lvJo2HKcjrsc+tfyv1Hw==", + "dev": true, + "requires": { + "@isaacs/string-locale-compare": "^1.1.0", + "@npmcli/arborist": "^5.6.3", + "@npmcli/ci-detect": "^2.0.0", + "@npmcli/config": "^4.2.1", + "@npmcli/fs": "^2.1.0", + "@npmcli/map-workspaces": "^2.0.3", + "@npmcli/package-json": "^2.0.0", + "@npmcli/run-script": "^4.2.1", + "abbrev": "~1.1.1", + "archy": "~1.0.0", + "cacache": "^16.1.3", + "chalk": "^4.1.2", + "chownr": "^2.0.0", + "cli-columns": "^4.0.0", + "cli-table3": "^0.6.2", + "columnify": "^1.6.0", + "fastest-levenshtein": "^1.0.12", + "fs-minipass": "^2.1.0", + "glob": "^8.0.1", + "graceful-fs": "^4.2.10", + "hosted-git-info": "^5.2.1", + "ini": "^3.0.1", + "init-package-json": "^3.0.2", + "is-cidr": "^4.0.2", + "json-parse-even-better-errors": "^2.3.1", + "libnpmaccess": "^6.0.4", + "libnpmdiff": "^4.0.5", + "libnpmexec": "^4.0.14", + "libnpmfund": "^3.0.5", + "libnpmhook": "^8.0.4", + "libnpmorg": "^4.0.4", + "libnpmpack": "^4.1.3", + "libnpmpublish": "^6.0.5", + "libnpmsearch": "^5.0.4", + "libnpmteam": "^4.0.4", + "libnpmversion": "^3.0.7", + "make-fetch-happen": "^10.2.0", + "minimatch": "^5.1.0", + "minipass": "^3.1.6", + "minipass-pipeline": "^1.2.4", + "mkdirp": "^1.0.4", + "mkdirp-infer-owner": "^2.0.0", + "ms": "^2.1.2", + "node-gyp": "^9.1.0", + "nopt": "^6.0.0", + "npm-audit-report": "^3.0.0", + "npm-install-checks": "^5.0.0", + "npm-package-arg": "^9.1.0", + "npm-pick-manifest": "^7.0.2", + "npm-profile": "^6.2.0", + "npm-registry-fetch": "^13.3.1", + "npm-user-validate": "^1.0.1", + "npmlog": "^6.0.2", + "opener": "^1.5.2", + "p-map": "^4.0.0", + "pacote": "^13.6.2", + "parse-conflict-json": "^2.0.2", + "proc-log": "^2.0.1", + "qrcode-terminal": "^0.12.0", + "read": "~1.0.7", + "read-package-json": "^5.0.2", + "read-package-json-fast": "^2.0.3", + "readdir-scoped-modules": "^1.1.0", + "rimraf": "^3.0.2", + "semver": "^7.3.7", + "ssri": "^9.0.1", + "tar": "^6.1.11", + "text-table": "~0.2.0", + "tiny-relative-date": "^1.3.0", + "treeverse": "^2.0.0", + "validate-npm-package-name": "^4.0.0", + "which": "^2.0.2", + "write-file-atomic": "^4.0.1" + }, + "dependencies": { + "@colors/colors": { + "version": "1.5.0", + "bundled": true, + "dev": true, + "optional": true + }, + "@gar/promisify": { + "version": "1.1.3", + "bundled": true, + "dev": true + }, + "@isaacs/string-locale-compare": { + "version": "1.1.0", + "bundled": true, + "dev": true + }, + "@npmcli/arborist": { + "version": "5.6.3", + "bundled": true, + "dev": true, + "requires": { + "@isaacs/string-locale-compare": "^1.1.0", + "@npmcli/installed-package-contents": "^1.0.7", + "@npmcli/map-workspaces": "^2.0.3", + "@npmcli/metavuln-calculator": "^3.0.1", + "@npmcli/move-file": "^2.0.0", + "@npmcli/name-from-folder": "^1.0.1", + "@npmcli/node-gyp": "^2.0.0", + "@npmcli/package-json": "^2.0.0", + "@npmcli/query": "^1.2.0", + "@npmcli/run-script": "^4.1.3", + "bin-links": "^3.0.3", + "cacache": "^16.1.3", + "common-ancestor-path": "^1.0.1", + "hosted-git-info": "^5.2.1", + "json-parse-even-better-errors": "^2.3.1", + "json-stringify-nice": "^1.1.4", + "minimatch": "^5.1.0", + "mkdirp": "^1.0.4", + "mkdirp-infer-owner": "^2.0.0", + "nopt": "^6.0.0", + "npm-install-checks": "^5.0.0", + "npm-package-arg": "^9.0.0", + "npm-pick-manifest": "^7.0.2", + "npm-registry-fetch": "^13.0.0", + "npmlog": "^6.0.2", + "pacote": "^13.6.1", + "parse-conflict-json": "^2.0.1", + "proc-log": "^2.0.0", + "promise-all-reject-late": "^1.0.0", + "promise-call-limit": "^1.0.1", + "read-package-json-fast": "^2.0.2", + "readdir-scoped-modules": "^1.1.0", + "rimraf": "^3.0.2", + "semver": "^7.3.7", + "ssri": "^9.0.0", + "treeverse": "^2.0.0", + "walk-up-path": "^1.0.0" + } + }, + "@npmcli/ci-detect": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "@npmcli/config": { + "version": "4.2.2", + "bundled": true, + "dev": true, + "requires": { + "@npmcli/map-workspaces": "^2.0.2", + "ini": "^3.0.0", + "mkdirp-infer-owner": "^2.0.0", + "nopt": "^6.0.0", + "proc-log": "^2.0.0", + "read-package-json-fast": "^2.0.3", + "semver": "^7.3.5", + "walk-up-path": "^1.0.0" + } + }, + "@npmcli/disparity-colors": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "requires": { + "ansi-styles": "^4.3.0" + } + }, + "@npmcli/fs": { + "version": "2.1.2", + "bundled": true, + "dev": true, + "requires": { + "@gar/promisify": "^1.1.3", + "semver": "^7.3.5" + } + }, + "@npmcli/git": { + "version": "3.0.2", + "bundled": true, + "dev": true, + "requires": { + "@npmcli/promise-spawn": "^3.0.0", + "lru-cache": "^7.4.4", + "mkdirp": "^1.0.4", + "npm-pick-manifest": "^7.0.0", + "proc-log": "^2.0.0", + "promise-inflight": "^1.0.1", + "promise-retry": "^2.0.1", + "semver": "^7.3.5", + "which": "^2.0.2" + } + }, + "@npmcli/installed-package-contents": { + "version": "1.0.7", + "bundled": true, + "dev": true, + "requires": { + "npm-bundled": "^1.1.1", + "npm-normalize-package-bin": "^1.0.1" + }, + "dependencies": { + "npm-bundled": { + "version": "1.1.2", + "bundled": true, + "dev": true, + "requires": { + "npm-normalize-package-bin": "^1.0.1" + } + } + } + }, + "@npmcli/map-workspaces": { + "version": "2.0.4", + "bundled": true, + "dev": true, + "requires": { + "@npmcli/name-from-folder": "^1.0.1", + "glob": "^8.0.1", + "minimatch": "^5.0.1", + "read-package-json-fast": "^2.0.3" + } + }, + "@npmcli/metavuln-calculator": { + "version": "3.1.1", + "bundled": true, + "dev": true, + "requires": { + "cacache": "^16.0.0", + "json-parse-even-better-errors": "^2.3.1", + "pacote": "^13.0.3", + "semver": "^7.3.5" + } + }, + "@npmcli/move-file": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "requires": { + "mkdirp": "^1.0.4", + "rimraf": "^3.0.2" + } + }, + "@npmcli/name-from-folder": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "@npmcli/node-gyp": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "@npmcli/package-json": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "requires": { + "json-parse-even-better-errors": "^2.3.1" + } + }, + "@npmcli/promise-spawn": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "infer-owner": "^1.0.4" + } + }, + "@npmcli/query": { + "version": "1.2.0", + "bundled": true, + "dev": true, + "requires": { + "npm-package-arg": "^9.1.0", + "postcss-selector-parser": "^6.0.10", + "semver": "^7.3.7" + } + }, + "@npmcli/run-script": { + "version": "4.2.1", + "bundled": true, + "dev": true, + "requires": { + "@npmcli/node-gyp": "^2.0.0", + "@npmcli/promise-spawn": "^3.0.0", + "node-gyp": "^9.0.0", + "read-package-json-fast": "^2.0.3", + "which": "^2.0.2" + } + }, + "@tootallnate/once": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "abbrev": { + "version": "1.1.1", + "bundled": true, + "dev": true + }, + "agent-base": { + "version": "6.0.2", + "bundled": true, + "dev": true, + "requires": { + "debug": "4" + } + }, + "agentkeepalive": { + "version": "4.2.1", + "bundled": true, + "dev": true, + "requires": { + "debug": "^4.1.0", + "depd": "^1.1.2", + "humanize-ms": "^1.2.1" + } + }, + "aggregate-error": { + "version": "3.1.0", + "bundled": true, + "dev": true, + "requires": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + } + }, + "ansi-regex": { + "version": "5.0.1", + "bundled": true, + "dev": true + }, + "ansi-styles": { + "version": "4.3.0", + "bundled": true, + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "aproba": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "archy": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "are-we-there-yet": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "requires": { + "delegates": "^1.0.0", + "readable-stream": "^3.6.0" + } + }, + "asap": { + "version": "2.0.6", + "bundled": true, + "dev": true + }, + "balanced-match": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "bin-links": { + "version": "3.0.3", + "bundled": true, + "dev": true, + "requires": { + "cmd-shim": "^5.0.0", + "mkdirp-infer-owner": "^2.0.0", + "npm-normalize-package-bin": "^2.0.0", + "read-cmd-shim": "^3.0.0", + "rimraf": "^3.0.0", + "write-file-atomic": "^4.0.0" + }, + "dependencies": { + "npm-normalize-package-bin": { + "version": "2.0.0", + "bundled": true, + "dev": true + } + } + }, + "binary-extensions": { + "version": "2.2.0", + "bundled": true, + "dev": true + }, + "brace-expansion": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "requires": { + "balanced-match": "^1.0.0" + } + }, + "builtins": { + "version": "5.0.1", + "bundled": true, + "dev": true, + "requires": { + "semver": "^7.0.0" + } + }, + "cacache": { + "version": "16.1.3", + "bundled": true, + "dev": true, + "requires": { + "@npmcli/fs": "^2.1.0", + "@npmcli/move-file": "^2.0.0", + "chownr": "^2.0.0", + "fs-minipass": "^2.1.0", + "glob": "^8.0.1", + "infer-owner": "^1.0.4", + "lru-cache": "^7.7.1", + "minipass": "^3.1.6", + "minipass-collect": "^1.0.2", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "mkdirp": "^1.0.4", + "p-map": "^4.0.0", + "promise-inflight": "^1.0.1", + "rimraf": "^3.0.2", + "ssri": "^9.0.0", + "tar": "^6.1.11", + "unique-filename": "^2.0.0" + } + }, + "chalk": { + "version": "4.1.2", + "bundled": true, + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "chownr": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "cidr-regex": { + "version": "3.1.1", + "bundled": true, + "dev": true, + "requires": { + "ip-regex": "^4.1.0" + } + }, + "clean-stack": { + "version": "2.2.0", + "bundled": true, + "dev": true + }, + "cli-columns": { + "version": "4.0.0", + "bundled": true, + "dev": true, + "requires": { + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1" + } + }, + "cli-table3": { + "version": "0.6.2", + "bundled": true, + "dev": true, + "requires": { + "@colors/colors": "1.5.0", + "string-width": "^4.2.0" + } + }, + "clone": { + "version": "1.0.4", + "bundled": true, + "dev": true + }, + "cmd-shim": { + "version": "5.0.0", + "bundled": true, + "dev": true, + "requires": { + "mkdirp-infer-owner": "^2.0.0" + } + }, + "color-convert": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "bundled": true, + "dev": true + }, + "color-support": { + "version": "1.1.3", + "bundled": true, + "dev": true + }, + "columnify": { + "version": "1.6.0", + "bundled": true, + "dev": true, + "requires": { + "strip-ansi": "^6.0.1", + "wcwidth": "^1.0.0" + } + }, + "common-ancestor-path": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "bundled": true, + "dev": true + }, + "console-control-strings": { + "version": "1.1.0", + "bundled": true, + "dev": true + }, + "cssesc": { + "version": "3.0.0", + "bundled": true, + "dev": true + }, + "debug": { + "version": "4.3.4", + "bundled": true, + "dev": true, + "requires": { + "ms": "2.1.2" + }, + "dependencies": { + "ms": { + "version": "2.1.2", + "bundled": true, + "dev": true + } + } + }, + "debuglog": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "defaults": { + "version": "1.0.3", + "bundled": true, + "dev": true, + "requires": { + "clone": "^1.0.2" + } + }, + "delegates": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "depd": { + "version": "1.1.2", + "bundled": true, + "dev": true + }, + "dezalgo": { + "version": "1.0.4", + "bundled": true, + "dev": true, + "requires": { + "asap": "^2.0.0", + "wrappy": "1" + } + }, + "diff": { + "version": "5.1.0", + "bundled": true, + "dev": true + }, + "emoji-regex": { + "version": "8.0.0", + "bundled": true, + "dev": true + }, + "encoding": { + "version": "0.1.13", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "iconv-lite": "^0.6.2" + } + }, + "env-paths": { + "version": "2.2.1", + "bundled": true, + "dev": true + }, + "err-code": { + "version": "2.0.3", + "bundled": true, + "dev": true + }, + "fastest-levenshtein": { + "version": "1.0.12", + "bundled": true, + "dev": true + }, + "fs-minipass": { + "version": "2.1.0", + "bundled": true, + "dev": true, + "requires": { + "minipass": "^3.0.0" + } + }, + "fs.realpath": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "function-bind": { + "version": "1.1.1", + "bundled": true, + "dev": true + }, + "gauge": { + "version": "4.0.4", + "bundled": true, + "dev": true, + "requires": { + "aproba": "^1.0.3 || ^2.0.0", + "color-support": "^1.1.3", + "console-control-strings": "^1.1.0", + "has-unicode": "^2.0.1", + "signal-exit": "^3.0.7", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1", + "wide-align": "^1.1.5" + } + }, + "glob": { + "version": "8.0.3", + "bundled": true, + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^5.0.1", + "once": "^1.3.0" + } + }, + "graceful-fs": { + "version": "4.2.10", + "bundled": true, + "dev": true + }, + "has": { + "version": "1.0.3", + "bundled": true, + "dev": true, + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-flag": { + "version": "4.0.0", + "bundled": true, + "dev": true + }, + "has-unicode": { + "version": "2.0.1", + "bundled": true, + "dev": true + }, + "hosted-git-info": { + "version": "5.2.1", + "bundled": true, + "dev": true, + "requires": { + "lru-cache": "^7.5.1" + } + }, + "http-cache-semantics": { + "version": "4.1.1", + "bundled": true, + "dev": true + }, + "http-proxy-agent": { + "version": "5.0.0", + "bundled": true, + "dev": true, + "requires": { + "@tootallnate/once": "2", + "agent-base": "6", + "debug": "4" + } + }, + "https-proxy-agent": { + "version": "5.0.1", + "bundled": true, + "dev": true, + "requires": { + "agent-base": "6", + "debug": "4" + } + }, + "humanize-ms": { + "version": "1.2.1", + "bundled": true, + "dev": true, + "requires": { + "ms": "^2.0.0" + } + }, + "iconv-lite": { + "version": "0.6.3", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + } + }, + "ignore-walk": { + "version": "5.0.1", + "bundled": true, + "dev": true, + "requires": { + "minimatch": "^5.0.1" + } + }, + "imurmurhash": { + "version": "0.1.4", + "bundled": true, + "dev": true + }, + "indent-string": { + "version": "4.0.0", + "bundled": true, + "dev": true + }, + "infer-owner": { + "version": "1.0.4", + "bundled": true, + "dev": true + }, + "inflight": { + "version": "1.0.6", + "bundled": true, + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "bundled": true, + "dev": true + }, + "ini": { + "version": "3.0.1", + "bundled": true, + "dev": true + }, + "init-package-json": { + "version": "3.0.2", + "bundled": true, + "dev": true, + "requires": { + "npm-package-arg": "^9.0.1", + "promzard": "^0.3.0", + "read": "^1.0.7", + "read-package-json": "^5.0.0", + "semver": "^7.3.5", + "validate-npm-package-license": "^3.0.4", + "validate-npm-package-name": "^4.0.0" + } + }, + "ip": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "ip-regex": { + "version": "4.3.0", + "bundled": true, + "dev": true + }, + "is-cidr": { + "version": "4.0.2", + "bundled": true, + "dev": true, + "requires": { + "cidr-regex": "^3.1.1" + } + }, + "is-core-module": { + "version": "2.10.0", + "bundled": true, + "dev": true, + "requires": { + "has": "^1.0.3" + } + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "bundled": true, + "dev": true + }, + "is-lambda": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "isexe": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "json-parse-even-better-errors": { + "version": "2.3.1", + "bundled": true, + "dev": true + }, + "json-stringify-nice": { + "version": "1.1.4", + "bundled": true, + "dev": true + }, + "jsonparse": { + "version": "1.3.1", + "bundled": true, + "dev": true + }, + "just-diff": { + "version": "5.1.1", + "bundled": true, + "dev": true + }, + "just-diff-apply": { + "version": "5.4.1", + "bundled": true, + "dev": true + }, + "libnpmaccess": { + "version": "6.0.4", + "bundled": true, + "dev": true, + "requires": { + "aproba": "^2.0.0", + "minipass": "^3.1.1", + "npm-package-arg": "^9.0.1", + "npm-registry-fetch": "^13.0.0" + } + }, + "libnpmdiff": { + "version": "4.0.5", + "bundled": true, + "dev": true, + "requires": { + "@npmcli/disparity-colors": "^2.0.0", + "@npmcli/installed-package-contents": "^1.0.7", + "binary-extensions": "^2.2.0", + "diff": "^5.1.0", + "minimatch": "^5.0.1", + "npm-package-arg": "^9.0.1", + "pacote": "^13.6.1", + "tar": "^6.1.0" + } + }, + "libnpmexec": { + "version": "4.0.14", + "bundled": true, + "dev": true, + "requires": { + "@npmcli/arborist": "^5.6.3", + "@npmcli/ci-detect": "^2.0.0", + "@npmcli/fs": "^2.1.1", + "@npmcli/run-script": "^4.2.0", + "chalk": "^4.1.0", + "mkdirp-infer-owner": "^2.0.0", + "npm-package-arg": "^9.0.1", + "npmlog": "^6.0.2", + "pacote": "^13.6.1", + "proc-log": "^2.0.0", + "read": "^1.0.7", + "read-package-json-fast": "^2.0.2", + "semver": "^7.3.7", + "walk-up-path": "^1.0.0" + } + }, + "libnpmfund": { + "version": "3.0.5", + "bundled": true, + "dev": true, + "requires": { + "@npmcli/arborist": "^5.6.3" + } + }, + "libnpmhook": { + "version": "8.0.4", + "bundled": true, + "dev": true, + "requires": { + "aproba": "^2.0.0", + "npm-registry-fetch": "^13.0.0" + } + }, + "libnpmorg": { + "version": "4.0.4", + "bundled": true, + "dev": true, + "requires": { + "aproba": "^2.0.0", + "npm-registry-fetch": "^13.0.0" + } + }, + "libnpmpack": { + "version": "4.1.3", + "bundled": true, + "dev": true, + "requires": { + "@npmcli/run-script": "^4.1.3", + "npm-package-arg": "^9.0.1", + "pacote": "^13.6.1" + } + }, + "libnpmpublish": { + "version": "6.0.5", + "bundled": true, + "dev": true, + "requires": { + "normalize-package-data": "^4.0.0", + "npm-package-arg": "^9.0.1", + "npm-registry-fetch": "^13.0.0", + "semver": "^7.3.7", + "ssri": "^9.0.0" + } + }, + "libnpmsearch": { + "version": "5.0.4", + "bundled": true, + "dev": true, + "requires": { + "npm-registry-fetch": "^13.0.0" + } + }, + "libnpmteam": { + "version": "4.0.4", + "bundled": true, + "dev": true, + "requires": { + "aproba": "^2.0.0", + "npm-registry-fetch": "^13.0.0" + } + }, + "libnpmversion": { + "version": "3.0.7", + "bundled": true, + "dev": true, + "requires": { + "@npmcli/git": "^3.0.0", + "@npmcli/run-script": "^4.1.3", + "json-parse-even-better-errors": "^2.3.1", + "proc-log": "^2.0.0", + "semver": "^7.3.7" + } + }, + "lru-cache": { + "version": "7.13.2", + "bundled": true, + "dev": true + }, + "make-fetch-happen": { + "version": "10.2.1", + "bundled": true, + "dev": true, + "requires": { + "agentkeepalive": "^4.2.1", + "cacache": "^16.1.0", + "http-cache-semantics": "^4.1.0", + "http-proxy-agent": "^5.0.0", + "https-proxy-agent": "^5.0.0", + "is-lambda": "^1.0.1", + "lru-cache": "^7.7.1", + "minipass": "^3.1.6", + "minipass-collect": "^1.0.2", + "minipass-fetch": "^2.0.3", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "negotiator": "^0.6.3", + "promise-retry": "^2.0.1", + "socks-proxy-agent": "^7.0.0", + "ssri": "^9.0.0" + } + }, + "minimatch": { + "version": "5.1.0", + "bundled": true, + "dev": true, + "requires": { + "brace-expansion": "^2.0.1" + } + }, + "minipass": { + "version": "3.3.4", + "bundled": true, + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "minipass-collect": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "requires": { + "minipass": "^3.0.0" + } + }, + "minipass-fetch": { + "version": "2.1.1", + "bundled": true, + "dev": true, + "requires": { + "encoding": "^0.1.13", + "minipass": "^3.1.6", + "minipass-sized": "^1.0.3", + "minizlib": "^2.1.2" + } + }, + "minipass-flush": { + "version": "1.0.5", + "bundled": true, + "dev": true, + "requires": { + "minipass": "^3.0.0" + } + }, + "minipass-json-stream": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "requires": { + "jsonparse": "^1.3.1", + "minipass": "^3.0.0" + } + }, + "minipass-pipeline": { + "version": "1.2.4", + "bundled": true, + "dev": true, + "requires": { + "minipass": "^3.0.0" + } + }, + "minipass-sized": { + "version": "1.0.3", + "bundled": true, + "dev": true, + "requires": { + "minipass": "^3.0.0" + } + }, + "minizlib": { + "version": "2.1.2", + "bundled": true, + "dev": true, + "requires": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + } + }, + "mkdirp": { + "version": "1.0.4", + "bundled": true, + "dev": true + }, + "mkdirp-infer-owner": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "requires": { + "chownr": "^2.0.0", + "infer-owner": "^1.0.4", + "mkdirp": "^1.0.3" + } + }, + "ms": { + "version": "2.1.3", + "bundled": true, + "dev": true + }, + "mute-stream": { + "version": "0.0.8", + "bundled": true, + "dev": true + }, + "negotiator": { + "version": "0.6.3", + "bundled": true, + "dev": true + }, + "node-gyp": { + "version": "9.1.0", + "bundled": true, + "dev": true, + "requires": { + "env-paths": "^2.2.0", + "glob": "^7.1.4", + "graceful-fs": "^4.2.6", + "make-fetch-happen": "^10.0.3", + "nopt": "^5.0.0", + "npmlog": "^6.0.0", + "rimraf": "^3.0.2", + "semver": "^7.3.5", + "tar": "^6.1.2", + "which": "^2.0.2" + }, + "dependencies": { + "brace-expansion": { + "version": "1.1.11", + "bundled": true, + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "glob": { + "version": "7.2.3", + "bundled": true, + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "minimatch": { + "version": "3.1.2", + "bundled": true, + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "nopt": { + "version": "5.0.0", + "bundled": true, + "dev": true, + "requires": { + "abbrev": "1" + } + } + } + }, + "nopt": { + "version": "6.0.0", + "bundled": true, + "dev": true, + "requires": { + "abbrev": "^1.0.0" + } + }, + "normalize-package-data": { + "version": "4.0.1", + "bundled": true, + "dev": true, + "requires": { + "hosted-git-info": "^5.0.0", + "is-core-module": "^2.8.1", + "semver": "^7.3.5", + "validate-npm-package-license": "^3.0.4" + } + }, + "npm-audit-report": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "chalk": "^4.0.0" + } + }, + "npm-bundled": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "requires": { + "npm-normalize-package-bin": "^2.0.0" + }, + "dependencies": { + "npm-normalize-package-bin": { + "version": "2.0.0", + "bundled": true, + "dev": true + } + } + }, + "npm-install-checks": { + "version": "5.0.0", + "bundled": true, + "dev": true, + "requires": { + "semver": "^7.1.1" + } + }, + "npm-normalize-package-bin": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "npm-package-arg": { + "version": "9.1.0", + "bundled": true, + "dev": true, + "requires": { + "hosted-git-info": "^5.0.0", + "proc-log": "^2.0.1", + "semver": "^7.3.5", + "validate-npm-package-name": "^4.0.0" + } + }, + "npm-packlist": { + "version": "5.1.3", + "bundled": true, + "dev": true, + "requires": { + "glob": "^8.0.1", + "ignore-walk": "^5.0.1", + "npm-bundled": "^2.0.0", + "npm-normalize-package-bin": "^2.0.0" + }, + "dependencies": { + "npm-normalize-package-bin": { + "version": "2.0.0", + "bundled": true, + "dev": true + } + } + }, + "npm-pick-manifest": { + "version": "7.0.2", + "bundled": true, + "dev": true, + "requires": { + "npm-install-checks": "^5.0.0", + "npm-normalize-package-bin": "^2.0.0", + "npm-package-arg": "^9.0.0", + "semver": "^7.3.5" + }, + "dependencies": { + "npm-normalize-package-bin": { + "version": "2.0.0", + "bundled": true, + "dev": true + } + } + }, + "npm-profile": { + "version": "6.2.1", + "bundled": true, + "dev": true, + "requires": { + "npm-registry-fetch": "^13.0.1", + "proc-log": "^2.0.0" + } + }, + "npm-registry-fetch": { + "version": "13.3.1", + "bundled": true, + "dev": true, + "requires": { + "make-fetch-happen": "^10.0.6", + "minipass": "^3.1.6", + "minipass-fetch": "^2.0.3", + "minipass-json-stream": "^1.0.1", + "minizlib": "^2.1.2", + "npm-package-arg": "^9.0.1", + "proc-log": "^2.0.0" + } + }, + "npm-user-validate": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "npmlog": { + "version": "6.0.2", + "bundled": true, + "dev": true, + "requires": { + "are-we-there-yet": "^3.0.0", + "console-control-strings": "^1.1.0", + "gauge": "^4.0.3", + "set-blocking": "^2.0.0" + } + }, + "once": { + "version": "1.4.0", + "bundled": true, + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "opener": { + "version": "1.5.2", + "bundled": true, + "dev": true + }, + "p-map": { + "version": "4.0.0", + "bundled": true, + "dev": true, + "requires": { + "aggregate-error": "^3.0.0" + } + }, + "pacote": { + "version": "13.6.2", + "bundled": true, + "dev": true, + "requires": { + "@npmcli/git": "^3.0.0", + "@npmcli/installed-package-contents": "^1.0.7", + "@npmcli/promise-spawn": "^3.0.0", + "@npmcli/run-script": "^4.1.0", + "cacache": "^16.0.0", + "chownr": "^2.0.0", + "fs-minipass": "^2.1.0", + "infer-owner": "^1.0.4", + "minipass": "^3.1.6", + "mkdirp": "^1.0.4", + "npm-package-arg": "^9.0.0", + "npm-packlist": "^5.1.0", + "npm-pick-manifest": "^7.0.0", + "npm-registry-fetch": "^13.0.1", + "proc-log": "^2.0.0", + "promise-retry": "^2.0.1", + "read-package-json": "^5.0.0", + "read-package-json-fast": "^2.0.3", + "rimraf": "^3.0.2", + "ssri": "^9.0.0", + "tar": "^6.1.11" + } + }, + "parse-conflict-json": { + "version": "2.0.2", + "bundled": true, + "dev": true, + "requires": { + "json-parse-even-better-errors": "^2.3.1", + "just-diff": "^5.0.1", + "just-diff-apply": "^5.2.0" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "postcss-selector-parser": { + "version": "6.0.10", + "bundled": true, + "dev": true, + "requires": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + } + }, + "proc-log": { + "version": "2.0.1", + "bundled": true, + "dev": true + }, + "promise-all-reject-late": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "promise-call-limit": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "promise-inflight": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "promise-retry": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "requires": { + "err-code": "^2.0.2", + "retry": "^0.12.0" + } + }, + "promzard": { + "version": "0.3.0", + "bundled": true, + "dev": true, + "requires": { + "read": "1" + } + }, + "qrcode-terminal": { + "version": "0.12.0", + "bundled": true, + "dev": true + }, + "read": { + "version": "1.0.7", + "bundled": true, + "dev": true, + "requires": { + "mute-stream": "~0.0.4" + } + }, + "read-cmd-shim": { + "version": "3.0.0", + "bundled": true, + "dev": true + }, + "read-package-json": { + "version": "5.0.2", + "bundled": true, + "dev": true, + "requires": { + "glob": "^8.0.1", + "json-parse-even-better-errors": "^2.3.1", + "normalize-package-data": "^4.0.0", + "npm-normalize-package-bin": "^2.0.0" + }, + "dependencies": { + "npm-normalize-package-bin": { + "version": "2.0.0", + "bundled": true, + "dev": true + } + } + }, + "read-package-json-fast": { + "version": "2.0.3", + "bundled": true, + "dev": true, + "requires": { + "json-parse-even-better-errors": "^2.3.0", + "npm-normalize-package-bin": "^1.0.1" + } + }, + "readable-stream": { + "version": "3.6.0", + "bundled": true, + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "readdir-scoped-modules": { + "version": "1.1.0", + "bundled": true, + "dev": true, + "requires": { + "debuglog": "^1.0.1", + "dezalgo": "^1.0.0", + "graceful-fs": "^4.1.2", + "once": "^1.3.0" + } + }, + "retry": { + "version": "0.12.0", + "bundled": true, + "dev": true + }, + "rimraf": { + "version": "3.0.2", + "bundled": true, + "dev": true, + "requires": { + "glob": "^7.1.3" + }, + "dependencies": { + "brace-expansion": { + "version": "1.1.11", + "bundled": true, + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "glob": { + "version": "7.2.3", + "bundled": true, + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "minimatch": { + "version": "3.1.2", + "bundled": true, + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + } + } + }, + "safe-buffer": { + "version": "5.2.1", + "bundled": true, + "dev": true + }, + "safer-buffer": { + "version": "2.1.2", + "bundled": true, + "dev": true, + "optional": true + }, + "semver": { + "version": "7.3.7", + "bundled": true, + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + }, + "dependencies": { + "lru-cache": { + "version": "6.0.0", + "bundled": true, + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + } + } + }, + "set-blocking": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "signal-exit": { + "version": "3.0.7", + "bundled": true, + "dev": true + }, + "smart-buffer": { + "version": "4.2.0", + "bundled": true, + "dev": true + }, + "socks": { + "version": "2.7.0", + "bundled": true, + "dev": true, + "requires": { + "ip": "^2.0.0", + "smart-buffer": "^4.2.0" + } + }, + "socks-proxy-agent": { + "version": "7.0.0", + "bundled": true, + "dev": true, + "requires": { + "agent-base": "^6.0.2", + "debug": "^4.3.3", + "socks": "^2.6.2" + } + }, + "spdx-correct": { + "version": "3.1.1", + "bundled": true, + "dev": true, + "requires": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-exceptions": { + "version": "2.3.0", + "bundled": true, + "dev": true + }, + "spdx-expression-parse": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "requires": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-license-ids": { + "version": "3.0.11", + "bundled": true, + "dev": true + }, + "ssri": { + "version": "9.0.1", + "bundled": true, + "dev": true, + "requires": { + "minipass": "^3.1.1" + } + }, + "string_decoder": { + "version": "1.3.0", + "bundled": true, + "dev": true, + "requires": { + "safe-buffer": "~5.2.0" + } + }, + "string-width": { + "version": "4.2.3", + "bundled": true, + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + } + }, + "strip-ansi": { + "version": "6.0.1", + "bundled": true, + "dev": true, + "requires": { + "ansi-regex": "^5.0.1" + } + }, + "supports-color": { + "version": "7.2.0", + "bundled": true, + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "tar": { + "version": "6.1.11", + "bundled": true, + "dev": true, + "requires": { + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "minipass": "^3.0.0", + "minizlib": "^2.1.1", + "mkdirp": "^1.0.3", + "yallist": "^4.0.0" + } + }, + "text-table": { + "version": "0.2.0", + "bundled": true, + "dev": true + }, + "tiny-relative-date": { + "version": "1.3.0", + "bundled": true, + "dev": true + }, + "treeverse": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "unique-filename": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "requires": { + "unique-slug": "^3.0.0" + } + }, + "unique-slug": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "imurmurhash": "^0.1.4" + } + }, + "util-deprecate": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "validate-npm-package-license": { + "version": "3.0.4", + "bundled": true, + "dev": true, + "requires": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "validate-npm-package-name": { + "version": "4.0.0", + "bundled": true, + "dev": true, + "requires": { + "builtins": "^5.0.0" + } + }, + "walk-up-path": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "wcwidth": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "requires": { + "defaults": "^1.0.3" + } + }, + "which": { + "version": "2.0.2", + "bundled": true, + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "wide-align": { + "version": "1.1.5", + "bundled": true, + "dev": true, + "requires": { + "string-width": "^1.0.2 || 2 || 3 || 4" + } + }, + "wrappy": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "write-file-atomic": { + "version": "4.0.2", + "bundled": true, + "dev": true, + "requires": { + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.7" + } + }, + "yallist": { + "version": "4.0.0", + "bundled": true, + "dev": true + } + } + }, + "p-filter": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-filter/-/p-filter-2.1.0.tgz", + "integrity": "sha512-ZBxxZ5sL2HghephhpGAQdoskxplTwr7ICaehZwLIlfL6acuVgZPm8yBNuRAFBGEqtD/hmUeq9eqLg2ys9Xr/yw==", "dev": true, "requires": { - "hosted-git-info": "^2.1.4", - "resolve": "^1.10.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" + "p-map": "^2.0.0" } }, - "semver": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "p-map": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz", + "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==", "dev": true }, - "type-fest": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", - "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", "dev": true - } - } - }, - "read-pkg-up": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", - "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", - "dev": true, - "requires": { - "find-up": "^4.1.0", - "read-pkg": "^5.2.0", - "type-fest": "^0.8.1" - }, - "dependencies": { - "type-fest": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", - "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + }, + "temp-dir": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/temp-dir/-/temp-dir-2.0.0.tgz", + "integrity": "sha512-aoBAniQmmwtcKp/7BzsH8Cxzv8OL736p7v1ihGb5e9DJ9kTwGWHrQrVB5+lfVDzfGrdRzXch+ig7LHaY1JTOrg==", "dev": true - } - } - }, - "readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - }, - "readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dev": true, - "requires": { - "picomatch": "^2.2.1" - } - }, - "rechoir": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.7.1.tgz", - "integrity": "sha512-/njmZ8s1wVeR6pjTZ+0nCnv8SpZNRMT2D1RLOJQESlYFDBvwpTA4KWJpZ+sBJ4+vhjILRcK7JIFdGCdxEAAitg==", - "dev": true, - "requires": { - "resolve": "^1.9.0" - } - }, - "redent": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", - "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", - "dev": true, - "requires": { - "indent-string": "^4.0.0", - "strip-indent": "^3.0.0" - } - }, - "regexpp": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-1.1.0.tgz", - "integrity": "sha512-LOPw8FpgdQF9etWMaAfG/WRthIdXJGYp4mJ2Jgn/2lpkbod9jPn0t9UqN7AxBOKNfzRbYyVfgc7Vk4t/MpnXgw==", - "dev": true - }, - "require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", - "dev": true - }, - "require-from-string": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", - "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", - "dev": true - }, - "require-uncached": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz", - "integrity": "sha512-Xct+41K3twrbBHdxAgMoOS+cNcoqIjfM2/VxBF4LL2hVph7YsF8VSKyQ3BDFZwEVbok9yeDl2le/qo0S77WG2w==", - "dev": true, - "requires": { - "caller-path": "^0.1.0", - "resolve-from": "^1.0.0" - }, - "dependencies": { - "resolve-from": { + }, + "tempy": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-1.0.1.tgz", - "integrity": "sha512-kT10v4dhrlLNcnO084hEjvXCI1wUG9qZLoz2RogxqDQQYy7IxjI/iMUkOtQTNEh6rzHxvdQWHsJyel1pKOVCxg==", + "resolved": "https://registry.npmjs.org/tempy/-/tempy-1.0.1.tgz", + "integrity": "sha512-biM9brNqxSc04Ee71hzFbryD11nX7VPhQQY32AdDmjFvodsRFz/3ufeoTZ6uYkRFfGo188tENcASNs3vTdsM0w==", + "dev": true, + "requires": { + "del": "^6.0.0", + "is-stream": "^2.0.0", + "temp-dir": "^2.0.0", + "type-fest": "^0.16.0", + "unique-string": "^2.0.0" + } + }, + "type-fest": { + "version": "0.16.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.16.0.tgz", + "integrity": "sha512-eaBzG6MxNzEn9kiwvtre90cXaNLkmadMWa1zQMs3XORCXNbsH/OewwbxC5ia9dCxIxnTAsSxXJaa/p5y8DlvJg==", + "dev": true + }, + "unique-string": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz", + "integrity": "sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==", + "dev": true, + "requires": { + "crypto-random-string": "^2.0.0" + } + }, + "url-join": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/url-join/-/url-join-4.0.1.tgz", + "integrity": "sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA==", "dev": true } } }, - "requires-port": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", - "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==" - }, - "resolve": { - "version": "1.22.8", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", - "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", - "dev": true, - "requires": { - "is-core-module": "^2.13.0", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - } - }, - "resolve-cwd": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", - "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", - "dev": true, - "requires": { - "resolve-from": "^5.0.0" - } - }, - "resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "select-hose": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", + "integrity": "sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg==", "dev": true }, - "resolve-global": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/resolve-global/-/resolve-global-1.0.0.tgz", - "integrity": "sha512-zFa12V4OLtT5XUX/Q4VLvTfBf+Ok0SPc1FNGM/z9ctUdiU618qwKpWnd0CHs3+RqROfyEg/DhuHbMWYqcgljEw==", + "selfsigned": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-2.4.1.tgz", + "integrity": "sha512-th5B4L2U+eGLq1TVh7zNRGBapioSORUeymIydxgFpwww9d2qyKvtuPU2jJuHvYAwwqi2Y596QBL3eEqcPEYL8Q==", "dev": true, "requires": { - "global-dirs": "^0.1.1" + "@types/node-forge": "^1.3.0", + "node-forge": "^1" } }, - "restore-cursor": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", - "integrity": "sha512-6IzJLuGi4+R14vwagDHX+JrXmPVtPpn4mffDJ1UdR7/Edm87fl6yi8mMBIVvFtJaNTUvjughmW4hwLhRG7gC1Q==", + "semantic-release": { + "version": "22.0.12", + "resolved": "https://registry.npmjs.org/semantic-release/-/semantic-release-22.0.12.tgz", + "integrity": "sha512-0mhiCR/4sZb00RVFJIUlMuiBkW3NMpVIW2Gse7noqEMoFGkvfPPAImEQbkBV8xga4KOPP4FdTRYuLLy32R1fPw==", "dev": true, "requires": { - "onetime": "^2.0.0", - "signal-exit": "^3.0.2" + "@semantic-release/commit-analyzer": "^11.0.0", + "@semantic-release/error": "^4.0.0", + "@semantic-release/github": "^9.0.0", + "@semantic-release/npm": "^11.0.0", + "@semantic-release/release-notes-generator": "^12.0.0", + "aggregate-error": "^5.0.0", + "cosmiconfig": "^8.0.0", + "debug": "^4.0.0", + "env-ci": "^10.0.0", + "execa": "^8.0.0", + "figures": "^6.0.0", + "find-versions": "^5.1.0", + "get-stream": "^6.0.0", + "git-log-parser": "^1.2.0", + "hook-std": "^3.0.0", + "hosted-git-info": "^7.0.0", + "import-from-esm": "^1.3.1", + "lodash-es": "^4.17.21", + "marked": "^9.0.0", + "marked-terminal": "^6.0.0", + "micromatch": "^4.0.2", + "p-each-series": "^3.0.0", + "p-reduce": "^3.0.0", + "read-pkg-up": "^11.0.0", + "resolve-from": "^5.0.0", + "semver": "^7.3.2", + "semver-diff": "^4.0.0", + "signale": "^1.2.1", + "yargs": "^17.5.1" }, "dependencies": { + "execa": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", + "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==", + "dev": true, + "requires": { + "cross-spawn": "^7.0.3", + "get-stream": "^8.0.1", + "human-signals": "^5.0.0", + "is-stream": "^3.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^5.1.0", + "onetime": "^6.0.0", + "signal-exit": "^4.1.0", + "strip-final-newline": "^3.0.0" + }, + "dependencies": { + "get-stream": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", + "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==", + "dev": true + } + } + }, + "figures": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-6.1.0.tgz", + "integrity": "sha512-d+l3qxjSesT4V7v2fh+QnmFnUWv9lSpjarhShNTgBOfA0ttejbQUAlHLitbjkoRiDulW0OPoQPYIGhIC8ohejg==", + "dev": true, + "requires": { + "is-unicode-supported": "^2.0.0" + } + }, + "hosted-git-info": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-7.0.2.tgz", + "integrity": "sha512-puUZAUKT5m8Zzvs72XWy3HtvVbTWljRE66cP60bxJzAqf2DgICo7lYTY2IHUmLnNpjYvw5bvmoHvPc0QO2a62w==", + "dev": true, + "requires": { + "lru-cache": "^10.0.1" + } + }, + "human-signals": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz", + "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==", + "dev": true + }, + "is-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", + "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", + "dev": true + }, + "lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true + }, "mimic-fn": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", - "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", + "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", "dev": true }, + "normalize-package-data": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-6.0.2.tgz", + "integrity": "sha512-V6gygoYb/5EmNI+MEGrWkC+e6+Rr7mTmfHrxDbLzxQogBkgzo76rkok0Am6thgSF7Mv2nLOajAJj5vDJZEFn7g==", + "dev": true, + "requires": { + "hosted-git-info": "^7.0.0", + "semver": "^7.3.5", + "validate-npm-package-license": "^3.0.4" + } + }, + "npm-run-path": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.3.0.tgz", + "integrity": "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==", + "dev": true, + "requires": { + "path-key": "^4.0.0" + } + }, "onetime": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", - "integrity": "sha512-oyyPpiMaKARvvcgip+JV+7zci5L8D1W9RZIz2l1o08AM3pfspitVWnPt3mzHcBPp12oYMTy0pqrFs/C+m3EwsQ==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", + "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", "dev": true, "requires": { - "mimic-fn": "^1.0.0" + "mimic-fn": "^4.0.0" } - } - } - }, - "retry": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", - "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", - "dev": true - }, - "rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "requires": { - "glob": "^7.1.3" + }, + "parse-json": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-8.1.0.tgz", + "integrity": "sha512-rum1bPifK5SSar35Z6EKZuYPJx85pkNaFrxBK3mwdfSJ1/WKbYrjoW/zTPSjRRamfmVX1ACBIdFAO0VRErW/EA==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.22.13", + "index-to-position": "^0.1.2", + "type-fest": "^4.7.1" + } + }, + "path-key": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", + "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", + "dev": true + }, + "read-pkg": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-9.0.1.tgz", + "integrity": "sha512-9viLL4/n1BJUCT1NXVTdS1jtm80yDEgR5T4yCelII49Mbj0v1rZdKqj7zCiYdbB0CuCgdrvHcNogAKTFPBocFA==", + "dev": true, + "requires": { + "@types/normalize-package-data": "^2.4.3", + "normalize-package-data": "^6.0.0", + "parse-json": "^8.0.0", + "type-fest": "^4.6.0", + "unicorn-magic": "^0.1.0" + } + }, + "read-pkg-up": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-11.0.0.tgz", + "integrity": "sha512-LOVbvF1Q0SZdjClSefZ0Nz5z8u+tIE7mV5NibzmE9VYmDe9CaBbAVtz1veOSZbofrdsilxuDAYnFenukZVp8/Q==", + "dev": true, + "requires": { + "find-up-simple": "^1.0.0", + "read-pkg": "^9.0.0", + "type-fest": "^4.6.0" + } + }, + "signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true + }, + "strip-final-newline": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", + "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", + "dev": true + }, + "type-fest": { + "version": "4.26.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.26.1.tgz", + "integrity": "sha512-yOGpmOAL7CkKe/91I5O3gPICmJNLJ1G4zFYVAsRHg7M64biSnPtRj0WNQt++bRkjYOqjWXrhnUw1utzmVErAdg==", + "dev": true + } } }, - "rrweb-cssom": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.6.0.tgz", - "integrity": "sha512-APM0Gt1KoXBz0iIkkdB/kfvGOwC4UuJFeG/c+yV7wSc7q96cG/kJ0HiYCnzivD9SB53cLV1MlHFNfOuPaadYSw==" - }, - "run-async": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", - "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==", - "dev": true - }, - "rx-lite": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-4.0.8.tgz", - "integrity": "sha512-Cun9QucwK6MIrp3mry/Y7hqD1oFqTYLQ4pGxaHTjIdaFDWRGGLikqp6u8LcWJnzpoALg9hap+JGk8sFIUuEGNA==", - "dev": true - }, - "rx-lite-aggregates": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/rx-lite-aggregates/-/rx-lite-aggregates-4.0.8.tgz", - "integrity": "sha512-3xPNZGW93oCjiO7PtKxRK6iOVYBWBvtf9QHDfU23Oc+dLIQmAV//UnyXV/yihv81VS/UqoQPk4NegS8EFi55Hg==", + "semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", "dev": true, "requires": { - "rx-lite": "*" - } - }, - "safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true - }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" - }, - "saxes": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz", - "integrity": "sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==", - "requires": { - "xmlchars": "^2.2.0" + "lru-cache": "^6.0.0" } }, - "schema-utils": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", - "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", + "semver-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-4.0.0.tgz", + "integrity": "sha512-0Ju4+6A8iOnpL/Thra7dZsSlOHYAHIeMxfhWQRI1/VLcT3WDBZKKtQt/QkBOsiIN9ZpuvHE6cGZ0x4glCMmfiA==", "dev": true, "requires": { - "@types/json-schema": "^7.0.8", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" + "semver": "^7.3.5" } }, - "select-hose": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", - "integrity": "sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg==", + "semver-regex": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/semver-regex/-/semver-regex-4.0.5.tgz", + "integrity": "sha512-hunMQrEy1T6Jr2uEVjrAIqjwWcQTgOAcIM52C8MY1EZSD3DDNft04XzvYKPqjED65bNVVko0YI38nYeEHCX3yw==", "dev": true }, - "selfsigned": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-2.4.1.tgz", - "integrity": "sha512-th5B4L2U+eGLq1TVh7zNRGBapioSORUeymIydxgFpwww9d2qyKvtuPU2jJuHvYAwwqi2Y596QBL3eEqcPEYL8Q==", - "dev": true, - "requires": { - "@types/node-forge": "^1.3.0", - "node-forge": "^1" - } - }, - "semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } - }, "send": { "version": "0.18.0", "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", @@ -11507,6 +27075,84 @@ "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", "dev": true }, + "signale": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/signale/-/signale-1.4.0.tgz", + "integrity": "sha512-iuh+gPf28RkltuJC7W5MRi6XAjTDCAPC/prJUpQoG4vIP3MJZ+GTydVnodXA7pwvTKb2cA0m9OFZW/cdWy/I/w==", + "dev": true, + "requires": { + "chalk": "^2.3.2", + "figures": "^2.0.0", + "pkg-conf": "^2.1.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "skin-tone": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/skin-tone/-/skin-tone-2.0.0.tgz", + "integrity": "sha512-kUMbT1oBJCpgrnKoSr0o6wPtvRWT9W9UKvGLwfJYO2WuahZRHOpEyL1ckyMGgMWh0UdpmaoFqKKD29WTomNEGA==", + "dev": true, + "requires": { + "unicode-emoji-modifier-base": "^1.0.0" + } + }, + "slash": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-5.1.0.tgz", + "integrity": "sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==", + "dev": true + }, "slice-ansi": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-1.0.0.tgz", @@ -11568,6 +27214,12 @@ "source-map": "^0.6.0" } }, + "spawn-error-forwarder": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/spawn-error-forwarder/-/spawn-error-forwarder-1.0.0.tgz", + "integrity": "sha512-gRjMgK5uFjbCvdibeGJuy3I5OYz6VLoVdsOJdA6wV0WlfQVLFueoqMxwwYD9RODdgb6oUIvlRlsyFSiQkMKu0g==", + "dev": true + }, "spdx-correct": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", @@ -11627,6 +27279,15 @@ "wbuf": "^1.7.3" } }, + "split": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz", + "integrity": "sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==", + "dev": true, + "requires": { + "through": "2" + } + }, "split2": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/split2/-/split2-3.2.2.tgz", @@ -11648,6 +27309,48 @@ "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", "dev": true }, + "stream-combiner2": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/stream-combiner2/-/stream-combiner2-1.1.1.tgz", + "integrity": "sha512-3PnJbYgS56AeWgtKF5jtJRT6uFJe56Z0Hc5Ngg/6sI6rIt8iiMBTa9cvdyFfpMQjaVHr8dusbNeFGIIonxOvKw==", + "dev": true, + "requires": { + "duplexer2": "~0.1.0", + "readable-stream": "^2.0.2" + }, + "dependencies": { + "readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, "string_decoder": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", @@ -11677,6 +27380,12 @@ "ansi-regex": "^5.0.1" } }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "dev": true + }, "strip-final-newline": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", @@ -11707,6 +27416,27 @@ "has-flag": "^4.0.0" } }, + "supports-hyperlinks": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-3.1.0.tgz", + "integrity": "sha512-2rn0BZ+/f7puLOHZm1HOJfwBggfaHXUpPUSSG/SWM4TWp5KCfmNYwnC3hruy2rZlMnmWZ+QAGpZfchu3f3695A==", + "dev": true, + "requires": { + "has-flag": "^4.0.0", + "supports-color": "^7.0.0" + }, + "dependencies": { + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, "supports-preserve-symlinks-flag": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", @@ -11852,6 +27582,38 @@ "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", "dev": true }, + "temp-dir": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/temp-dir/-/temp-dir-3.0.0.tgz", + "integrity": "sha512-nHc6S/bwIilKHNRgK/3jlhDoIHcp45YgyiwcAk46Tr0LfEqGBVpmiAyuiuxeVE44m3mXnEeVhaipLOEWmH+Njw==", + "dev": true + }, + "tempy": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/tempy/-/tempy-3.1.0.tgz", + "integrity": "sha512-7jDLIdD2Zp0bDe5r3D2qtkd1QOCacylBuL7oa4udvN6v2pqr4+LcCr67C8DR1zkpaZ8XosF5m1yQSabKAW6f2g==", + "dev": true, + "requires": { + "is-stream": "^3.0.0", + "temp-dir": "^3.0.0", + "type-fest": "^2.12.2", + "unique-string": "^3.0.0" + }, + "dependencies": { + "is-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", + "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", + "dev": true + }, + "type-fest": { + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz", + "integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==", + "dev": true + } + } + }, "terser": { "version": "5.26.0", "resolved": "https://registry.npmjs.org/terser/-/terser-5.26.0.tgz", @@ -11953,6 +27715,12 @@ "punycode": "^2.3.1" } }, + "traverse": { + "version": "0.6.8", + "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.6.8.tgz", + "integrity": "sha512-aXJDbk6SnumuaZSANd21XAo15ucCDE38H4fkqiGsc3MhCK+wOlZvLP9cB/TvpHT0mOyWgC4Z8EwRlzqYSUzdsA==", + "dev": true + }, "trim-newlines": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.1.tgz", @@ -12038,12 +27806,46 @@ "integrity": "sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==", "dev": true }, + "uglify-js": { + "version": "3.19.3", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.19.3.tgz", + "integrity": "sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ==", + "dev": true, + "optional": true + }, "undici-types": { "version": "5.26.5", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", "dev": true }, + "unicode-emoji-modifier-base": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unicode-emoji-modifier-base/-/unicode-emoji-modifier-base-1.0.0.tgz", + "integrity": "sha512-yLSH4py7oFH3oG/9K+XWrz1pSi3dfUrWEnInbxMfArOfc1+33BlGPQtLsOYwvdMy11AwUBetYuaRxSPqgkq+8g==", + "dev": true + }, + "unicorn-magic": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.1.0.tgz", + "integrity": "sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ==", + "dev": true + }, + "unique-string": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-3.0.0.tgz", + "integrity": "sha512-VGXBUVwxKMBUznyffQweQABPRRW1vHZAbadFZud4pLFAqRGvv/96vafgjWFqzourzr8YonlQiPgH0YCJfawoGQ==", + "dev": true, + "requires": { + "crypto-random-string": "^4.0.0" + } + }, + "universal-user-agent": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.1.tgz", + "integrity": "sha512-yCzhz6FN2wU1NiiQRogkTQszlQSlpWaw8SvVegAc+bDxbzHgh1vX8uIe8OYyMH6DwH+sdTJsgMl36+mSMdRJIQ==", + "dev": true + }, "universalify": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", @@ -12074,6 +27876,12 @@ "punycode": "^2.1.0" } }, + "url-join": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/url-join/-/url-join-5.0.0.tgz", + "integrity": "sha512-n2huDr9h9yzd6exQVnH/jU5mr+Pfx08LRXXZhkLLetAMESRj+anQsTAh940iMrIetKAmry9coFuZQ2jY8/p3WA==", + "dev": true + }, "url-parse": { "version": "1.5.10", "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", @@ -12425,6 +28233,12 @@ "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", "dev": true }, + "wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==", + "dev": true + }, "wrap-ansi": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", @@ -12467,6 +28281,12 @@ "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==" }, + "xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "dev": true + }, "y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", diff --git a/package.json b/package.json index 260c546ba3..7dfa03160b 100644 --- a/package.json +++ b/package.json @@ -22,6 +22,8 @@ "@commitlint/config-conventional": "^17.8.1", "eslint": "^4.19.1", "husky": "9.1.6", + "scratch-semantic-release-config": "1.0.16", + "semantic-release": "22.0.12", "source-map-loader": "^4.0.1", "ts-loader": "^9.5.1", "typescript": "^5.6.3", From 677ff6f9589ef84b849822e17a705583a55e50db Mon Sep 17 00:00:00 2001 From: Christopher Willis-Ford <7019101+cwillisf@users.noreply.github.com> Date: Fri, 18 Oct 2024 13:46:32 -0700 Subject: [PATCH 113/130] fix(deps): after installing deps, replace Blockly v11 with v12 RC --- .gitignore | 3 +++ package.json | 1 + temp-use-blockly-v12-rc.sh | 26 ++++++++++++++++++++++++++ tsconfig.json | 3 +++ 4 files changed, 33 insertions(+) create mode 100755 temp-use-blockly-v12-rc.sh diff --git a/.gitignore b/.gitignore index ca5e13595f..fb708b5c85 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,6 @@ +# Temporary until Blockly v12 release +/blockly-rc/ + # OSX .DS_Store diff --git a/package.json b/package.json index 7dfa03160b..980da3277f 100644 --- a/package.json +++ b/package.json @@ -13,6 +13,7 @@ "scripts": { "build": "webpack --mode production", "prepare": "husky || true", + "prepublish": "./temp-use-blockly-v12-rc.sh", "start": "webpack serve --open --mode development", "test": "echo \"Error: no test specified\" && exit 1", "test:lint": "eslint ." diff --git a/temp-use-blockly-v12-rc.sh b/temp-use-blockly-v12-rc.sh new file mode 100755 index 0000000000..1b52deac87 --- /dev/null +++ b/temp-use-blockly-v12-rc.sh @@ -0,0 +1,26 @@ +#!/usr/bin/env bash +# vim: set tw=118 ts=2 sw=2 expandtab + +# This script is intended to be run from the root of the scratch-blocks repo. +# This will check out the Blockly v12 Release Candidate branch, +# build it, and link it into node_modules/ + +# TODO: Remove this script once Blockly v12 is available from https://www.npmjs.com/package/blockly + +# WARNING: This uses `npm link`, which causes system-wide changes! + +set -e -x + +if [ ! -d "blockly-rc" ]; then + git clone --branch rc/v12.0.0 git@github.com:google/blockly.git blockly-rc +else + git -C blockly-rc checkout rc/v12.0.0 + git -C blockly-rc pull +fi +npm -C blockly-rc ci +npm -C blockly-rc run package + +# --legacy-peer-deps can be removed once the Blockly plugins used by scratch-blocks support Blockly v12 +# --prefer-offline speeds this up by roughly 2x on my computer (!!) +# --prefer-offline should be OK since we're probably running immediately after a non-offline `npm i` or `npm ci` +npm link --prefer-offline --legacy-peer-deps blockly-rc/dist/ diff --git a/tsconfig.json b/tsconfig.json index 9035b59753..d7603609a0 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,4 +1,7 @@ { + "exclude": [ + "./blockly-rc/" + ], "compilerOptions": { "outDir": "./dist/", "noImplicitAny": true, From 384a6fad293b6a652f1b7bbceb4e2b392a709930 Mon Sep 17 00:00:00 2001 From: Christopher Willis-Ford <7019101+cwillisf@users.noreply.github.com> Date: Fri, 18 Oct 2024 13:57:33 -0700 Subject: [PATCH 114/130] ci: bring back deploy workflow --- .github/workflows/deploy.yml | 38 ++++++++++++++++++++++++++++++++++++ TODO.md | 2 +- 2 files changed, 39 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/deploy.yml diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml new file mode 100644 index 0000000000..75f6b177d3 --- /dev/null +++ b/.github/workflows/deploy.yml @@ -0,0 +1,38 @@ +name: build-scratch-blocks +on: + push: # Runs whenever a commit is pushed to the repository + workflow_dispatch: # Allows you to run this workflow manually from the Actions tab +jobs: + setup: + runs-on: ubuntu-latest + env: + PROJECT_PATH: ./scratch-blocks + steps: + - run: | + for F in chrome chromium chromedriver; do + which $F && $F --version || echo Not found: $F + done + - uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3 + - name: Check Python version + run: python --version + - name: Setup Node + uses: actions/setup-node@1a4442cacd436585916779262731d5b162bc6ec7 # v3 + with: + node-version-file: '.nvmrc' + # TODO: tests + - name: Install Node Dependencies + run: npm ci + - name: Build + run: npm run build + # - name: Deploy playground to GitHub Pages + # uses: peaceiris/actions-gh-pages@373f7f263a76c20808c831209c920827a82a2847 # v3 + # with: + # github_token: ${{ secrets.GITHUB_TOKEN }} + # publish_dir: ./gh-pages + # full_commit_message: "Build for ${{ github.sha }} ${{ github.event.head_commit.message }}" + # enable_jekyll: true + - name: Run semantic-release + env: + NPM_TOKEN: ${{ secrets.NPM_TOKEN }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: npx --no -- semantic-release diff --git a/TODO.md b/TODO.md index 6c0a21d57f..0e190ba3e7 100644 --- a/TODO.md +++ b/TODO.md @@ -4,7 +4,7 @@ Before this un-forked version of `scratch-blocks` is fully ready for release, we - [ ] Hook up i18n / l10n - [x] Fix or remove Husky -- [ ] Set up CI & CD +- [x] Set up CI & CD - [ ] Wait for Blockly v12 release, then update Blockly dependencies accordingly Things we need to do before we consider this project "done" but could wait until after the initial release: From 8a861f0aac2737de08cc3e1c65942a99d21f1ba8 Mon Sep 17 00:00:00 2001 From: Christopher Willis-Ford <7019101+cwillisf@users.noreply.github.com> Date: Fri, 18 Oct 2024 14:05:56 -0700 Subject: [PATCH 115/130] fix(deps): clone Blockly RC over HTTP instead of SSH --- temp-use-blockly-v12-rc.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/temp-use-blockly-v12-rc.sh b/temp-use-blockly-v12-rc.sh index 1b52deac87..fca0495b04 100755 --- a/temp-use-blockly-v12-rc.sh +++ b/temp-use-blockly-v12-rc.sh @@ -12,7 +12,7 @@ set -e -x if [ ! -d "blockly-rc" ]; then - git clone --branch rc/v12.0.0 git@github.com:google/blockly.git blockly-rc + git clone --branch rc/v12.0.0 --single-branch --depth 1 https://github.com/google/blockly.git blockly-rc else git -C blockly-rc checkout rc/v12.0.0 git -C blockly-rc pull From 899a981fb55c60e4b7822e9a77ebb0a65819d094 Mon Sep 17 00:00:00 2001 From: Christopher Willis-Ford <7019101+cwillisf@users.noreply.github.com> Date: Fri, 18 Oct 2024 14:41:14 -0700 Subject: [PATCH 116/130] fix!: bump to v2.0 to reflect Blockly un-forking BREAKING CHANGE: scratch-blocks is no longer a divergent fork of Blockly, and instead depends on Blockly as a regular node_modules dependency. Thanks, @gonfunko and everyone else at Google who helped with this effort! From 21b15d1d8e29eef836615ac45488d856b6a22d01 Mon Sep 17 00:00:00 2001 From: Christopher Willis-Ford <7019101+cwillisf@users.noreply.github.com> Date: Fri, 18 Oct 2024 14:59:05 -0700 Subject: [PATCH 117/130] fix: don't include Blockly RC source in npm package --- .npmignore | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.npmignore b/.npmignore index 89433f5d7a..06c2e230b4 100644 --- a/.npmignore +++ b/.npmignore @@ -1,3 +1,7 @@ +# Temporary until Blockly v12 release +/blockly-rc/ +/temp-use-blockly-v12-rc.sh + # Development files /.circleci .eslintrc From 5beaf502071cb6ee370a451477556efe1638c564 Mon Sep 17 00:00:00 2001 From: Christopher Willis-Ford <7019101+cwillisf@users.noreply.github.com> Date: Sun, 20 Oct 2024 18:16:38 -0700 Subject: [PATCH 118/130] ci: make temporary "spork" release channel --- release.config.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/release.config.js b/release.config.js index 3398114626..a669fae098 100644 --- a/release.config.js +++ b/release.config.js @@ -13,6 +13,10 @@ module.exports = { { name: 'beta', prerelease: true + }, + { + name: 'spork', + prerelease: true } ] }; From 638ee0f1dc8abeb775dc1b5c9fdc2f8dc87fd040 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Mon, 21 Oct 2024 01:19:56 +0000 Subject: [PATCH 119/130] chore(release): 2.0.0-spork.1 [skip ci] # [2.0.0-spork.1](https://github.com/scratchfoundation/scratch-blocks/compare/v1.1.86...v2.0.0-spork.1) (2024-10-21) ### Bug Fixes * Add support for flyout labels with status indicators ([#212](https://github.com/scratchfoundation/scratch-blocks/issues/212)) ([665d196](https://github.com/scratchfoundation/scratch-blocks/commit/665d1963759caab39c1a0078a81e5e3b63734f05)) * add support for Scratch-style block comments ([#83](https://github.com/scratchfoundation/scratch-blocks/issues/83)) ([8902091](https://github.com/scratchfoundation/scratch-blocks/commit/8902091c2da8ab68aeac6e2a3954741197a50b37)) * add support for Scratch-style procedures ([#39](https://github.com/scratchfoundation/scratch-blocks/issues/39)) ([13647eb](https://github.com/scratchfoundation/scratch-blocks/commit/13647eb36439926e82cbe847a643f592702690ab)) * add zoom controls config ([#126](https://github.com/scratchfoundation/scratch-blocks/issues/126)) ([a09ae24](https://github.com/scratchfoundation/scratch-blocks/commit/a09ae248a1c3aa422942b1f9d21487c79c0c4b86)) * allow focusing fields in the flyout on mobile ([#184](https://github.com/scratchfoundation/scratch-blocks/issues/184)) ([6c9d3a6](https://github.com/scratchfoundation/scratch-blocks/commit/6c9d3a6026f67fd4a173c718d7a2ba66b69922f6)) * allow specifying the function to be used for prompting about variable creation/edits ([#106](https://github.com/scratchfoundation/scratch-blocks/issues/106)) ([4cfe66f](https://github.com/scratchfoundation/scratch-blocks/commit/4cfe66fa0419e6140ff6f7cad1c1bfc884917a72)) * clean up data block definitions ([#90](https://github.com/scratchfoundation/scratch-blocks/issues/90)) ([9ea96e2](https://github.com/scratchfoundation/scratch-blocks/commit/9ea96e27f43688bcf81bdc006adac129a1b286c8)) * correctly align extension block icons ([#182](https://github.com/scratchfoundation/scratch-blocks/issues/182)) ([e3dbad1](https://github.com/scratchfoundation/scratch-blocks/commit/e3dbad1feb19c5e72ac66ba9aa9e6f47580a414b)) * delete context menu to display the correct number of blocks ([#127](https://github.com/scratchfoundation/scratch-blocks/issues/127)) ([a65d24a](https://github.com/scratchfoundation/scratch-blocks/commit/a65d24a38daf8a740d5230ee9a7fbac5ae70e2af)) * **deps:** after installing deps, replace Blockly v11 with v12 RC ([677ff6f](https://github.com/scratchfoundation/scratch-blocks/commit/677ff6f9589ef84b849822e17a705583a55e50db)) * **deps:** clone Blockly RC over HTTP instead of SSH ([8a861f0](https://github.com/scratchfoundation/scratch-blocks/commit/8a861f0aac2737de08cc3e1c65942a99d21f1ba8)) * display icons in the toolbox for extension categories ([#47](https://github.com/scratchfoundation/scratch-blocks/issues/47)) ([b53eadd](https://github.com/scratchfoundation/scratch-blocks/commit/b53eaddcf2ca261ea5798f342e0ec600bf60ca19)) * don't hide the drag surface ([#38](https://github.com/scratchfoundation/scratch-blocks/issues/38)) ([7f70f09](https://github.com/scratchfoundation/scratch-blocks/commit/7f70f09e11972be8a6ee512323a0a39a52ef0452)) * don't include Blockly RC source in npm package ([21b15d1](https://github.com/scratchfoundation/scratch-blocks/commit/21b15d1d8e29eef836615ac45488d856b6a22d01)) * don't show global/local options when renaming a variable ([#123](https://github.com/scratchfoundation/scratch-blocks/issues/123)) ([22a6b73](https://github.com/scratchfoundation/scratch-blocks/commit/22a6b733636b738d200c67ae53caee3e072e043a)) * don't show scope options when renaming a variable from the variable getter context menu ([#139](https://github.com/scratchfoundation/scratch-blocks/issues/139)) ([375e56d](https://github.com/scratchfoundation/scratch-blocks/commit/375e56db6918dc3475d5c8f29f53cd03f138e4a7)) * don't warn about procedure references when moving the definition on the workspace ([#131](https://github.com/scratchfoundation/scratch-blocks/issues/131)) ([cda58cc](https://github.com/scratchfoundation/scratch-blocks/commit/cda58ccfa799a0d301d6ba842c6546c1eb9f5614)) * enable and style workspace comments ([#82](https://github.com/scratchfoundation/scratch-blocks/issues/82)) ([98ccb62](https://github.com/scratchfoundation/scratch-blocks/commit/98ccb62d7280d2cc711337581464138a281453e3)) * enable dragging arguments out of procedure blocks ([#119](https://github.com/scratchfoundation/scratch-blocks/issues/119)) ([0ca0620](https://github.com/scratchfoundation/scratch-blocks/commit/0ca0620aad343cdbb1d632ddf3ae73a70085aa03)) * Export colours. ([7c346fa](https://github.com/scratchfoundation/scratch-blocks/commit/7c346fa2424962d7796e42232d9e7db5899dfd5a)) * Export Scratch messages. ([09326a1](https://github.com/scratchfoundation/scratch-blocks/commit/09326a1c82e5dfa4316d426cd745a8f1c52315b9)) * fix a crash when adding a broadcast message ([#150](https://github.com/scratchfoundation/scratch-blocks/issues/150)) ([8e165ce](https://github.com/scratchfoundation/scratch-blocks/commit/8e165cec9a45f5f9d17f2255ed3fd58f834881f7)) * fix alignment of "define" text baseline on custom blocks ([#220](https://github.com/scratchfoundation/scratch-blocks/issues/220)) ([cc4d9f9](https://github.com/scratchfoundation/scratch-blocks/commit/cc4d9f9bc7520313145c4c0cb9978c4dfc6b3bfc)) * fix bug that caused the number/string input in the custom block editor to have square corners ([#213](https://github.com/scratchfoundation/scratch-blocks/issues/213)) ([c3ee958](https://github.com/scratchfoundation/scratch-blocks/commit/c3ee958a5b5b8cf1ae375f82b5dce88a81ee62dd)) * fix bug that could cause duplicated procedure argument blocks to create more duplicates on drag ([#217](https://github.com/scratchfoundation/scratch-blocks/issues/217)) ([6a1c8a9](https://github.com/scratchfoundation/scratch-blocks/commit/6a1c8a9e745d77f2aec49c3cae06dd6836bd58ef)) * fix bug that prevented modal dialogs from appearing on mobile ([#183](https://github.com/scratchfoundation/scratch-blocks/issues/183)) ([37e0f10](https://github.com/scratchfoundation/scratch-blocks/commit/37e0f10f4a59e1bb32734b955b7f2f17e4f2fca0)) * fix bug that prevented showing the contextual menu on blocks ([#176](https://github.com/scratchfoundation/scratch-blocks/issues/176)) ([2e98ff1](https://github.com/scratchfoundation/scratch-blocks/commit/2e98ff15a149b0ff44e30e7023b36d1605030311)) * fix color of block reporter dropdown text ([#205](https://github.com/scratchfoundation/scratch-blocks/issues/205)) ([73d978e](https://github.com/scratchfoundation/scratch-blocks/commit/73d978e6c98d546774398e4d48faa7c181fdac11)) * fix dropdown menu metrics ([#148](https://github.com/scratchfoundation/scratch-blocks/issues/148)) ([40eee91](https://github.com/scratchfoundation/scratch-blocks/commit/40eee91711fb2cc76494221ce2f8b08fc5d9f868)) * fix exception when editing custom blocks ([#105](https://github.com/scratchfoundation/scratch-blocks/issues/105)) ([7478546](https://github.com/scratchfoundation/scratch-blocks/commit/747854658b5db2f4cfc00d827ef00c1081ab3c28)) * fix positioning of categories when scrolling via the toolbox ([#186](https://github.com/scratchfoundation/scratch-blocks/issues/186)) ([6d14530](https://github.com/scratchfoundation/scratch-blocks/commit/6d1453082c3ed220c0ff09bf5b785a49df9f4312)) * fix styling of dropdown menus ([#152](https://github.com/scratchfoundation/scratch-blocks/issues/152)) ([0e80277](https://github.com/scratchfoundation/scratch-blocks/commit/0e802773ce3749a3f74f5fec986aba54312a56cd)) * fix the color of procedure argument blocks ([#216](https://github.com/scratchfoundation/scratch-blocks/issues/216)) ([88c700e](https://github.com/scratchfoundation/scratch-blocks/commit/88c700e40ea9ed05d3a237936ae44d2b62b1424f)) * fix the colors of the angle picker dropdown ([#179](https://github.com/scratchfoundation/scratch-blocks/issues/179)) ([59896d2](https://github.com/scratchfoundation/scratch-blocks/commit/59896d2f55e12f5f28bb8bc615f4b5eb186e0ae6)) * fix the flyout width at 250 pixels ([#168](https://github.com/scratchfoundation/scratch-blocks/issues/168)) ([a47aba6](https://github.com/scratchfoundation/scratch-blocks/commit/a47aba6189fbbb825ad24bd05ab3c8ecdc3dc972)) * fix the styling of contextual menus ([#147](https://github.com/scratchfoundation/scratch-blocks/issues/147)) ([6fbc2e5](https://github.com/scratchfoundation/scratch-blocks/commit/6fbc2e5ef4d24279be3073021319e717963d76e4)) * fix toolbox category selection ([#141](https://github.com/scratchfoundation/scratch-blocks/issues/141)) ([d3e1a1b](https://github.com/scratchfoundation/scratch-blocks/commit/d3e1a1b39099ec8a8ca72f3cac21fac5d588d449)) * fix wrapping of long category labels ([#166](https://github.com/scratchfoundation/scratch-blocks/issues/166)) ([7b39ac1](https://github.com/scratchfoundation/scratch-blocks/commit/7b39ac141bf353edf0cc5379289a33dd3a3ecba8)) * fixed bug where broadcast messages would appear in the variable dropdown list ([#124](https://github.com/scratchfoundation/scratch-blocks/issues/124)) ([b1e67f6](https://github.com/scratchfoundation/scratch-blocks/commit/b1e67f62dcedbd35e1b92d1ec1c773ff74b2ef56)) * hide disable and inline inputs contextual menu items ([#35](https://github.com/scratchfoundation/scratch-blocks/issues/35)) ([c548298](https://github.com/scratchfoundation/scratch-blocks/commit/c548298f3b9cf6baa0c27fdb54b5336538d4abf0)) * improve positioning of newly created procedure blocks ([#121](https://github.com/scratchfoundation/scratch-blocks/issues/121)) ([84a9e5b](https://github.com/scratchfoundation/scratch-blocks/commit/84a9e5b8e9aba2688fd10672a852827311f32259)) * improve reliability of block value reporting ([#77](https://github.com/scratchfoundation/scratch-blocks/issues/77)) ([cb5b068](https://github.com/scratchfoundation/scratch-blocks/commit/cb5b068afa6e781e649754b55fc013a02112431e)) * improve sizing and rendering of comments ([#219](https://github.com/scratchfoundation/scratch-blocks/issues/219)) ([1279c0a](https://github.com/scratchfoundation/scratch-blocks/commit/1279c0aacefb8bbfaaa9786531a56c5a45cf24ee)) * load CSS and fix up UI appearance ([#33](https://github.com/scratchfoundation/scratch-blocks/issues/33)) ([1645129](https://github.com/scratchfoundation/scratch-blocks/commit/1645129950797408d01e3966a9d1b7bdf6223226)) * load the continuous toolbox ([#31](https://github.com/scratchfoundation/scratch-blocks/issues/31)) ([ea68b1c](https://github.com/scratchfoundation/scratch-blocks/commit/ea68b1c25f055288e2ee39f846c17e5861f1a01f)) * make block images work in all contexts ([#30](https://github.com/scratchfoundation/scratch-blocks/issues/30)) ([920febf](https://github.com/scratchfoundation/scratch-blocks/commit/920febf5c3304bcf3a561b1e7c0e016540399540)) * make FieldNumber a subclass of FieldTextInput ([#214](https://github.com/scratchfoundation/scratch-blocks/issues/214)) ([3ae2235](https://github.com/scratchfoundation/scratch-blocks/commit/3ae22356f5ee9ed5da55b744657a033e43ad1ce0)) * make variable names case-sensitive ([#122](https://github.com/scratchfoundation/scratch-blocks/issues/122)) ([46854cd](https://github.com/scratchfoundation/scratch-blocks/commit/46854cdb7c9fe92b8621a9e36acd6f94e9383a9f)) * match Scratch behaviors around dragging and connection stickiness ([#80](https://github.com/scratchfoundation/scratch-blocks/issues/80)) ([fd1bc58](https://github.com/scratchfoundation/scratch-blocks/commit/fd1bc58bdef66697b0630d1c67f5a04d01dfa716)) * miscellaneous UI fixits ([#41](https://github.com/scratchfoundation/scratch-blocks/issues/41)) ([300a1ce](https://github.com/scratchfoundation/scratch-blocks/commit/300a1ce564a55cb65ef2e01792a0ba1149621c50)) * modernize and reenable the colour slider field ([#42](https://github.com/scratchfoundation/scratch-blocks/issues/42)) ([4f97982](https://github.com/scratchfoundation/scratch-blocks/commit/4f979828f1122d5cf314a8de464457ae8b925ed7)) * more closely align flyout layout with Scratch ([#45](https://github.com/scratchfoundation/scratch-blocks/issues/45)) ([49663ed](https://github.com/scratchfoundation/scratch-blocks/commit/49663ed2f823ea45a04c0201d467d4e06e0d7078)) * prevent deleting procedure definition blocks with references by dragging to the flyout ([#120](https://github.com/scratchfoundation/scratch-blocks/issues/120)) ([fa9367d](https://github.com/scratchfoundation/scratch-blocks/commit/fa9367d975e8c3fd45321248eb365c9cd0477dbb)) * prevent dragging blocks into the slot occupied by the procedure definition block's example caller block ([#118](https://github.com/scratchfoundation/scratch-blocks/issues/118)) ([453ffa9](https://github.com/scratchfoundation/scratch-blocks/commit/453ffa9654927be023571f5bb496a1d0ff36aad9)) * re-export scratch-blocks utility functions ([#26](https://github.com/scratchfoundation/scratch-blocks/issues/26)) ([685ecfc](https://github.com/scratchfoundation/scratch-blocks/commit/685ecfc0ce9f3c9335393f5af71eb3755aabedd4)) * readd the control blocks ([#22](https://github.com/scratchfoundation/scratch-blocks/issues/22)) ([f69d4ac](https://github.com/scratchfoundation/scratch-blocks/commit/f69d4ac8ebd128b318919f4a3ac5222d211adfbb)) * readd the data blocks ([#29](https://github.com/scratchfoundation/scratch-blocks/issues/29)) ([fafed65](https://github.com/scratchfoundation/scratch-blocks/commit/fafed65e73f59877200741c36244d082f2b3aad1)) * readd the event blocks ([#21](https://github.com/scratchfoundation/scratch-blocks/issues/21)) ([4de530f](https://github.com/scratchfoundation/scratch-blocks/commit/4de530f00310ee27c0ad55940c9cb6bf1208df91)) * readd the looks blocks ([#23](https://github.com/scratchfoundation/scratch-blocks/issues/23)) ([34f07c0](https://github.com/scratchfoundation/scratch-blocks/commit/34f07c0ed7982963ded8563b5f45d374e740d98c)) * readd the motion blocks ([#20](https://github.com/scratchfoundation/scratch-blocks/issues/20)) ([79398c2](https://github.com/scratchfoundation/scratch-blocks/commit/79398c2ebae7329d0d428bab5870e559423ab36b)) * readd the operator blocks and dependencies ([#19](https://github.com/scratchfoundation/scratch-blocks/issues/19)) ([8024e9f](https://github.com/scratchfoundation/scratch-blocks/commit/8024e9fd638586d26e6b47424e0067c0387af8cd)) * readd the sensing blocks ([#27](https://github.com/scratchfoundation/scratch-blocks/issues/27)) ([9f5f135](https://github.com/scratchfoundation/scratch-blocks/commit/9f5f1351be5818fb9392214b8047acace8333a65)) * readd the sound blocks ([#24](https://github.com/scratchfoundation/scratch-blocks/issues/24)) ([6837513](https://github.com/scratchfoundation/scratch-blocks/commit/6837513d3f217e94522a3ce756273d6ff8e7538c)) * reenable reporting block values ([#55](https://github.com/scratchfoundation/scratch-blocks/issues/55)) ([70c8cfd](https://github.com/scratchfoundation/scratch-blocks/commit/70c8cfd73ee1081eafcb2773fe56a4e078cb2bea)) * reenable shadows for blocks being dragged ([#79](https://github.com/scratchfoundation/scratch-blocks/issues/79)) ([94d2a2c](https://github.com/scratchfoundation/scratch-blocks/commit/94d2a2ca55c0d0265a79237610bcf8c246d74a9b)) * reenable support for checkboxes in the flyout ([#43](https://github.com/scratchfoundation/scratch-blocks/issues/43)) ([e603c67](https://github.com/scratchfoundation/scratch-blocks/commit/e603c67cf7c55ff09c292991ef6b9f9ac3aae0f9)) * reenable support for dragging blocks between sprites ([#130](https://github.com/scratchfoundation/scratch-blocks/issues/130)) ([3d8b998](https://github.com/scratchfoundation/scratch-blocks/commit/3d8b998f3be7e76adf313a60b81f29b871266c94)) * reenable the matrix field ([#49](https://github.com/scratchfoundation/scratch-blocks/issues/49)) ([aa3341b](https://github.com/scratchfoundation/scratch-blocks/commit/aa3341b69e51de847f177124660a304e2bca8446)) * reenable the mobile numpad field ([#54](https://github.com/scratchfoundation/scratch-blocks/issues/54)) ([003afd0](https://github.com/scratchfoundation/scratch-blocks/commit/003afd04b98ae1d3688b5356885e27c116fc61ac)) * reenable the note block and picker field ([#48](https://github.com/scratchfoundation/scratch-blocks/issues/48)) ([de62d77](https://github.com/scratchfoundation/scratch-blocks/commit/de62d7752eb80f67a654ae2e87820ad4183e833d)) * reenable the vertical separator field ([#46](https://github.com/scratchfoundation/scratch-blocks/issues/46)) ([48e931f](https://github.com/scratchfoundation/scratch-blocks/commit/48e931fa9de3e31b18f088557c2cbfd0738b4bc6)) * remove canvas transition ([#129](https://github.com/scratchfoundation/scratch-blocks/issues/129)) ([ff4b115](https://github.com/scratchfoundation/scratch-blocks/commit/ff4b1151d702be0be5dabf1f1032fd08b8d58e3e)) * remove underscore from a few createProcedureDefCallback calls ([#40](https://github.com/scratchfoundation/scratch-blocks/issues/40)) ([4e794f6](https://github.com/scratchfoundation/scratch-blocks/commit/4e794f6503dfba1d12f9e99905660d305d34e309)) * render the procedure definition block like Scratch ([#115](https://github.com/scratchfoundation/scratch-blocks/issues/115)) ([2a543f5](https://github.com/scratchfoundation/scratch-blocks/commit/2a543f56f6d45bcc970cfe56dbfdea6ff26c833a)) * resolve error when adding the stop block to the workspace ([#56](https://github.com/scratchfoundation/scratch-blocks/issues/56)) ([f3e059c](https://github.com/scratchfoundation/scratch-blocks/commit/f3e059cbf5cf3ce4e063871632a213c8d58f1000)) * resolve various UI issues ([#117](https://github.com/scratchfoundation/scratch-blocks/issues/117)) ([4b74d5c](https://github.com/scratchfoundation/scratch-blocks/commit/4b74d5ca4ffaf7dfd7c040bce5cfd725c96d848a)) * select new variable blocks' monitor checkboxes after creation ([#140](https://github.com/scratchfoundation/scratch-blocks/issues/140)) ([3811d93](https://github.com/scratchfoundation/scratch-blocks/commit/3811d93f57c2a72a8a830a7326e2d27694bec7b7)) * show connection highlights for boolean inputs ([#181](https://github.com/scratchfoundation/scratch-blocks/issues/181)) ([303611a](https://github.com/scratchfoundation/scratch-blocks/commit/303611a5475b4c5914d14c7fa04915d0cb0a0d03)) * show the glow only when blocks are running ([#57](https://github.com/scratchfoundation/scratch-blocks/issues/57)) ([33e9e91](https://github.com/scratchfoundation/scratch-blocks/commit/33e9e91be1210c1699bc3491df5d9c7c191bc30d)) * show the name of the list in the list getter block context menu ([#132](https://github.com/scratchfoundation/scratch-blocks/issues/132)) ([eb839fc](https://github.com/scratchfoundation/scratch-blocks/commit/eb839fcef9e8befad591cf35c00044adff9269f6)) * update the flyout for compatibility with the new flyout API ([#209](https://github.com/scratchfoundation/scratch-blocks/issues/209)) ([7ce9991](https://github.com/scratchfoundation/scratch-blocks/commit/7ce9991b6f1b6a504847097ebd098f0ec1e50e52)) * use non-deprecated input type constants ([#78](https://github.com/scratchfoundation/scratch-blocks/issues/78)) ([1f1c859](https://github.com/scratchfoundation/scratch-blocks/commit/1f1c8598a5dac8bb42dd82fff7edc7eda7fe4225)) * use Scratch-style text blocks ([#37](https://github.com/scratchfoundation/scratch-blocks/issues/37)) ([6bbbdf7](https://github.com/scratchfoundation/scratch-blocks/commit/6bbbdf763ba43d3dc0af7bad15478f848455f4df)) * use Scratch's FieldAngle ([#138](https://github.com/scratchfoundation/scratch-blocks/issues/138)) ([ef7911c](https://github.com/scratchfoundation/scratch-blocks/commit/ef7911cf7fd12d6370733bdd3778560925bd050c)) * fix!: bump to v2.0 to reflect Blockly un-forking ([899a981](https://github.com/scratchfoundation/scratch-blocks/commit/899a981fb55c60e4b7822e9a77ebb0a65819d094)) ### Features * add a block inflater that supports recycling ([#207](https://github.com/scratchfoundation/scratch-blocks/issues/207)) ([0701679](https://github.com/scratchfoundation/scratch-blocks/commit/07016799832530cf851c14be484158e58bdaa9dd)) * add bubbles/icons for block flyout checkboxes ([#208](https://github.com/scratchfoundation/scratch-blocks/issues/208)) ([39b2162](https://github.com/scratchfoundation/scratch-blocks/commit/39b2162db62973860c904f0b78f1d7f27abebc99)) * add custom Scratch variable model and creation event classes ([#86](https://github.com/scratchfoundation/scratch-blocks/issues/86)) ([2598ede](https://github.com/scratchfoundation/scratch-blocks/commit/2598ede046de74164922bd919695eae65bd0c9b2)) * clean up and export Scratch's variables.js ([#88](https://github.com/scratchfoundation/scratch-blocks/issues/88)) ([5c1acfe](https://github.com/scratchfoundation/scratch-blocks/commit/5c1acfe3dc1bb0bf406ba20ffd1e25b22356fbd7)) * readd support for the custom Data toolbox category ([#87](https://github.com/scratchfoundation/scratch-blocks/issues/87)) ([dcfbf39](https://github.com/scratchfoundation/scratch-blocks/commit/dcfbf391cfcf2dbdf04c84b7e5c4d1463c18ed1d)) * reenable Scratch's FieldVariable subclass ([#91](https://github.com/scratchfoundation/scratch-blocks/issues/91)) ([7c891e3](https://github.com/scratchfoundation/scratch-blocks/commit/7c891e35207b6f561917f27739917cb84755d57c)) ### Reverts * Revert "fix: add zoom controls config (#126)" (#128) ([8e1dc14](https://github.com/scratchfoundation/scratch-blocks/commit/8e1dc14483d6e012734a30b666af7aa5427c58f9)), closes [#126](https://github.com/scratchfoundation/scratch-blocks/issues/126) [#128](https://github.com/scratchfoundation/scratch-blocks/issues/128) ### BREAKING CHANGES * scratch-blocks is no longer a divergent fork of Blockly, and instead depends on Blockly as a regular node_modules dependency. Thanks, @gonfunko and everyone else at Google who helped with this effort! --- CHANGELOG.md | 118 ++++++++++++++++++++++++++++++++++++++++++++++ package-lock.json | 4 +- package.json | 2 +- 3 files changed, 121 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ba82b7a33f..ed42163ecc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,124 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [2.0.0-spork.1](https://github.com/scratchfoundation/scratch-blocks/compare/v1.1.86...v2.0.0-spork.1) (2024-10-21) + + +### Bug Fixes + +* Add support for flyout labels with status indicators ([#212](https://github.com/scratchfoundation/scratch-blocks/issues/212)) ([665d196](https://github.com/scratchfoundation/scratch-blocks/commit/665d1963759caab39c1a0078a81e5e3b63734f05)) +* add support for Scratch-style block comments ([#83](https://github.com/scratchfoundation/scratch-blocks/issues/83)) ([8902091](https://github.com/scratchfoundation/scratch-blocks/commit/8902091c2da8ab68aeac6e2a3954741197a50b37)) +* add support for Scratch-style procedures ([#39](https://github.com/scratchfoundation/scratch-blocks/issues/39)) ([13647eb](https://github.com/scratchfoundation/scratch-blocks/commit/13647eb36439926e82cbe847a643f592702690ab)) +* add zoom controls config ([#126](https://github.com/scratchfoundation/scratch-blocks/issues/126)) ([a09ae24](https://github.com/scratchfoundation/scratch-blocks/commit/a09ae248a1c3aa422942b1f9d21487c79c0c4b86)) +* allow focusing fields in the flyout on mobile ([#184](https://github.com/scratchfoundation/scratch-blocks/issues/184)) ([6c9d3a6](https://github.com/scratchfoundation/scratch-blocks/commit/6c9d3a6026f67fd4a173c718d7a2ba66b69922f6)) +* allow specifying the function to be used for prompting about variable creation/edits ([#106](https://github.com/scratchfoundation/scratch-blocks/issues/106)) ([4cfe66f](https://github.com/scratchfoundation/scratch-blocks/commit/4cfe66fa0419e6140ff6f7cad1c1bfc884917a72)) +* clean up data block definitions ([#90](https://github.com/scratchfoundation/scratch-blocks/issues/90)) ([9ea96e2](https://github.com/scratchfoundation/scratch-blocks/commit/9ea96e27f43688bcf81bdc006adac129a1b286c8)) +* correctly align extension block icons ([#182](https://github.com/scratchfoundation/scratch-blocks/issues/182)) ([e3dbad1](https://github.com/scratchfoundation/scratch-blocks/commit/e3dbad1feb19c5e72ac66ba9aa9e6f47580a414b)) +* delete context menu to display the correct number of blocks ([#127](https://github.com/scratchfoundation/scratch-blocks/issues/127)) ([a65d24a](https://github.com/scratchfoundation/scratch-blocks/commit/a65d24a38daf8a740d5230ee9a7fbac5ae70e2af)) +* **deps:** after installing deps, replace Blockly v11 with v12 RC ([677ff6f](https://github.com/scratchfoundation/scratch-blocks/commit/677ff6f9589ef84b849822e17a705583a55e50db)) +* **deps:** clone Blockly RC over HTTP instead of SSH ([8a861f0](https://github.com/scratchfoundation/scratch-blocks/commit/8a861f0aac2737de08cc3e1c65942a99d21f1ba8)) +* display icons in the toolbox for extension categories ([#47](https://github.com/scratchfoundation/scratch-blocks/issues/47)) ([b53eadd](https://github.com/scratchfoundation/scratch-blocks/commit/b53eaddcf2ca261ea5798f342e0ec600bf60ca19)) +* don't hide the drag surface ([#38](https://github.com/scratchfoundation/scratch-blocks/issues/38)) ([7f70f09](https://github.com/scratchfoundation/scratch-blocks/commit/7f70f09e11972be8a6ee512323a0a39a52ef0452)) +* don't include Blockly RC source in npm package ([21b15d1](https://github.com/scratchfoundation/scratch-blocks/commit/21b15d1d8e29eef836615ac45488d856b6a22d01)) +* don't show global/local options when renaming a variable ([#123](https://github.com/scratchfoundation/scratch-blocks/issues/123)) ([22a6b73](https://github.com/scratchfoundation/scratch-blocks/commit/22a6b733636b738d200c67ae53caee3e072e043a)) +* don't show scope options when renaming a variable from the variable getter context menu ([#139](https://github.com/scratchfoundation/scratch-blocks/issues/139)) ([375e56d](https://github.com/scratchfoundation/scratch-blocks/commit/375e56db6918dc3475d5c8f29f53cd03f138e4a7)) +* don't warn about procedure references when moving the definition on the workspace ([#131](https://github.com/scratchfoundation/scratch-blocks/issues/131)) ([cda58cc](https://github.com/scratchfoundation/scratch-blocks/commit/cda58ccfa799a0d301d6ba842c6546c1eb9f5614)) +* enable and style workspace comments ([#82](https://github.com/scratchfoundation/scratch-blocks/issues/82)) ([98ccb62](https://github.com/scratchfoundation/scratch-blocks/commit/98ccb62d7280d2cc711337581464138a281453e3)) +* enable dragging arguments out of procedure blocks ([#119](https://github.com/scratchfoundation/scratch-blocks/issues/119)) ([0ca0620](https://github.com/scratchfoundation/scratch-blocks/commit/0ca0620aad343cdbb1d632ddf3ae73a70085aa03)) +* Export colours. ([7c346fa](https://github.com/scratchfoundation/scratch-blocks/commit/7c346fa2424962d7796e42232d9e7db5899dfd5a)) +* Export Scratch messages. ([09326a1](https://github.com/scratchfoundation/scratch-blocks/commit/09326a1c82e5dfa4316d426cd745a8f1c52315b9)) +* fix a crash when adding a broadcast message ([#150](https://github.com/scratchfoundation/scratch-blocks/issues/150)) ([8e165ce](https://github.com/scratchfoundation/scratch-blocks/commit/8e165cec9a45f5f9d17f2255ed3fd58f834881f7)) +* fix alignment of "define" text baseline on custom blocks ([#220](https://github.com/scratchfoundation/scratch-blocks/issues/220)) ([cc4d9f9](https://github.com/scratchfoundation/scratch-blocks/commit/cc4d9f9bc7520313145c4c0cb9978c4dfc6b3bfc)) +* fix bug that caused the number/string input in the custom block editor to have square corners ([#213](https://github.com/scratchfoundation/scratch-blocks/issues/213)) ([c3ee958](https://github.com/scratchfoundation/scratch-blocks/commit/c3ee958a5b5b8cf1ae375f82b5dce88a81ee62dd)) +* fix bug that could cause duplicated procedure argument blocks to create more duplicates on drag ([#217](https://github.com/scratchfoundation/scratch-blocks/issues/217)) ([6a1c8a9](https://github.com/scratchfoundation/scratch-blocks/commit/6a1c8a9e745d77f2aec49c3cae06dd6836bd58ef)) +* fix bug that prevented modal dialogs from appearing on mobile ([#183](https://github.com/scratchfoundation/scratch-blocks/issues/183)) ([37e0f10](https://github.com/scratchfoundation/scratch-blocks/commit/37e0f10f4a59e1bb32734b955b7f2f17e4f2fca0)) +* fix bug that prevented showing the contextual menu on blocks ([#176](https://github.com/scratchfoundation/scratch-blocks/issues/176)) ([2e98ff1](https://github.com/scratchfoundation/scratch-blocks/commit/2e98ff15a149b0ff44e30e7023b36d1605030311)) +* fix color of block reporter dropdown text ([#205](https://github.com/scratchfoundation/scratch-blocks/issues/205)) ([73d978e](https://github.com/scratchfoundation/scratch-blocks/commit/73d978e6c98d546774398e4d48faa7c181fdac11)) +* fix dropdown menu metrics ([#148](https://github.com/scratchfoundation/scratch-blocks/issues/148)) ([40eee91](https://github.com/scratchfoundation/scratch-blocks/commit/40eee91711fb2cc76494221ce2f8b08fc5d9f868)) +* fix exception when editing custom blocks ([#105](https://github.com/scratchfoundation/scratch-blocks/issues/105)) ([7478546](https://github.com/scratchfoundation/scratch-blocks/commit/747854658b5db2f4cfc00d827ef00c1081ab3c28)) +* fix positioning of categories when scrolling via the toolbox ([#186](https://github.com/scratchfoundation/scratch-blocks/issues/186)) ([6d14530](https://github.com/scratchfoundation/scratch-blocks/commit/6d1453082c3ed220c0ff09bf5b785a49df9f4312)) +* fix styling of dropdown menus ([#152](https://github.com/scratchfoundation/scratch-blocks/issues/152)) ([0e80277](https://github.com/scratchfoundation/scratch-blocks/commit/0e802773ce3749a3f74f5fec986aba54312a56cd)) +* fix the color of procedure argument blocks ([#216](https://github.com/scratchfoundation/scratch-blocks/issues/216)) ([88c700e](https://github.com/scratchfoundation/scratch-blocks/commit/88c700e40ea9ed05d3a237936ae44d2b62b1424f)) +* fix the colors of the angle picker dropdown ([#179](https://github.com/scratchfoundation/scratch-blocks/issues/179)) ([59896d2](https://github.com/scratchfoundation/scratch-blocks/commit/59896d2f55e12f5f28bb8bc615f4b5eb186e0ae6)) +* fix the flyout width at 250 pixels ([#168](https://github.com/scratchfoundation/scratch-blocks/issues/168)) ([a47aba6](https://github.com/scratchfoundation/scratch-blocks/commit/a47aba6189fbbb825ad24bd05ab3c8ecdc3dc972)) +* fix the styling of contextual menus ([#147](https://github.com/scratchfoundation/scratch-blocks/issues/147)) ([6fbc2e5](https://github.com/scratchfoundation/scratch-blocks/commit/6fbc2e5ef4d24279be3073021319e717963d76e4)) +* fix toolbox category selection ([#141](https://github.com/scratchfoundation/scratch-blocks/issues/141)) ([d3e1a1b](https://github.com/scratchfoundation/scratch-blocks/commit/d3e1a1b39099ec8a8ca72f3cac21fac5d588d449)) +* fix wrapping of long category labels ([#166](https://github.com/scratchfoundation/scratch-blocks/issues/166)) ([7b39ac1](https://github.com/scratchfoundation/scratch-blocks/commit/7b39ac141bf353edf0cc5379289a33dd3a3ecba8)) +* fixed bug where broadcast messages would appear in the variable dropdown list ([#124](https://github.com/scratchfoundation/scratch-blocks/issues/124)) ([b1e67f6](https://github.com/scratchfoundation/scratch-blocks/commit/b1e67f62dcedbd35e1b92d1ec1c773ff74b2ef56)) +* hide disable and inline inputs contextual menu items ([#35](https://github.com/scratchfoundation/scratch-blocks/issues/35)) ([c548298](https://github.com/scratchfoundation/scratch-blocks/commit/c548298f3b9cf6baa0c27fdb54b5336538d4abf0)) +* improve positioning of newly created procedure blocks ([#121](https://github.com/scratchfoundation/scratch-blocks/issues/121)) ([84a9e5b](https://github.com/scratchfoundation/scratch-blocks/commit/84a9e5b8e9aba2688fd10672a852827311f32259)) +* improve reliability of block value reporting ([#77](https://github.com/scratchfoundation/scratch-blocks/issues/77)) ([cb5b068](https://github.com/scratchfoundation/scratch-blocks/commit/cb5b068afa6e781e649754b55fc013a02112431e)) +* improve sizing and rendering of comments ([#219](https://github.com/scratchfoundation/scratch-blocks/issues/219)) ([1279c0a](https://github.com/scratchfoundation/scratch-blocks/commit/1279c0aacefb8bbfaaa9786531a56c5a45cf24ee)) +* load CSS and fix up UI appearance ([#33](https://github.com/scratchfoundation/scratch-blocks/issues/33)) ([1645129](https://github.com/scratchfoundation/scratch-blocks/commit/1645129950797408d01e3966a9d1b7bdf6223226)) +* load the continuous toolbox ([#31](https://github.com/scratchfoundation/scratch-blocks/issues/31)) ([ea68b1c](https://github.com/scratchfoundation/scratch-blocks/commit/ea68b1c25f055288e2ee39f846c17e5861f1a01f)) +* make block images work in all contexts ([#30](https://github.com/scratchfoundation/scratch-blocks/issues/30)) ([920febf](https://github.com/scratchfoundation/scratch-blocks/commit/920febf5c3304bcf3a561b1e7c0e016540399540)) +* make FieldNumber a subclass of FieldTextInput ([#214](https://github.com/scratchfoundation/scratch-blocks/issues/214)) ([3ae2235](https://github.com/scratchfoundation/scratch-blocks/commit/3ae22356f5ee9ed5da55b744657a033e43ad1ce0)) +* make variable names case-sensitive ([#122](https://github.com/scratchfoundation/scratch-blocks/issues/122)) ([46854cd](https://github.com/scratchfoundation/scratch-blocks/commit/46854cdb7c9fe92b8621a9e36acd6f94e9383a9f)) +* match Scratch behaviors around dragging and connection stickiness ([#80](https://github.com/scratchfoundation/scratch-blocks/issues/80)) ([fd1bc58](https://github.com/scratchfoundation/scratch-blocks/commit/fd1bc58bdef66697b0630d1c67f5a04d01dfa716)) +* miscellaneous UI fixits ([#41](https://github.com/scratchfoundation/scratch-blocks/issues/41)) ([300a1ce](https://github.com/scratchfoundation/scratch-blocks/commit/300a1ce564a55cb65ef2e01792a0ba1149621c50)) +* modernize and reenable the colour slider field ([#42](https://github.com/scratchfoundation/scratch-blocks/issues/42)) ([4f97982](https://github.com/scratchfoundation/scratch-blocks/commit/4f979828f1122d5cf314a8de464457ae8b925ed7)) +* more closely align flyout layout with Scratch ([#45](https://github.com/scratchfoundation/scratch-blocks/issues/45)) ([49663ed](https://github.com/scratchfoundation/scratch-blocks/commit/49663ed2f823ea45a04c0201d467d4e06e0d7078)) +* prevent deleting procedure definition blocks with references by dragging to the flyout ([#120](https://github.com/scratchfoundation/scratch-blocks/issues/120)) ([fa9367d](https://github.com/scratchfoundation/scratch-blocks/commit/fa9367d975e8c3fd45321248eb365c9cd0477dbb)) +* prevent dragging blocks into the slot occupied by the procedure definition block's example caller block ([#118](https://github.com/scratchfoundation/scratch-blocks/issues/118)) ([453ffa9](https://github.com/scratchfoundation/scratch-blocks/commit/453ffa9654927be023571f5bb496a1d0ff36aad9)) +* re-export scratch-blocks utility functions ([#26](https://github.com/scratchfoundation/scratch-blocks/issues/26)) ([685ecfc](https://github.com/scratchfoundation/scratch-blocks/commit/685ecfc0ce9f3c9335393f5af71eb3755aabedd4)) +* readd the control blocks ([#22](https://github.com/scratchfoundation/scratch-blocks/issues/22)) ([f69d4ac](https://github.com/scratchfoundation/scratch-blocks/commit/f69d4ac8ebd128b318919f4a3ac5222d211adfbb)) +* readd the data blocks ([#29](https://github.com/scratchfoundation/scratch-blocks/issues/29)) ([fafed65](https://github.com/scratchfoundation/scratch-blocks/commit/fafed65e73f59877200741c36244d082f2b3aad1)) +* readd the event blocks ([#21](https://github.com/scratchfoundation/scratch-blocks/issues/21)) ([4de530f](https://github.com/scratchfoundation/scratch-blocks/commit/4de530f00310ee27c0ad55940c9cb6bf1208df91)) +* readd the looks blocks ([#23](https://github.com/scratchfoundation/scratch-blocks/issues/23)) ([34f07c0](https://github.com/scratchfoundation/scratch-blocks/commit/34f07c0ed7982963ded8563b5f45d374e740d98c)) +* readd the motion blocks ([#20](https://github.com/scratchfoundation/scratch-blocks/issues/20)) ([79398c2](https://github.com/scratchfoundation/scratch-blocks/commit/79398c2ebae7329d0d428bab5870e559423ab36b)) +* readd the operator blocks and dependencies ([#19](https://github.com/scratchfoundation/scratch-blocks/issues/19)) ([8024e9f](https://github.com/scratchfoundation/scratch-blocks/commit/8024e9fd638586d26e6b47424e0067c0387af8cd)) +* readd the sensing blocks ([#27](https://github.com/scratchfoundation/scratch-blocks/issues/27)) ([9f5f135](https://github.com/scratchfoundation/scratch-blocks/commit/9f5f1351be5818fb9392214b8047acace8333a65)) +* readd the sound blocks ([#24](https://github.com/scratchfoundation/scratch-blocks/issues/24)) ([6837513](https://github.com/scratchfoundation/scratch-blocks/commit/6837513d3f217e94522a3ce756273d6ff8e7538c)) +* reenable reporting block values ([#55](https://github.com/scratchfoundation/scratch-blocks/issues/55)) ([70c8cfd](https://github.com/scratchfoundation/scratch-blocks/commit/70c8cfd73ee1081eafcb2773fe56a4e078cb2bea)) +* reenable shadows for blocks being dragged ([#79](https://github.com/scratchfoundation/scratch-blocks/issues/79)) ([94d2a2c](https://github.com/scratchfoundation/scratch-blocks/commit/94d2a2ca55c0d0265a79237610bcf8c246d74a9b)) +* reenable support for checkboxes in the flyout ([#43](https://github.com/scratchfoundation/scratch-blocks/issues/43)) ([e603c67](https://github.com/scratchfoundation/scratch-blocks/commit/e603c67cf7c55ff09c292991ef6b9f9ac3aae0f9)) +* reenable support for dragging blocks between sprites ([#130](https://github.com/scratchfoundation/scratch-blocks/issues/130)) ([3d8b998](https://github.com/scratchfoundation/scratch-blocks/commit/3d8b998f3be7e76adf313a60b81f29b871266c94)) +* reenable the matrix field ([#49](https://github.com/scratchfoundation/scratch-blocks/issues/49)) ([aa3341b](https://github.com/scratchfoundation/scratch-blocks/commit/aa3341b69e51de847f177124660a304e2bca8446)) +* reenable the mobile numpad field ([#54](https://github.com/scratchfoundation/scratch-blocks/issues/54)) ([003afd0](https://github.com/scratchfoundation/scratch-blocks/commit/003afd04b98ae1d3688b5356885e27c116fc61ac)) +* reenable the note block and picker field ([#48](https://github.com/scratchfoundation/scratch-blocks/issues/48)) ([de62d77](https://github.com/scratchfoundation/scratch-blocks/commit/de62d7752eb80f67a654ae2e87820ad4183e833d)) +* reenable the vertical separator field ([#46](https://github.com/scratchfoundation/scratch-blocks/issues/46)) ([48e931f](https://github.com/scratchfoundation/scratch-blocks/commit/48e931fa9de3e31b18f088557c2cbfd0738b4bc6)) +* remove canvas transition ([#129](https://github.com/scratchfoundation/scratch-blocks/issues/129)) ([ff4b115](https://github.com/scratchfoundation/scratch-blocks/commit/ff4b1151d702be0be5dabf1f1032fd08b8d58e3e)) +* remove underscore from a few createProcedureDefCallback calls ([#40](https://github.com/scratchfoundation/scratch-blocks/issues/40)) ([4e794f6](https://github.com/scratchfoundation/scratch-blocks/commit/4e794f6503dfba1d12f9e99905660d305d34e309)) +* render the procedure definition block like Scratch ([#115](https://github.com/scratchfoundation/scratch-blocks/issues/115)) ([2a543f5](https://github.com/scratchfoundation/scratch-blocks/commit/2a543f56f6d45bcc970cfe56dbfdea6ff26c833a)) +* resolve error when adding the stop block to the workspace ([#56](https://github.com/scratchfoundation/scratch-blocks/issues/56)) ([f3e059c](https://github.com/scratchfoundation/scratch-blocks/commit/f3e059cbf5cf3ce4e063871632a213c8d58f1000)) +* resolve various UI issues ([#117](https://github.com/scratchfoundation/scratch-blocks/issues/117)) ([4b74d5c](https://github.com/scratchfoundation/scratch-blocks/commit/4b74d5ca4ffaf7dfd7c040bce5cfd725c96d848a)) +* select new variable blocks' monitor checkboxes after creation ([#140](https://github.com/scratchfoundation/scratch-blocks/issues/140)) ([3811d93](https://github.com/scratchfoundation/scratch-blocks/commit/3811d93f57c2a72a8a830a7326e2d27694bec7b7)) +* show connection highlights for boolean inputs ([#181](https://github.com/scratchfoundation/scratch-blocks/issues/181)) ([303611a](https://github.com/scratchfoundation/scratch-blocks/commit/303611a5475b4c5914d14c7fa04915d0cb0a0d03)) +* show the glow only when blocks are running ([#57](https://github.com/scratchfoundation/scratch-blocks/issues/57)) ([33e9e91](https://github.com/scratchfoundation/scratch-blocks/commit/33e9e91be1210c1699bc3491df5d9c7c191bc30d)) +* show the name of the list in the list getter block context menu ([#132](https://github.com/scratchfoundation/scratch-blocks/issues/132)) ([eb839fc](https://github.com/scratchfoundation/scratch-blocks/commit/eb839fcef9e8befad591cf35c00044adff9269f6)) +* update the flyout for compatibility with the new flyout API ([#209](https://github.com/scratchfoundation/scratch-blocks/issues/209)) ([7ce9991](https://github.com/scratchfoundation/scratch-blocks/commit/7ce9991b6f1b6a504847097ebd098f0ec1e50e52)) +* use non-deprecated input type constants ([#78](https://github.com/scratchfoundation/scratch-blocks/issues/78)) ([1f1c859](https://github.com/scratchfoundation/scratch-blocks/commit/1f1c8598a5dac8bb42dd82fff7edc7eda7fe4225)) +* use Scratch-style text blocks ([#37](https://github.com/scratchfoundation/scratch-blocks/issues/37)) ([6bbbdf7](https://github.com/scratchfoundation/scratch-blocks/commit/6bbbdf763ba43d3dc0af7bad15478f848455f4df)) +* use Scratch's FieldAngle ([#138](https://github.com/scratchfoundation/scratch-blocks/issues/138)) ([ef7911c](https://github.com/scratchfoundation/scratch-blocks/commit/ef7911cf7fd12d6370733bdd3778560925bd050c)) + + +* fix!: bump to v2.0 to reflect Blockly un-forking ([899a981](https://github.com/scratchfoundation/scratch-blocks/commit/899a981fb55c60e4b7822e9a77ebb0a65819d094)) + + +### Features + +* add a block inflater that supports recycling ([#207](https://github.com/scratchfoundation/scratch-blocks/issues/207)) ([0701679](https://github.com/scratchfoundation/scratch-blocks/commit/07016799832530cf851c14be484158e58bdaa9dd)) +* add bubbles/icons for block flyout checkboxes ([#208](https://github.com/scratchfoundation/scratch-blocks/issues/208)) ([39b2162](https://github.com/scratchfoundation/scratch-blocks/commit/39b2162db62973860c904f0b78f1d7f27abebc99)) +* add custom Scratch variable model and creation event classes ([#86](https://github.com/scratchfoundation/scratch-blocks/issues/86)) ([2598ede](https://github.com/scratchfoundation/scratch-blocks/commit/2598ede046de74164922bd919695eae65bd0c9b2)) +* clean up and export Scratch's variables.js ([#88](https://github.com/scratchfoundation/scratch-blocks/issues/88)) ([5c1acfe](https://github.com/scratchfoundation/scratch-blocks/commit/5c1acfe3dc1bb0bf406ba20ffd1e25b22356fbd7)) +* readd support for the custom Data toolbox category ([#87](https://github.com/scratchfoundation/scratch-blocks/issues/87)) ([dcfbf39](https://github.com/scratchfoundation/scratch-blocks/commit/dcfbf391cfcf2dbdf04c84b7e5c4d1463c18ed1d)) +* reenable Scratch's FieldVariable subclass ([#91](https://github.com/scratchfoundation/scratch-blocks/issues/91)) ([7c891e3](https://github.com/scratchfoundation/scratch-blocks/commit/7c891e35207b6f561917f27739917cb84755d57c)) + + +### Reverts + +* Revert "fix: add zoom controls config (#126)" (#128) ([8e1dc14](https://github.com/scratchfoundation/scratch-blocks/commit/8e1dc14483d6e012734a30b666af7aa5427c58f9)), closes [#126](https://github.com/scratchfoundation/scratch-blocks/issues/126) [#128](https://github.com/scratchfoundation/scratch-blocks/issues/128) + + +### BREAKING CHANGES + +* scratch-blocks is no longer a divergent fork of +Blockly, and instead depends on Blockly as a regular node_modules +dependency. + +Thanks, @gonfunko and everyone else at Google who helped with this +effort! + ## [1.1.86](https://github.com/scratchfoundation/scratch-blocks/compare/v1.1.85...v1.1.86) (2024-04-12) diff --git a/package-lock.json b/package-lock.json index d52883236b..fb32cefed9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "scratch-blocks", - "version": "2.0.0", + "version": "2.0.0-spork.1", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "scratch-blocks", - "version": "2.0.0", + "version": "2.0.0-spork.1", "license": "Apache-2.0", "dependencies": { "@blockly/continuous-toolbox": "^6.0.9", diff --git a/package.json b/package.json index 980da3277f..68e35d14d5 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "scratch-blocks", - "version": "2.0.0", + "version": "2.0.0-spork.1", "description": "Scratch Blocks is a library for building creative computing interfaces.", "author": "Massachusetts Institute of Technology", "license": "Apache-2.0", From 9a03eeaf992554f8affa7faf0530e628a42a5206 Mon Sep 17 00:00:00 2001 From: Aaron Dodson Date: Tue, 19 Nov 2024 14:55:03 -0800 Subject: [PATCH 120/130] refactor: migrate scratch-blocks to Typescript (#224) * chore: rename checkbox_buble.js to checkbox_bubble.ts * refactor: convert CheckboxBubble to TS * chore: rename status_indicator_label.js to status_indicator_label.ts * refactor: convert StatusIndicatorLabel to Typescript * chore: rename status_indicator_label_flyout_inflater.js to status_indicator_label_flyout_inflater.ts * refactor: convert StatusIndicatorLabelFlyoutInflater to TS * chore: rename recyclable_block_flyout_inflater.js to recyclable_block_flyout_inflater.ts * refactor: convert RecyclableBlockFlyoutInflater to TS * chore: rename procedures.js to procedures.ts * refactor: modernize and convert procedures.ts to Typescript * chore: rename variables.js to variables.ts * refactor: convert variables.ts to Typescript * refactor: modernize variables.ts * chore: rename shadows.js to shadows.ts * refactor: convert shadows.ts to Typescript * chore: rename scratch_variable_model.js to scratch_variable_model.ts * refactor: convert ScratchVariableModel to Typescript * chore: rename scratch_variable_map.js to scratch_variable_map.ts * refactor: convert ScratchVariableMap to Typescript * chore: rename scratch_dragger.js to scratch_dragger.ts * refactor: convert ScratchDragger to Typescript * chore: add TSDoc to ScratchDragger * chore: rename scratch_continuous_toolbox.js to scratch_continuous_toolbox.ts * refactor: convert ScratchContinuousToolbox to Typescript * chore: rename scratch_continuous_category.js to scratch_continuous_category.ts * refactor: convert ScratchContinuousCategory to Typescript * chore: rename scratch_connection_checker.js to scratch_connection_checker.ts * refactor: convert ScratchConnectionChecker to Typescript * chore: rename scratch_comment_icon.js to scratch_comment_icon.ts * refactor: convert ScratchCommentIcon to Typescript * chore: rename data_category.js to data_category.ts * refactor: convert data_category.ts to Typescript * refactor: modernize data_category.ts * chore: rename scratch_block_paster.js to scratch_block_paster.ts * refactor: convert ScratchBlockPaster to Typescript * chore: rename glows.js to glows.ts * refactor: convert glows.ts to Typescript * chore: rename flyout_checkbox_icon.js to flyout_checkbox_icon.ts * refactor: convert FlyoutCheckboxIcon to Typescript * refactor: convert css.js to Typescript * chore: rename context_menu_items.js to context_menu_items.ts * refactor: convert context_menu_items.ts to Typescript * refactor: convert constants.js to Typescript * chore: add license to constants.ts * refactor: convert colours.js to Typescript * chore: remove the unneded categories.js * chore: rename block_reporting.js to block_reporting.ts * refactor: convert block_reporting.ts to Typescript * chore: rename colour.js to colour.ts * refactor: convert colour.ts to Typescript * refactor: convert control.js to Typescript * refactor: convert event.js to Typescript * refactor: convert looks.js to Typescript * refactor: convert math.js to Typescript * refactor: convert matrix.js to Typescript * refactor: convert motion.js to Typescript * refactor: convert note.js to Typescript * refactor: convert operators.js to Typescript * refactor: convert sensing.js to Typescript * refactor: convert sound.js to Typescript * refactor: convert text.js to Typescript * chore: rename data.js to data.ts * refactor: convert data.ts to Typescript * chore: rename procedures.js to procedures.ts * refactor: convert procedures.ts to Typescript * refactor: modernize procedures.ts * chore: rename vertical_extensions.js to vertical_extensions.ts * refactor: convert vertical_extensions.ts to Typescript * chore: rename field_angle.js to scratch_field_angle.ts * refactor: convert ScratchFieldAngle to Typescript * refactor: clean up ScratchFieldAngle * refactor: add typings for `this` to block definitions * chore: rename field_variable.js to scratch_field_variable.ts * refactor: convert ScratchFieldVariable to Typescript * chore: rename field_vertical_separator.js to field_vertical_separator.ts * refactor: convert FieldVerticalSeparator to Typescript * chore: rename field_variable_getter.js to field_variable_getter.ts * refactor: convert FieldVariableGetter to Typescript * chore: rename field_textinput_removable.js to field_textinput_removable.ts * refactor: convert FieldTextInputRemovable to Typescript * chore: rename field_number.js to scratch_field_number.ts * refactor: convert ScratchFieldNumber to Typescript * chore: rename field_note.js to field_note.ts * refactor: convert FieldNote to Typescript * chore: rename field_matrix.js to field_matrix.ts * refactor: convert FieldMatrix to Typescript * chore: rename field_dropdown.js to scratch_field_dropdown.ts * refactor: convert ScratchFieldDropdown to Typescript * chore: rename field_colour_slider.js to field_colour_slider.ts * refactor: convert FieldColourSlider to Typescript * chore: rename events_block_comment_base.js to events_block_comment_base.ts * refactor: convert BlockCommentBase to Typescript * chore: rename events_block_comment_change.js to events_block_comment_change.ts * refactor: convert BlockCommentChange to Typescript * chore: rename events_block_comment_collapse.js to events_block_comment_collapse.ts * refactor: convert BlockCommentCollapse to Typescript * chore: rename events_block_comment_create.js to events_block_comment_create.ts * refactor: convert BlockCommentCreate to Typescript * chore: rename events_block_comment_delete.js to events_block_comment_delete.ts * refactor: convert BlockCommentDelete to Typescript * chore: rename events_block_comment_move.js to events_block_comment_move.ts * refactor: convert BlockCommentMove to Typescript * chore: rename events_block_comment_resize.js to events_block_comment_resize.ts * refactor: convert BlockCommentResize to Typescript * chore: rename events_block_drag_end.js to events_block_drag_end.ts * refactor: convert BlockDragEnd to Typescript * chore: rename events_block_drag_outside.js to events_block_drag_outside.ts * refactor: convert BlockDragOutside to Typescript * chore: rename events_scratch_variable_create.js to events_scratch_variable_create.ts * refactor: convert ScratchVariableCreate to Typescript * chore: rename bowler_hat.js to bowler_hat.ts * refactor: convert BowlerHat to Typescript * chore: rename constants.js to constants.ts * refactor: convert ConstantProvider to Typescript * chore: rename drawer.js to drawer.ts * refactor: convert Drawer to Typescript * chore: rename path_object.js to path_object.ts * refactor: convert PathObject to Typescript * chore: rename render_info.js to render_info.ts * refactor: convert RenderInfo to Typescript * chore: rename renderer.js to renderer.ts * refactor: convert Renderer to Typescript * chore: rename scratch_blocks_utils.js to scratch_blocks_utils.ts * refactor: remove unused functions * refactor: convert scratch_blocks_utils.ts to Typescript --- ...{block_reporting.js => block_reporting.ts} | 12 +- src/blocks/{colour.js => colour.ts} | 12 +- src/blocks/{control.js => control.ts} | 75 +- src/blocks/{data.js => data.ts} | 276 ++++--- src/blocks/{event.js => event.ts} | 45 +- src/blocks/{looks.js => looks.ts} | 97 +-- src/blocks/{math.js => math.ts} | 17 +- src/blocks/{matrix.js => matrix.ts} | 5 +- src/blocks/{motion.js => motion.ts} | 93 +-- src/blocks/{note.js => note.ts} | 5 +- src/blocks/{operators.js => operators.ts} | 73 +- src/blocks/{procedures.js => procedures.ts} | 687 +++++++++++------- src/blocks/{sensing.js => sensing.ts} | 82 +-- src/blocks/{sound.js => sound.ts} | 37 +- src/blocks/{text.js => text.ts} | 3 +- ...l_extensions.js => vertical_extensions.ts} | 163 ++--- src/categories.js | 15 - src/checkable_continuous_flyout.js | 4 +- ...{checkbox_bubble.js => checkbox_bubble.ts} | 89 +-- src/{colours.js => colours.ts} | 15 +- src/{constants.js => constants.ts} | 13 + ...xt_menu_items.js => context_menu_items.ts} | 30 +- src/{css.js => css.ts} | 0 src/{data_category.js => data_category.ts} | 366 ++++++---- ...t_base.js => events_block_comment_base.ts} | 27 +- ...ange.js => events_block_comment_change.ts} | 34 +- ...se.js => events_block_comment_collapse.ts} | 30 +- ...eate.js => events_block_comment_create.ts} | 46 +- ...lete.js => events_block_comment_delete.ts} | 8 +- ...t_move.js => events_block_comment_move.ts} | 42 +- src/events/events_block_comment_resize.js | 52 -- src/events/events_block_comment_resize.ts | 88 +++ src/events/events_block_drag_end.js | 33 - src/events/events_block_drag_end.ts | 49 ++ src/events/events_block_drag_outside.js | 30 - src/events/events_block_drag_outside.ts | 44 ++ ...e.js => events_scratch_variable_create.ts} | 43 +- ...olour_slider.js => field_colour_slider.ts} | 223 +++--- .../{field_matrix.js => field_matrix.ts} | 408 +++++------ src/fields/{field_note.js => field_note.ts} | 513 ++++++------- ...ovable.js => field_textinput_removable.ts} | 37 +- ...ble_getter.js => field_variable_getter.ts} | 45 +- ...parator.js => field_vertical_separator.ts} | 44 +- ...{field_angle.js => scratch_field_angle.ts} | 210 +++--- ..._dropdown.js => scratch_field_dropdown.ts} | 16 +- ...ield_number.js => scratch_field_number.ts} | 115 +-- ..._variable.js => scratch_field_variable.ts} | 73 +- ...eckbox_icon.js => flyout_checkbox_icon.ts} | 34 +- src/{glows.js => glows.ts} | 47 +- src/index.ts | 119 ++- src/procedures.js | 425 ----------- src/procedures.ts | 462 ++++++++++++ ...js => recyclable_block_flyout_inflater.ts} | 70 +- src/renderer/{bowler_hat.js => bowler_hat.ts} | 2 +- src/renderer/{constants.js => constants.ts} | 38 +- src/renderer/{drawer.js => drawer.ts} | 11 +- .../{path_object.js => path_object.ts} | 4 +- .../{render_info.js => render_info.ts} | 26 +- src/renderer/renderer.js | 74 -- src/renderer/renderer.ts | 76 ++ ...lock_paster.js => scratch_block_paster.ts} | 16 +- src/scratch_blocks_utils.js | 148 ---- src/scratch_blocks_utils.ts | 39 + ...omment_icon.js => scratch_comment_icon.ts} | 69 +- src/scratch_connection_checker.js | 29 - src/scratch_connection_checker.ts | 44 ++ ...gory.js => scratch_continuous_category.ts} | 33 +- ...olbox.js => scratch_continuous_toolbox.ts} | 38 +- ...{scratch_dragger.js => scratch_dragger.ts} | 125 +++- ...ariable_map.js => scratch_variable_map.ts} | 5 +- src/scratch_variable_model.js | 24 - src/scratch_variable_model.ts | 30 + src/{shadows.js => shadows.ts} | 12 +- ...tor_label.js => status_indicator_label.ts} | 60 +- ...status_indicator_label_flyout_inflater.ts} | 16 +- src/{variables.js => variables.ts} | 276 +++---- 76 files changed, 3494 insertions(+), 3282 deletions(-) rename src/{block_reporting.js => block_reporting.ts} (69%) rename src/blocks/{colour.js => colour.ts} (84%) rename src/blocks/{control.js => control.ts} (87%) rename src/blocks/{data.js => data.ts} (72%) rename src/blocks/{event.js => event.ts} (88%) rename src/blocks/{looks.js => looks.ts} (84%) rename src/blocks/{math.js => math.ts} (90%) rename src/blocks/{matrix.js => matrix.ts} (92%) rename src/blocks/{motion.js => motion.ts} (83%) rename src/blocks/{note.js => note.ts} (92%) rename src/blocks/{operators.js => operators.ts} (84%) rename src/blocks/{procedures.js => procedures.ts} (58%) rename src/blocks/{sensing.js => sensing.ts} (84%) rename src/blocks/{sound.js => sound.ts} (83%) rename src/blocks/{text.js => text.ts} (95%) rename src/blocks/{vertical_extensions.js => vertical_extensions.ts} (62%) delete mode 100644 src/categories.js rename src/{checkbox_bubble.js => checkbox_bubble.ts} (75%) rename src/{colours.js => colours.ts} (83%) rename src/{constants.js => constants.ts} (87%) rename src/{context_menu_items.js => context_menu_items.ts} (82%) rename src/{css.js => css.ts} (100%) rename src/{data_category.js => data_category.ts} (60%) rename src/events/{events_block_comment_base.js => events_block_comment_base.ts} (52%) rename src/events/{events_block_comment_change.js => events_block_comment_change.ts} (55%) rename src/events/{events_block_comment_collapse.js => events_block_comment_collapse.ts} (54%) rename src/events/{events_block_comment_create.js => events_block_comment_create.ts} (51%) rename src/events/{events_block_comment_delete.js => events_block_comment_delete.ts} (73%) rename src/events/{events_block_comment_move.js => events_block_comment_move.ts} (56%) delete mode 100644 src/events/events_block_comment_resize.js create mode 100644 src/events/events_block_comment_resize.ts delete mode 100644 src/events/events_block_drag_end.js create mode 100644 src/events/events_block_drag_end.ts delete mode 100644 src/events/events_block_drag_outside.js create mode 100644 src/events/events_block_drag_outside.ts rename src/events/{events_scratch_variable_create.js => events_scratch_variable_create.ts} (59%) rename src/fields/{field_colour_slider.js => field_colour_slider.ts} (62%) rename src/fields/{field_matrix.js => field_matrix.ts} (59%) rename src/fields/{field_note.js => field_note.ts} (63%) rename src/fields/{field_textinput_removable.js => field_textinput_removable.ts} (72%) rename src/fields/{field_variable_getter.js => field_variable_getter.ts} (73%) rename src/fields/{field_vertical_separator.js => field_vertical_separator.ts} (69%) rename src/fields/{field_angle.js => scratch_field_angle.ts} (62%) rename src/fields/{field_dropdown.js => scratch_field_dropdown.ts} (64%) rename src/fields/{field_number.js => scratch_field_number.ts} (77%) rename src/fields/{field_variable.js => scratch_field_variable.ts} (69%) rename src/{flyout_checkbox_icon.js => flyout_checkbox_icon.ts} (62%) rename src/{glows.js => glows.ts} (63%) delete mode 100644 src/procedures.js create mode 100644 src/procedures.ts rename src/{recyclable_block_flyout_inflater.js => recyclable_block_flyout_inflater.ts} (68%) rename src/renderer/{bowler_hat.js => bowler_hat.ts} (83%) rename src/renderer/{constants.js => constants.ts} (50%) rename src/renderer/{drawer.js => drawer.ts} (84%) rename src/renderer/{path_object.js => path_object.ts} (92%) rename src/renderer/{render_info.js => render_info.ts} (79%) delete mode 100644 src/renderer/renderer.js create mode 100644 src/renderer/renderer.ts rename src/{scratch_block_paster.js => scratch_block_paster.ts} (72%) delete mode 100644 src/scratch_blocks_utils.js create mode 100644 src/scratch_blocks_utils.ts rename src/{scratch_comment_icon.js => scratch_comment_icon.ts} (74%) delete mode 100644 src/scratch_connection_checker.js create mode 100644 src/scratch_connection_checker.ts rename src/{scratch_continuous_category.js => scratch_continuous_category.ts} (71%) rename src/{scratch_continuous_toolbox.js => scratch_continuous_toolbox.ts} (72%) rename src/{scratch_dragger.js => scratch_dragger.ts} (50%) rename src/{scratch_variable_map.js => scratch_variable_map.ts} (87%) delete mode 100644 src/scratch_variable_model.js create mode 100644 src/scratch_variable_model.ts rename src/{shadows.js => shadows.ts} (77%) rename src/{status_indicator_label.js => status_indicator_label.ts} (77%) rename src/{status_indicator_label_flyout_inflater.js => status_indicator_label_flyout_inflater.ts} (68%) rename src/{variables.js => variables.ts} (50%) diff --git a/src/block_reporting.js b/src/block_reporting.ts similarity index 69% rename from src/block_reporting.js rename to src/block_reporting.ts index 4a4e0253d9..9df9bc87ad 100644 --- a/src/block_reporting.js +++ b/src/block_reporting.ts @@ -1,10 +1,12 @@ import * as Blockly from "blockly/core"; -import { Colours } from "./colours.js"; +import { Colours } from "./colours"; -export function reportValue(id, value) { - const block = - Blockly.getMainWorkspace().getBlockById(id) || - Blockly.getMainWorkspace().getFlyout().getWorkspace().getBlockById(id); +export function reportValue(id: string, value: string) { + const block = (Blockly.getMainWorkspace().getBlockById(id) || + (Blockly.getMainWorkspace() as Blockly.WorkspaceSvg) + .getFlyout() + .getWorkspace() + .getBlockById(id)) as Blockly.BlockSvg; if (!block) { throw "Tried to report value on block that does not exist."; } diff --git a/src/blocks/colour.js b/src/blocks/colour.ts similarity index 84% rename from src/blocks/colour.js rename to src/blocks/colour.ts index 8f1e9e2fb5..f1462786b9 100644 --- a/src/blocks/colour.js +++ b/src/blocks/colour.ts @@ -23,23 +23,23 @@ * @author fraser@google.com (Neil Fraser) */ import * as Blockly from "blockly/core"; -import * as Constants from "../constants.js"; +import * as Constants from "../constants"; /** * Pick a random colour. - * @return {string} #RRGGBB for random colour. + * + * @returns #RRGGBB for random colour. */ -function randomColour() { - var num = Math.floor(Math.random() * Math.pow(2, 24)); +function randomColour(): string { + const num = Math.floor(Math.random() * Math.pow(2, 24)); return "#" + ("00000" + num.toString(16)).substr(-6); } Blockly.Blocks["colour_picker"] = { /** * Block for colour picker. - * @this Blockly.Block */ - init: function () { + init: function (this: Blockly.Block) { this.jsonInit({ message0: "%1", args0: [ diff --git a/src/blocks/control.js b/src/blocks/control.ts similarity index 87% rename from src/blocks/control.js rename to src/blocks/control.ts index 0564e9bc65..6c625ed78a 100644 --- a/src/blocks/control.js +++ b/src/blocks/control.ts @@ -19,15 +19,13 @@ */ import * as Blockly from "blockly/core"; -import { Categories } from "../categories.js"; Blockly.Blocks["control_forever"] = { /** * Block for repeat n times (external number). * https://blockly-demo.appspot.com/static/demos/blockfactory/index.html#5eke39 - * @this Blockly.Block */ - init: function () { + init: function (this: Blockly.Block) { const ws = this.workspace.options.parentWorkspace || this.workspace; this.jsonInit({ id: "control_forever", @@ -51,7 +49,6 @@ Blockly.Blocks["control_forever"] = { flip_rtl: true, }, ], - category: Categories.control, extensions: ["colours_control", "shape_end"], }); }, @@ -61,9 +58,8 @@ Blockly.Blocks["control_repeat"] = { /** * Block for repeat n times (external number). * https://blockly-demo.appspot.com/static/demos/blockfactory/index.html#so57n9 - * @this Blockly.Block */ - init: function () { + init: function (this: Blockly.Block) { const ws = this.workspace.options.parentWorkspace || this.workspace; this.jsonInit({ id: "control_repeat", @@ -93,7 +89,6 @@ Blockly.Blocks["control_repeat"] = { flip_rtl: true, }, ], - category: Categories.control, extensions: ["colours_control", "shape_statement"], }); }, @@ -102,9 +97,8 @@ Blockly.Blocks["control_repeat"] = { Blockly.Blocks["control_if"] = { /** * Block for if-then. - * @this Blockly.Block */ - init: function () { + init: function (this: Blockly.Block) { this.jsonInit({ type: "control_if", message0: Blockly.Msg.CONTROL_IF, @@ -122,7 +116,6 @@ Blockly.Blocks["control_if"] = { name: "SUBSTACK", }, ], - category: Categories.control, extensions: ["colours_control", "shape_statement"], }); }, @@ -131,9 +124,8 @@ Blockly.Blocks["control_if"] = { Blockly.Blocks["control_if_else"] = { /** * Block for if-else. - * @this Blockly.Block */ - init: function () { + init: function (this: Blockly.Block) { this.jsonInit({ type: "control_if_else", message0: Blockly.Msg.CONTROL_IF, @@ -159,7 +151,6 @@ Blockly.Blocks["control_if_else"] = { name: "SUBSTACK2", }, ], - category: Categories.control, extensions: ["colours_control", "shape_statement"], }); }, @@ -168,13 +159,12 @@ Blockly.Blocks["control_if_else"] = { Blockly.Blocks["control_stop"] = { /** * Block for stop all scripts. - * @this Blockly.Block */ - init: function () { - var ALL_SCRIPTS = "all"; - var THIS_SCRIPT = "this script"; - var OTHER_SCRIPTS = "other scripts in sprite"; - var stopDropdown = new Blockly.FieldDropdown( + init: function (this: Blockly.Block) { + const ALL_SCRIPTS = "all"; + const THIS_SCRIPT = "this script"; + const OTHER_SCRIPTS = "other scripts in sprite"; + const stopDropdown = new Blockly.FieldDropdown( function () { if ( this.sourceBlock_ && @@ -205,9 +195,8 @@ Blockly.Blocks["control_stop"] = { Blockly.Blocks["control_wait"] = { /** * Block to wait (pause) stack. - * @this Blockly.Block */ - init: function () { + init: function (this: Blockly.Block) { this.jsonInit({ id: "control_wait", message0: Blockly.Msg.CONTROL_WAIT, @@ -217,7 +206,6 @@ Blockly.Blocks["control_wait"] = { name: "DURATION", }, ], - category: Categories.control, extensions: ["colours_control", "shape_statement"], }); }, @@ -226,9 +214,8 @@ Blockly.Blocks["control_wait"] = { Blockly.Blocks["control_wait_until"] = { /** * Block to wait until a condition becomes true. - * @this Blockly.Block */ - init: function () { + init: function (this: Blockly.Block) { this.jsonInit({ message0: Blockly.Msg.CONTROL_WAITUNTIL, args0: [ @@ -238,7 +225,6 @@ Blockly.Blocks["control_wait_until"] = { check: "Boolean", }, ], - category: Categories.control, extensions: ["colours_control", "shape_statement"], }); }, @@ -247,9 +233,8 @@ Blockly.Blocks["control_wait_until"] = { Blockly.Blocks["control_repeat_until"] = { /** * Block to repeat until a condition becomes true. - * @this Blockly.Block */ - init: function () { + init: function (this: Blockly.Block) { const ws = this.workspace.options.parentWorkspace || this.workspace; this.jsonInit({ message0: Blockly.Msg.CONTROL_REPEATUNTIL, @@ -279,7 +264,6 @@ Blockly.Blocks["control_repeat_until"] = { flip_rtl: true, }, ], - category: Categories.control, extensions: ["colours_control", "shape_statement"], }); }, @@ -290,7 +274,7 @@ Blockly.Blocks["control_while"] = { * Block to repeat until a condition becomes false. * (This is an obsolete "hacked" block, for compatibility with 2.0.) */ - init: function () { + init: function (this: Blockly.Block) { const ws = this.workspace.options.parentWorkspace || this.workspace; this.jsonInit({ message0: Blockly.Msg.CONTROL_WHILE, @@ -320,7 +304,6 @@ Blockly.Blocks["control_while"] = { flip_rtl: true, }, ], - category: Categories.control, extensions: ["colours_control", "shape_statement"], }); }, @@ -330,9 +313,8 @@ Blockly.Blocks["control_for_each"] = { /** * Block for for-each. This is an obsolete block that is implemented for * compatibility with Scratch 2.0 projects. - * @this Blockly.Block */ - init: function () { + init: function (this: Blockly.Block) { this.jsonInit({ type: "control_for_each", message0: Blockly.Msg.CONTROL_FOREACH, @@ -353,7 +335,6 @@ Blockly.Blocks["control_for_each"] = { name: "SUBSTACK", }, ], - category: Categories.control, extensions: ["colours_control", "shape_statement"], }); }, @@ -362,14 +343,12 @@ Blockly.Blocks["control_for_each"] = { Blockly.Blocks["control_start_as_clone"] = { /** * Block for "when I start as a clone" hat. - * @this Blockly.Block */ - init: function () { + init: function (this: Blockly.Block) { this.jsonInit({ id: "control_start_as_clone", message0: Blockly.Msg.CONTROL_STARTASCLONE, args0: [], - category: Categories.control, extensions: ["colours_control", "shape_hat"], }); }, @@ -383,9 +362,8 @@ Blockly.Blocks["control_create_clone_of_menu"] = {}; Blockly.Blocks["control_create_clone_of"] = { /** * Block for "create clone of..." - * @this Blockly.Block */ - init: function () { + init: function (this: Blockly.Block) { this.jsonInit({ id: "control_start_as_clone", message0: Blockly.Msg.CONTROL_CREATECLONEOF, @@ -395,7 +373,6 @@ Blockly.Blocks["control_create_clone_of"] = { name: "CLONE_OPTION", }, ], - category: Categories.control, extensions: ["colours_control", "shape_statement"], }); }, @@ -404,13 +381,11 @@ Blockly.Blocks["control_create_clone_of"] = { Blockly.Blocks["control_delete_this_clone"] = { /** * Block for "delete this clone." - * @this Blockly.Block */ - init: function () { + init: function (this: Blockly.Block) { this.jsonInit({ message0: Blockly.Msg.CONTROL_DELETETHISCLONE, args0: [], - category: Categories.control, extensions: ["colours_control", "shape_end"], }); }, @@ -420,12 +395,10 @@ Blockly.Blocks["control_get_counter"] = { /** * Block to get the counter value. This is an obsolete block that is * implemented for compatibility with Scratch 2.0 projects. - * @this Blockly.Block */ - init: function () { + init: function (this: Blockly.Block) { this.jsonInit({ message0: Blockly.Msg.CONTROL_COUNTER, - category: Categories.control, extensions: ["colours_control", "output_number"], }); }, @@ -435,12 +408,10 @@ Blockly.Blocks["control_incr_counter"] = { /** * Block to add one to the counter value. This is an obsolete block that is * implemented for compatibility with Scratch 2.0 projects. - * @this Blockly.Block */ - init: function () { + init: function (this: Blockly.Block) { this.jsonInit({ message0: Blockly.Msg.CONTROL_INCRCOUNTER, - category: Categories.control, extensions: ["colours_control", "shape_statement"], }); }, @@ -450,12 +421,10 @@ Blockly.Blocks["control_clear_counter"] = { /** * Block to clear the counter value. This is an obsolete block that is * implemented for compatibility with Scratch 2.0 projects. - * @this Blockly.Block */ - init: function () { + init: function (this: Blockly.Block) { this.jsonInit({ message0: Blockly.Msg.CONTROL_CLEARCOUNTER, - category: Categories.control, extensions: ["colours_control", "shape_statement"], }); }, @@ -473,9 +442,8 @@ Blockly.Blocks["control_all_at_once"] = { * reporter that is always true (e.g. "if 1 = 1"). Also note that the * Scratch 2.0 spec for this block is "warpSpeed", but the label shows * "all at once". - * @this Blockly.Block */ - init: function () { + init: function (this: Blockly.Block) { this.jsonInit({ message0: Blockly.Msg.CONTROL_ALLATONCE, message1: "%1", // Statement @@ -485,7 +453,6 @@ Blockly.Blocks["control_all_at_once"] = { name: "SUBSTACK", }, ], - category: Categories.control, extensions: ["colours_control", "shape_statement"], }); }, diff --git a/src/blocks/data.js b/src/blocks/data.ts similarity index 72% rename from src/blocks/data.js rename to src/blocks/data.ts index 372f2e997a..bbc0588cdf 100644 --- a/src/blocks/data.js +++ b/src/blocks/data.ts @@ -19,17 +19,17 @@ */ import * as Blockly from "blockly/core"; -import { Categories } from "../categories.js"; -import * as Constants from "../constants.js"; -import * as scratchBlocksUtils from "../scratch_blocks_utils.js"; -import { renameVariable } from "../variables.js"; +import * as Constants from "../constants"; +import * as scratchBlocksUtils from "../scratch_blocks_utils"; +import { renameVariable } from "../variables"; +import type { ScratchFieldVariable } from "../fields/scratch_field_variable"; +import type { ScratchVariableModel } from "../scratch_variable_model"; Blockly.Blocks["data_variable"] = { /** * Block of Variables - * @this Blockly.Block */ - init: function () { + init: function (this: Blockly.Block) { this.jsonInit({ message0: "%1", lastDummyAlign0: "CENTRE", @@ -40,7 +40,6 @@ Blockly.Blocks["data_variable"] = { allowedVariableType: Constants.SCALAR_VARIABLE_TYPE, }, ], - category: Categories.data, extensions: [ "contextMenu_getVariableBlock", "colours_data", @@ -54,9 +53,8 @@ Blockly.Blocks["data_variable"] = { Blockly.Blocks["data_setvariableto"] = { /** * Block to set variable to a certain value - * @this Blockly.Block */ - init: function () { + init: function (this: Blockly.Block) { this.jsonInit({ message0: Blockly.Msg.DATA_SETVARIABLETO, args0: [ @@ -71,7 +69,6 @@ Blockly.Blocks["data_setvariableto"] = { name: "VALUE", }, ], - category: Categories.data, extensions: ["colours_data", "shape_statement"], }); }, @@ -80,9 +77,8 @@ Blockly.Blocks["data_setvariableto"] = { Blockly.Blocks["data_changevariableby"] = { /** * Block to change variable by a certain value - * @this Blockly.Block */ - init: function () { + init: function (this: Blockly.Block) { this.jsonInit({ message0: Blockly.Msg.DATA_CHANGEVARIABLEBY, args0: [ @@ -97,7 +93,6 @@ Blockly.Blocks["data_changevariableby"] = { name: "VALUE", }, ], - category: Categories.data, extensions: ["colours_data", "shape_statement"], }); }, @@ -106,9 +101,8 @@ Blockly.Blocks["data_changevariableby"] = { Blockly.Blocks["data_showvariable"] = { /** * Block to show a variable - * @this Blockly.Block */ - init: function () { + init: function (this: Blockly.Block) { this.jsonInit({ message0: Blockly.Msg.DATA_SHOWVARIABLE, args0: [ @@ -121,7 +115,6 @@ Blockly.Blocks["data_showvariable"] = { ], previousStatement: null, nextStatement: null, - category: Categories.data, extensions: ["colours_data"], }); }, @@ -130,9 +123,8 @@ Blockly.Blocks["data_showvariable"] = { Blockly.Blocks["data_hidevariable"] = { /** * Block to hide a variable - * @this Blockly.Block */ - init: function () { + init: function (this: Blockly.Block) { this.jsonInit({ message0: Blockly.Msg.DATA_HIDEVARIABLE, args0: [ @@ -145,7 +137,6 @@ Blockly.Blocks["data_hidevariable"] = { ], previousStatement: null, nextStatement: null, - category: Categories.data, extensions: ["colours_data"], }); }, @@ -154,9 +145,8 @@ Blockly.Blocks["data_hidevariable"] = { Blockly.Blocks["data_listcontents"] = { /** * List reporter. - * @this Blockly.Block */ - init: function () { + init: function (this: Blockly.Block) { this.jsonInit({ message0: "%1", args0: [ @@ -166,7 +156,6 @@ Blockly.Blocks["data_listcontents"] = { allowedVariableType: Constants.LIST_VARIABLE_TYPE, }, ], - category: Categories.dataLists, extensions: [ "contextMenu_getListBlock", "colours_data_lists", @@ -180,9 +169,8 @@ Blockly.Blocks["data_listcontents"] = { Blockly.Blocks["data_listindexall"] = { /** * List index menu, with all option. - * @this Blockly.Block */ - init: function () { + init: function (this: Blockly.Block) { this.jsonInit({ message0: "%1", args0: [ @@ -199,7 +187,6 @@ Blockly.Blocks["data_listindexall"] = { ], }, ], - category: Categories.data, extensions: ["colours_textfield", "output_string"], }); }, @@ -208,9 +195,8 @@ Blockly.Blocks["data_listindexall"] = { Blockly.Blocks["data_listindexrandom"] = { /** * List index menu, with random option. - * @this Blockly.Block */ - init: function () { + init: function (this: Blockly.Block) { this.jsonInit({ message0: "%1", args0: [ @@ -227,7 +213,6 @@ Blockly.Blocks["data_listindexrandom"] = { ], }, ], - category: Categories.data, extensions: ["colours_textfield", "output_string"], }); }, @@ -236,9 +221,8 @@ Blockly.Blocks["data_listindexrandom"] = { Blockly.Blocks["data_addtolist"] = { /** * Block to add item to list. - * @this Blockly.Block */ - init: function () { + init: function (this: Blockly.Block) { this.jsonInit({ message0: Blockly.Msg.DATA_ADDTOLIST, args0: [ @@ -253,7 +237,6 @@ Blockly.Blocks["data_addtolist"] = { defaultType: Constants.LIST_VARIABLE_TYPE, }, ], - category: Categories.dataLists, extensions: ["colours_data_lists", "shape_statement"], }); }, @@ -262,9 +245,8 @@ Blockly.Blocks["data_addtolist"] = { Blockly.Blocks["data_deleteoflist"] = { /** * Block to delete item from list. - * @this Blockly.Block */ - init: function () { + init: function (this: Blockly.Block) { this.jsonInit({ message0: Blockly.Msg.DATA_DELETEOFLIST, args0: [ @@ -279,7 +261,6 @@ Blockly.Blocks["data_deleteoflist"] = { defaultType: Constants.LIST_VARIABLE_TYPE, }, ], - category: Categories.dataLists, extensions: ["colours_data_lists", "shape_statement"], }); }, @@ -288,9 +269,8 @@ Blockly.Blocks["data_deleteoflist"] = { Blockly.Blocks["data_deletealloflist"] = { /** * Block to delete all items from list. - * @this Blockly.Block */ - init: function () { + init: function (this: Blockly.Block) { this.jsonInit({ message0: Blockly.Msg.DATA_DELETEALLOFLIST, args0: [ @@ -301,7 +281,6 @@ Blockly.Blocks["data_deletealloflist"] = { defaultType: Constants.LIST_VARIABLE_TYPE, }, ], - category: Categories.dataLists, extensions: ["colours_data_lists", "shape_statement"], }); }, @@ -310,9 +289,8 @@ Blockly.Blocks["data_deletealloflist"] = { Blockly.Blocks["data_insertatlist"] = { /** * Block to insert item to list. - * @this Blockly.Block */ - init: function () { + init: function (this: Blockly.Block) { this.jsonInit({ message0: Blockly.Msg.DATA_INSERTATLIST, args0: [ @@ -331,7 +309,6 @@ Blockly.Blocks["data_insertatlist"] = { defaultType: Constants.LIST_VARIABLE_TYPE, }, ], - category: Categories.dataLists, extensions: ["colours_data_lists", "shape_statement"], }); }, @@ -340,9 +317,8 @@ Blockly.Blocks["data_insertatlist"] = { Blockly.Blocks["data_replaceitemoflist"] = { /** * Block to insert item to list. - * @this Blockly.Block */ - init: function () { + init: function (this: Blockly.Block) { this.jsonInit({ message0: Blockly.Msg.DATA_REPLACEITEMOFLIST, args0: [ @@ -361,7 +337,6 @@ Blockly.Blocks["data_replaceitemoflist"] = { name: "ITEM", }, ], - category: Categories.dataLists, extensions: ["colours_data_lists", "shape_statement"], }); }, @@ -370,9 +345,8 @@ Blockly.Blocks["data_replaceitemoflist"] = { Blockly.Blocks["data_itemoflist"] = { /** * Block for reporting item of list. - * @this Blockly.Block */ - init: function () { + init: function (this: Blockly.Block) { this.jsonInit({ message0: Blockly.Msg.DATA_ITEMOFLIST, args0: [ @@ -388,7 +362,6 @@ Blockly.Blocks["data_itemoflist"] = { }, ], output: null, - category: Categories.dataLists, extensions: ["colours_data_lists"], outputShape: Constants.OUTPUT_SHAPE_ROUND, }); @@ -398,9 +371,8 @@ Blockly.Blocks["data_itemoflist"] = { Blockly.Blocks["data_itemnumoflist"] = { /** * Block for reporting the item # of a string in a list. - * @this Blockly.Block */ - init: function () { + init: function (this: Blockly.Block) { this.jsonInit({ message0: Blockly.Msg.DATA_ITEMNUMOFLIST, args0: [ @@ -416,7 +388,6 @@ Blockly.Blocks["data_itemnumoflist"] = { }, ], output: null, - category: Categories.dataLists, extensions: ["colours_data_lists"], outputShape: Constants.OUTPUT_SHAPE_ROUND, }); @@ -426,9 +397,8 @@ Blockly.Blocks["data_itemnumoflist"] = { Blockly.Blocks["data_lengthoflist"] = { /** * Block for reporting length of list. - * @this Blockly.Block */ - init: function () { + init: function (this: Blockly.Block) { this.jsonInit({ message0: Blockly.Msg.DATA_LENGTHOFLIST, args0: [ @@ -439,7 +409,6 @@ Blockly.Blocks["data_lengthoflist"] = { defaultType: Constants.LIST_VARIABLE_TYPE, }, ], - category: Categories.dataLists, extensions: ["colours_data_lists", "output_number"], }); }, @@ -448,9 +417,8 @@ Blockly.Blocks["data_lengthoflist"] = { Blockly.Blocks["data_listcontainsitem"] = { /** * Block to report whether list contains item. - * @this Blockly.Block */ - init: function () { + init: function (this: Blockly.Block) { this.jsonInit({ message0: Blockly.Msg.DATA_LISTCONTAINSITEM, args0: [ @@ -465,7 +433,6 @@ Blockly.Blocks["data_listcontainsitem"] = { name: "ITEM", }, ], - category: Categories.dataLists, extensions: ["colours_data_lists", "output_boolean"], }); }, @@ -474,9 +441,8 @@ Blockly.Blocks["data_listcontainsitem"] = { Blockly.Blocks["data_showlist"] = { /** * Block to show a list. - * @this Blockly.Block */ - init: function () { + init: function (this: Blockly.Block) { this.jsonInit({ message0: Blockly.Msg.DATA_SHOWLIST, args0: [ @@ -487,7 +453,6 @@ Blockly.Blocks["data_showlist"] = { defaultType: Constants.LIST_VARIABLE_TYPE, }, ], - category: Categories.dataLists, extensions: ["colours_data_lists", "shape_statement"], }); }, @@ -496,9 +461,8 @@ Blockly.Blocks["data_showlist"] = { Blockly.Blocks["data_hidelist"] = { /** * Block to hide a list. - * @this Blockly.Block */ - init: function () { + init: function (this: Blockly.Block) { this.jsonInit({ message0: Blockly.Msg.DATA_HIDELIST, args0: [ @@ -509,7 +473,6 @@ Blockly.Blocks["data_hidelist"] = { defaultType: Constants.LIST_VARIABLE_TYPE, }, ], - category: Categories.dataLists, extensions: ["colours_data_lists", "shape_statement"], }); }, @@ -518,51 +481,57 @@ Blockly.Blocks["data_hidelist"] = { /** * Mixin to add a context menu for a data_variable block. It adds one item for * each variable defined on the workspace. - * @mixin - * @augments Blockly.Block - * @package - * @readonly */ const CUSTOM_CONTEXT_MENU_GET_VARIABLE_MIXIN = { /** * Add context menu option to change the selected variable. - * @param {!Array} options List of menu options to add to. - * @this Blockly.Block + * + * @param options List of menu options to add to. */ - customContextMenu: function (options) { - var fieldName = "VARIABLE"; + customContextMenu: function ( + this: Blockly.Block, + options: Array< + | Blockly.ContextMenuRegistry.ContextMenuOption + | Blockly.ContextMenuRegistry.LegacyContextMenuOption + > + ) { + const fieldName = "VARIABLE"; if (this.isCollapsed()) { return; } - var currentVarName = this.getField(fieldName).getVariable().getName(); + const currentVarName = (this.getField(fieldName) as ScratchFieldVariable) + .getVariable() + .getName(); if (!this.isInFlyout) { - var variablesList = this.workspace.getVariablesOfType( - Constants.SCALAR_VARIABLE_TYPE - ); - variablesList.sort(function (a, b) { - return scratchBlocksUtils.compareStrings(a.getName(), b.getName()); - }); - for (var i = 0; i < variablesList.length; i++) { - var varName = variablesList[i].getName(); - if (varName == currentVarName) continue; + this.workspace + .getVariablesOfType(Constants.SCALAR_VARIABLE_TYPE) + .sort(function ( + a: Blockly.IVariableModel, + b: Blockly.IVariableModel + ) { + return scratchBlocksUtils.compareStrings(a.getName(), b.getName()); + }) + .forEach((variable: Blockly.IVariableModel) => { + const varName = variable.getName(); + if (varName === currentVarName) return; - var option = { enabled: true }; - option.text = varName; - - option.callback = VARIABLE_OPTION_CALLBACK_FACTORY( - this, - variablesList[i].getId(), - fieldName - ); - options.push(option); - } + options.push({ + enabled: true, + text: varName, + callback: VARIABLE_OPTION_CALLBACK_FACTORY( + this, + variable.getId(), + fieldName + ), + }); + }); } else { - var renameOption = { + const renameOption = { text: Blockly.Msg.RENAME_VARIABLE, enabled: true, callback: RENAME_OPTION_CALLBACK_FACTORY(this, fieldName), }; - var deleteOption = { + const deleteOption = { text: Blockly.Msg.DELETE_VARIABLE.replace("%1", currentVarName), enabled: true, callback: DELETE_OPTION_CALLBACK_FACTORY(this, fieldName), @@ -581,51 +550,57 @@ Blockly.Extensions.registerMixin( /** * Mixin to add a context menu for a data_listcontents block. It adds one item for * each list defined on the workspace. - * @mixin - * @augments Blockly.Block - * @package - * @readonly */ const CUSTOM_CONTEXT_MENU_GET_LIST_MIXIN = { /** * Add context menu option to change the selected list. - * @param {!Array} options List of menu options to add to. - * @this Blockly.Block + * + * @param options List of menu options to add to. */ - customContextMenu: function (options) { - var fieldName = "LIST"; + customContextMenu: function ( + this: Blockly.Block, + options: Array< + | Blockly.ContextMenuRegistry.ContextMenuOption + | Blockly.ContextMenuRegistry.LegacyContextMenuOption + > + ) { + const fieldName = "LIST"; if (this.isCollapsed()) { return; } - var currentVarName = this.getField(fieldName).getVariable().getName(); + const currentVarName = (this.getField(fieldName) as ScratchFieldVariable) + .getVariable() + .getName(); if (!this.isInFlyout) { - var variablesList = this.workspace.getVariablesOfType( - Constants.LIST_VARIABLE_TYPE - ); - variablesList.sort(function (a, b) { - return scratchBlocksUtils.compareStrings(a.getName(), b.getName()); - }); - for (var i = 0; i < variablesList.length; i++) { - var varName = variablesList[i].getName(); - if (varName == currentVarName) continue; - - var option = { enabled: true }; - option.text = varName; + this.workspace + .getVariablesOfType(Constants.LIST_VARIABLE_TYPE) + .sort(function ( + a: Blockly.IVariableModel, + b: Blockly.IVariableModel + ) { + return scratchBlocksUtils.compareStrings(a.getName(), b.getName()); + }) + .forEach((variable: Blockly.IVariableModel) => { + const varName = variable.getName(); + if (varName === currentVarName) return; - option.callback = VARIABLE_OPTION_CALLBACK_FACTORY( - this, - variablesList[i].getId(), - fieldName - ); - options.push(option); - } + options.push({ + enabled: true, + text: varName, + callback: VARIABLE_OPTION_CALLBACK_FACTORY( + this, + variable.getId(), + fieldName + ), + }); + }); } else { - var renameOption = { + const renameOption = { text: Blockly.Msg.RENAME_LIST, enabled: true, callback: RENAME_OPTION_CALLBACK_FACTORY(this, fieldName), }; - var deleteOption = { + const deleteOption = { text: Blockly.Msg.DELETE_LIST.replace("%1", currentVarName), enabled: true, callback: DELETE_OPTION_CALLBACK_FACTORY(this, fieldName), @@ -645,14 +620,19 @@ Blockly.Extensions.registerMixin( * block. Each variable on the workspace gets its own item in the dropdown * menu, and clicking on that item changes the text of the field on the source * block. - * @param {!Blockly.Block} block The block to update. - * @param {string} id The id of the variable to set on this block. - * @param {string} fieldName The name of the field to update on the block. - * @return {!function()} A function that updates the block with the new name. + * + * @param block The block to update. + * @param id The id of the variable to set on this block. + * @param fieldName The name of the field to update on the block. + * @returns A function that updates the block with the new name. */ -const VARIABLE_OPTION_CALLBACK_FACTORY = function (block, id, fieldName) { - return function () { - var variableField = block.getField(fieldName); +const VARIABLE_OPTION_CALLBACK_FACTORY = function ( + block: Blockly.Block, + id: string, + fieldName: string +): () => void { + return () => { + const variableField = block.getField(fieldName); if (!variableField) { console.log("Tried to get a variable field on the wrong type of block."); } @@ -663,28 +643,40 @@ const VARIABLE_OPTION_CALLBACK_FACTORY = function (block, id, fieldName) { /** * Callback for rename variable dropdown menu option associated with a * variable getter block. - * @param {!Blockly.Block} block The block with the variable to rename. - * @param {string} fieldName The name of the field to inspect on the block. - * @return {!function()} A function that renames the variable. + * + * @param block The block with the variable to rename. + * @param fieldName The name of the field to inspect on the block. + * @returns A function that renames the variable. */ -const RENAME_OPTION_CALLBACK_FACTORY = function (block, fieldName) { - return function () { - var workspace = block.workspace; - var variable = block.getField(fieldName).getVariable(); - renameVariable(workspace, variable); +const RENAME_OPTION_CALLBACK_FACTORY = function ( + block: Blockly.Block, + fieldName: string +): () => void { + return () => { + const workspace = block.workspace; + const variable = ( + block.getField(fieldName) as ScratchFieldVariable + ).getVariable() as ScratchVariableModel; + renameVariable(workspace as Blockly.WorkspaceSvg, variable); }; }; /** * Callback for delete variable dropdown menu option associated with a * variable getter block. - * @param {!Blockly.Block} block The block with the variable to delete. - * @param {string} fieldName The name of the field to inspect on the block. - * @return {!function()} A function that deletes the variable. + * + * @param block The block with the variable to delete. + * @param fieldName The name of the field to inspect on the block. + * @return A function that deletes the variable. */ -const DELETE_OPTION_CALLBACK_FACTORY = function (block, fieldName) { - return function () { - const variable = block.getField(fieldName).getVariable(); +const DELETE_OPTION_CALLBACK_FACTORY = function ( + block: Blockly.Block, + fieldName: string +): () => void { + return () => { + const variable = ( + block.getField(fieldName) as ScratchFieldVariable + ).getVariable(); Blockly.Variables.deleteVariable(variable.getWorkspace(), variable, block); }; }; diff --git a/src/blocks/event.js b/src/blocks/event.ts similarity index 88% rename from src/blocks/event.js rename to src/blocks/event.ts index 378006586e..609c260e96 100644 --- a/src/blocks/event.js +++ b/src/blocks/event.ts @@ -19,15 +19,13 @@ */ import * as Blockly from "blockly/core"; -import { Categories } from "../categories.js"; -import * as Constants from "../constants.js"; +import * as Constants from "../constants"; Blockly.Blocks["event_whentouchingobject"] = { /** * Block for when a sprite is touching an object. - * @this Blockly.Block */ - init: function () { + init: function (this: Blockly.Block) { this.jsonInit({ message0: Blockly.Msg.EVENT_WHENTOUCHINGOBJECT, args0: [ @@ -36,7 +34,6 @@ Blockly.Blocks["event_whentouchingobject"] = { name: "TOUCHINGOBJECTMENU", }, ], - category: Categories.event, extensions: ["colours_event", "shape_hat"], }); }, @@ -45,9 +42,8 @@ Blockly.Blocks["event_whentouchingobject"] = { Blockly.Blocks["event_touchingobjectmenu"] = { /** * "Touching [Object]" Block Menu. - * @this Blockly.Block */ - init: function () { + init: function (this: Blockly.Block) { this.jsonInit({ message0: "%1", args0: [ @@ -68,9 +64,8 @@ Blockly.Blocks["event_touchingobjectmenu"] = { Blockly.Blocks["event_whenflagclicked"] = { /** * Block for when flag clicked. - * @this Blockly.Block */ - init: function () { + init: function (this: Blockly.Block) { const ws = this.workspace.options.parentWorkspace || this.workspace; this.jsonInit({ id: "event_whenflagclicked", @@ -84,7 +79,6 @@ Blockly.Blocks["event_whenflagclicked"] = { alt: "flag", }, ], - category: Categories.event, extensions: ["colours_event", "shape_hat"], }); }, @@ -93,12 +87,10 @@ Blockly.Blocks["event_whenflagclicked"] = { Blockly.Blocks["event_whenthisspriteclicked"] = { /** * Block for when this sprite clicked. - * @this Blockly.Block */ - init: function () { + init: function (this: Blockly.Block) { this.jsonInit({ message0: Blockly.Msg.EVENT_WHENTHISSPRITECLICKED, - category: Categories.event, extensions: ["colours_event", "shape_hat"], }); }, @@ -107,12 +99,10 @@ Blockly.Blocks["event_whenthisspriteclicked"] = { Blockly.Blocks["event_whenstageclicked"] = { /** * Block for when the stage is clicked. - * @this Blockly.Block */ - init: function () { + init: function (this: Blockly.Block) { this.jsonInit({ message0: Blockly.Msg.EVENT_WHENSTAGECLICKED, - category: Categories.event, extensions: ["colours_event", "shape_hat"], }); }, @@ -121,9 +111,8 @@ Blockly.Blocks["event_whenstageclicked"] = { Blockly.Blocks["event_whenbroadcastreceived"] = { /** * Block for when broadcast received. - * @this Blockly.Block */ - init: function () { + init: function (this: Blockly.Block) { this.jsonInit({ id: "event_whenbroadcastreceived", message0: Blockly.Msg.EVENT_WHENBROADCASTRECEIVED, @@ -136,7 +125,6 @@ Blockly.Blocks["event_whenbroadcastreceived"] = { variable: Blockly.Msg.DEFAULT_BROADCAST_MESSAGE_NAME, }, ], - category: Categories.event, extensions: ["colours_event", "shape_hat"], }); }, @@ -151,9 +139,8 @@ Blockly.Blocks["event_whenbackdropswitchesto"] = {}; Blockly.Blocks["event_whengreaterthan"] = { /** * Block for when loudness/timer/video motion is greater than the value. - * @this Blockly.Block */ - init: function () { + init: function (this: Blockly.Block) { this.jsonInit({ message0: Blockly.Msg.EVENT_WHENGREATERTHAN, args0: [ @@ -170,7 +157,6 @@ Blockly.Blocks["event_whengreaterthan"] = { name: "VALUE", }, ], - category: Categories.event, extensions: ["colours_event", "shape_hat"], }); }, @@ -179,9 +165,8 @@ Blockly.Blocks["event_whengreaterthan"] = { Blockly.Blocks["event_broadcast_menu"] = { /** * Broadcast drop-down menu. - * @this Blockly.Block */ - init: function () { + init: function (this: Blockly.Block) { this.jsonInit({ message0: "%1", args0: [ @@ -201,9 +186,8 @@ Blockly.Blocks["event_broadcast_menu"] = { Blockly.Blocks["event_broadcast"] = { /** * Block to send a broadcast. - * @this Blockly.Block */ - init: function () { + init: function (this: Blockly.Block) { this.jsonInit({ id: "event_broadcast", message0: Blockly.Msg.EVENT_BROADCAST, @@ -213,7 +197,6 @@ Blockly.Blocks["event_broadcast"] = { name: "BROADCAST_INPUT", }, ], - category: Categories.event, extensions: ["colours_event", "shape_statement"], }); }, @@ -222,9 +205,8 @@ Blockly.Blocks["event_broadcast"] = { Blockly.Blocks["event_broadcastandwait"] = { /** * Block to send a broadcast. - * @this Blockly.Block */ - init: function () { + init: function (this: Blockly.Block) { this.jsonInit({ message0: Blockly.Msg.EVENT_BROADCASTANDWAIT, args0: [ @@ -233,7 +215,6 @@ Blockly.Blocks["event_broadcastandwait"] = { name: "BROADCAST_INPUT", }, ], - category: Categories.event, extensions: ["colours_event", "shape_statement"], }); }, @@ -242,9 +223,8 @@ Blockly.Blocks["event_broadcastandwait"] = { Blockly.Blocks["event_whenkeypressed"] = { /** * Block to send a broadcast. - * @this Blockly.Block */ - init: function () { + init: function (this: Blockly.Block) { this.jsonInit({ id: "event_whenkeypressed", message0: Blockly.Msg.EVENT_WHENKEYPRESSED, @@ -298,7 +278,6 @@ Blockly.Blocks["event_whenkeypressed"] = { ], }, ], - category: Categories.event, extensions: ["colours_event", "shape_hat"], }); }, diff --git a/src/blocks/looks.js b/src/blocks/looks.ts similarity index 84% rename from src/blocks/looks.js rename to src/blocks/looks.ts index 132e166bc3..5d3b907e3d 100644 --- a/src/blocks/looks.js +++ b/src/blocks/looks.ts @@ -19,14 +19,12 @@ */ import * as Blockly from "blockly/core"; -import { Categories } from "../categories.js"; Blockly.Blocks["looks_sayforsecs"] = { /** * Block to say for some time. - * @this Blockly.Block */ - init: function () { + init: function (this: Blockly.Block) { this.jsonInit({ message0: Blockly.Msg.LOOKS_SAYFORSECS, args0: [ @@ -39,7 +37,6 @@ Blockly.Blocks["looks_sayforsecs"] = { name: "SECS", }, ], - category: Categories.looks, extensions: ["colours_looks", "shape_statement"], }); }, @@ -48,9 +45,8 @@ Blockly.Blocks["looks_sayforsecs"] = { Blockly.Blocks["looks_say"] = { /** * Block to say. - * @this Blockly.Block */ - init: function () { + init: function (this: Blockly.Block) { this.jsonInit({ message0: Blockly.Msg.LOOKS_SAY, args0: [ @@ -59,7 +55,6 @@ Blockly.Blocks["looks_say"] = { name: "MESSAGE", }, ], - category: Categories.looks, extensions: ["colours_looks", "shape_statement"], }); }, @@ -68,9 +63,8 @@ Blockly.Blocks["looks_say"] = { Blockly.Blocks["looks_thinkforsecs"] = { /** * Block to think for some time. - * @this Blockly.Block */ - init: function () { + init: function (this: Blockly.Block) { this.jsonInit({ message0: Blockly.Msg.LOOKS_THINKFORSECS, args0: [ @@ -83,7 +77,6 @@ Blockly.Blocks["looks_thinkforsecs"] = { name: "SECS", }, ], - category: Categories.looks, extensions: ["colours_looks", "shape_statement"], }); }, @@ -92,9 +85,8 @@ Blockly.Blocks["looks_thinkforsecs"] = { Blockly.Blocks["looks_think"] = { /** * Block to think. - * @this Blockly.Block */ - init: function () { + init: function (this: Blockly.Block) { this.jsonInit({ message0: Blockly.Msg.LOOKS_THINK, args0: [ @@ -103,7 +95,6 @@ Blockly.Blocks["looks_think"] = { name: "MESSAGE", }, ], - category: Categories.looks, extensions: ["colours_looks", "shape_statement"], }); }, @@ -112,12 +103,10 @@ Blockly.Blocks["looks_think"] = { Blockly.Blocks["looks_show"] = { /** * Show block. - * @this Blockly.Block */ - init: function () { + init: function (this: Blockly.Block) { this.jsonInit({ message0: Blockly.Msg.LOOKS_SHOW, - category: Categories.looks, extensions: ["colours_looks", "shape_statement"], }); }, @@ -126,12 +115,10 @@ Blockly.Blocks["looks_show"] = { Blockly.Blocks["looks_hide"] = { /** * Hide block. - * @this Blockly.Block */ - init: function () { + init: function (this: Blockly.Block) { this.jsonInit({ message0: Blockly.Msg.LOOKS_HIDE, - category: Categories.looks, extensions: ["colours_looks", "shape_statement"], }); }, @@ -142,12 +129,10 @@ Blockly.Blocks["looks_hideallsprites"] = { * Hide-all-sprites block. Does not actually do anything. This is an * obsolete block that is implemented for compatibility with Scratch 2.0 * projects. - * @this Blockly.Block */ - init: function () { + init: function (this: Blockly.Block) { this.jsonInit({ message0: Blockly.Msg.LOOKS_HIDEALLSPRITES, - category: Categories.looks, extensions: ["colours_looks", "shape_statement"], }); }, @@ -156,9 +141,8 @@ Blockly.Blocks["looks_hideallsprites"] = { Blockly.Blocks["looks_changeeffectby"] = { /** * Block to change graphic effect. - * @this Blockly.Block */ - init: function () { + init: function (this: Blockly.Block) { this.jsonInit({ message0: Blockly.Msg.LOOKS_CHANGEEFFECTBY, args0: [ @@ -180,7 +164,6 @@ Blockly.Blocks["looks_changeeffectby"] = { name: "CHANGE", }, ], - category: Categories.looks, extensions: ["colours_looks", "shape_statement"], }); }, @@ -189,9 +172,8 @@ Blockly.Blocks["looks_changeeffectby"] = { Blockly.Blocks["looks_seteffectto"] = { /** * Block to set graphic effect. - * @this Blockly.Block */ - init: function () { + init: function (this: Blockly.Block) { this.jsonInit({ message0: Blockly.Msg.LOOKS_SETEFFECTTO, args0: [ @@ -213,7 +195,6 @@ Blockly.Blocks["looks_seteffectto"] = { name: "VALUE", }, ], - category: Categories.looks, extensions: ["colours_looks", "shape_statement"], }); }, @@ -222,12 +203,10 @@ Blockly.Blocks["looks_seteffectto"] = { Blockly.Blocks["looks_cleargraphiceffects"] = { /** * Block to clear graphic effects. - * @this Blockly.Block */ - init: function () { + init: function (this: Blockly.Block) { this.jsonInit({ message0: Blockly.Msg.LOOKS_CLEARGRAPHICEFFECTS, - category: Categories.looks, extensions: ["colours_looks", "shape_statement"], }); }, @@ -236,9 +215,8 @@ Blockly.Blocks["looks_cleargraphiceffects"] = { Blockly.Blocks["looks_changesizeby"] = { /** * Block to change size - * @this Blockly.Block */ - init: function () { + init: function (this: Blockly.Block) { this.jsonInit({ message0: Blockly.Msg.LOOKS_CHANGESIZEBY, args0: [ @@ -247,7 +225,6 @@ Blockly.Blocks["looks_changesizeby"] = { name: "CHANGE", }, ], - category: Categories.looks, extensions: ["colours_looks", "shape_statement"], }); }, @@ -256,9 +233,8 @@ Blockly.Blocks["looks_changesizeby"] = { Blockly.Blocks["looks_setsizeto"] = { /** * Block to set size - * @this Blockly.Block */ - init: function () { + init: function (this: Blockly.Block) { this.jsonInit({ message0: Blockly.Msg.LOOKS_SETSIZETO, args0: [ @@ -267,7 +243,6 @@ Blockly.Blocks["looks_setsizeto"] = { name: "SIZE", }, ], - category: Categories.looks, extensions: ["colours_looks", "shape_statement"], }); }, @@ -276,12 +251,10 @@ Blockly.Blocks["looks_setsizeto"] = { Blockly.Blocks["looks_size"] = { /** * Block to report size - * @this Blockly.Block */ - init: function () { + init: function (this: Blockly.Block) { this.jsonInit({ message0: Blockly.Msg.LOOKS_SIZE, - category: Categories.looks, extensions: ["colours_looks", "output_number", "monitor_block"], }); }, @@ -299,9 +272,8 @@ Blockly.Blocks["looks_changestretchby"] = { * displayed as red "undefined" blocks. Some Scratch projects still contain * these blocks, however, and they don't open in 3.0 unless the blocks * actually exist (though they still don't funcitonally do anything). - * @this Blockly.Block */ - init: function () { + init: function (this: Blockly.Block) { this.jsonInit({ message0: Blockly.Msg.LOOKS_CHANGESTRETCHBY, args0: [ @@ -310,7 +282,6 @@ Blockly.Blocks["looks_changestretchby"] = { name: "CHANGE", }, ], - category: Categories.looks, extensions: ["colours_looks", "shape_statement"], }); }, @@ -321,9 +292,8 @@ Blockly.Blocks["looks_setstretchto"] = { * Block to set stretch. Does not actually do anything. This is an obsolete * block that is implemented for compatibility with Scratch 1.4 projects * (see looks_changestretchby). - * @this Blockly.Block */ - init: function () { + init: function (this: Blockly.Block) { this.jsonInit({ message0: Blockly.Msg.LOOKS_SETSTRETCHTO, args0: [ @@ -332,7 +302,6 @@ Blockly.Blocks["looks_setstretchto"] = { name: "STRETCH", }, ], - category: Categories.looks, extensions: ["colours_looks", "shape_statement"], }); }, @@ -346,9 +315,8 @@ Blockly.Blocks["looks_costume"] = {}; Blockly.Blocks["looks_switchcostumeto"] = { /** * Block to switch the sprite's costume to the selected one. - * @this Blockly.Block */ - init: function () { + init: function (this: Blockly.Block) { this.jsonInit({ message0: Blockly.Msg.LOOKS_SWITCHCOSTUMETO, args0: [ @@ -357,7 +325,6 @@ Blockly.Blocks["looks_switchcostumeto"] = { name: "COSTUME", }, ], - category: Categories.looks, extensions: ["colours_looks", "shape_statement"], }); }, @@ -366,12 +333,10 @@ Blockly.Blocks["looks_switchcostumeto"] = { Blockly.Blocks["looks_nextcostume"] = { /** * Block to switch the sprite's costume to the next one. - * @this Blockly.Block */ - init: function () { + init: function (this: Blockly.Block) { this.jsonInit({ message0: Blockly.Msg.LOOKS_NEXTCOSTUME, - category: Categories.looks, extensions: ["colours_looks", "shape_statement"], }); }, @@ -380,9 +345,8 @@ Blockly.Blocks["looks_nextcostume"] = { Blockly.Blocks["looks_switchbackdropto"] = { /** * Block to switch the backdrop to the selected one. - * @this Blockly.Block */ - init: function () { + init: function (this: Blockly.Block) { this.jsonInit({ message0: Blockly.Msg.LOOKS_SWITCHBACKDROPTO, args0: [ @@ -391,7 +355,6 @@ Blockly.Blocks["looks_switchbackdropto"] = { name: "BACKDROP", }, ], - category: Categories.looks, extensions: ["colours_looks", "shape_statement"], }); }, @@ -405,9 +368,8 @@ Blockly.Blocks["looks_backdrops"] = {}; Blockly.Blocks["looks_gotofrontback"] = { /** * "Go to front/back" Block. - * @this Blockly.Block */ - init: function () { + init: function (this: Blockly.Block) { this.jsonInit({ message0: Blockly.Msg.LOOKS_GOTOFRONTBACK, args0: [ @@ -420,7 +382,6 @@ Blockly.Blocks["looks_gotofrontback"] = { ], }, ], - category: Categories.looks, extensions: ["colours_looks", "shape_statement"], }); }, @@ -429,9 +390,8 @@ Blockly.Blocks["looks_gotofrontback"] = { Blockly.Blocks["looks_goforwardbackwardlayers"] = { /** * "Go forward/backward [Number] Layers" Block. - * @this Blockly.Block */ - init: function () { + init: function (this: Blockly.Block) { this.jsonInit({ message0: Blockly.Msg.LOOKS_GOFORWARDBACKWARDLAYERS, args0: [ @@ -448,7 +408,6 @@ Blockly.Blocks["looks_goforwardbackwardlayers"] = { name: "NUM", }, ], - category: Categories.looks, extensions: ["colours_looks", "shape_statement"], }); }, @@ -457,9 +416,8 @@ Blockly.Blocks["looks_goforwardbackwardlayers"] = { Blockly.Blocks["looks_backdropnumbername"] = { /** * Block to report backdrop's number or name - * @this Blockly.Block */ - init: function () { + init: function (this: Blockly.Block) { this.jsonInit({ message0: Blockly.Msg.LOOKS_BACKDROPNUMBERNAME, args0: [ @@ -472,7 +430,6 @@ Blockly.Blocks["looks_backdropnumbername"] = { ], }, ], - category: Categories.looks, extensions: ["colours_looks", "output_number", "monitor_block"], }); }, @@ -481,9 +438,8 @@ Blockly.Blocks["looks_backdropnumbername"] = { Blockly.Blocks["looks_costumenumbername"] = { /** * Block to report costume's number or name - * @this Blockly.Block */ - init: function () { + init: function (this: Blockly.Block) { this.jsonInit({ message0: Blockly.Msg.LOOKS_COSTUMENUMBERNAME, args0: [ @@ -496,7 +452,6 @@ Blockly.Blocks["looks_costumenumbername"] = { ], }, ], - category: Categories.looks, extensions: ["colours_looks", "output_number", "monitor_block"], }); }, @@ -505,9 +460,8 @@ Blockly.Blocks["looks_costumenumbername"] = { Blockly.Blocks["looks_switchbackdroptoandwait"] = { /** * Block to switch the backdrop to the selected one and wait. - * @this Blockly.Block */ - init: function () { + init: function (this: Blockly.Block) { this.jsonInit({ message0: Blockly.Msg.LOOKS_SWITCHBACKDROPTOANDWAIT, args0: [ @@ -516,7 +470,6 @@ Blockly.Blocks["looks_switchbackdroptoandwait"] = { name: "BACKDROP", }, ], - category: Categories.looks, extensions: ["colours_looks", "shape_statement"], }); }, @@ -525,12 +478,10 @@ Blockly.Blocks["looks_switchbackdroptoandwait"] = { Blockly.Blocks["looks_nextbackdrop"] = { /** * Block to switch the backdrop to the next one. - * @this Blockly.Block */ - init: function () { + init: function (this: Blockly.Block) { this.jsonInit({ message0: Blockly.Msg.LOOKS_NEXTBACKDROP_BLOCK, - category: Categories.looks, extensions: ["colours_looks", "shape_statement"], }); }, diff --git a/src/blocks/math.js b/src/blocks/math.ts similarity index 90% rename from src/blocks/math.js rename to src/blocks/math.ts index 81ee5eeefe..1e6e8ce85f 100644 --- a/src/blocks/math.js +++ b/src/blocks/math.ts @@ -23,14 +23,13 @@ * @author q.neutron@gmail.com (Quynh Neutron) */ import * as Blockly from "blockly/core"; -import * as Constants from "../constants.js"; +import * as Constants from "../constants"; Blockly.Blocks["math_number"] = { /** * Block for generic numeric value. - * @this Blockly.Block */ - init: function () { + init: function (this: Blockly.Block) { this.jsonInit({ message0: "%1", args0: [ @@ -50,9 +49,8 @@ Blockly.Blocks["math_number"] = { Blockly.Blocks["math_integer"] = { /** * Block for integer value (no decimal, + or -). - * @this Blockly.Block */ - init: function () { + init: function (this: Blockly.Block) { this.jsonInit({ message0: "%1", args0: [ @@ -72,9 +70,8 @@ Blockly.Blocks["math_integer"] = { Blockly.Blocks["math_whole_number"] = { /** * Block for whole number value, no negatives or decimals. - * @this Blockly.Block */ - init: function () { + init: function (this: Blockly.Block) { this.jsonInit({ message0: "%1", args0: [ @@ -95,9 +92,8 @@ Blockly.Blocks["math_whole_number"] = { Blockly.Blocks["math_positive_number"] = { /** * Block for positive number value, with decimal. - * @this Blockly.Block */ - init: function () { + init: function (this: Blockly.Block) { this.jsonInit({ message0: "%1", args0: [ @@ -117,9 +113,8 @@ Blockly.Blocks["math_positive_number"] = { Blockly.Blocks["math_angle"] = { /** * Block for angle picker. - * @this Blockly.Block */ - init: function () { + init: function (this: Blockly.Block) { this.jsonInit({ message0: "%1", args0: [ diff --git a/src/blocks/matrix.js b/src/blocks/matrix.ts similarity index 92% rename from src/blocks/matrix.js rename to src/blocks/matrix.ts index 85893b17c0..68940c580b 100644 --- a/src/blocks/matrix.js +++ b/src/blocks/matrix.ts @@ -23,14 +23,13 @@ * @author khanning@gmail.com (Kreg Hanning) */ import * as Blockly from "blockly/core"; -import * as Constants from "../constants.js"; +import * as Constants from "../constants"; Blockly.Blocks["matrix"] = { /** * Block for matrix value. - * @this Blockly.Block */ - init: function () { + init: function (this: Blockly.Block) { this.jsonInit({ message0: "%1", args0: [ diff --git a/src/blocks/motion.js b/src/blocks/motion.ts similarity index 83% rename from src/blocks/motion.js rename to src/blocks/motion.ts index d0a273ab6f..f6d1805a42 100644 --- a/src/blocks/motion.js +++ b/src/blocks/motion.ts @@ -19,14 +19,12 @@ */ import * as Blockly from "blockly/core"; -import { Categories } from "../categories.js"; Blockly.Blocks["motion_movesteps"] = { /** * Block to move steps. - * @this Blockly.Block */ - init: function () { + init: function (this: Blockly.Block) { this.jsonInit({ message0: Blockly.Msg.MOTION_MOVESTEPS, args0: [ @@ -35,7 +33,6 @@ Blockly.Blocks["motion_movesteps"] = { name: "STEPS", }, ], - category: Categories.motion, extensions: ["colours_motion", "shape_statement"], }); }, @@ -44,9 +41,8 @@ Blockly.Blocks["motion_movesteps"] = { Blockly.Blocks["motion_turnright"] = { /** * Block to turn right. - * @this Blockly.Block */ - init: function () { + init: function (this: Blockly.Block) { const ws = this.workspace.options.parentWorkspace || this.workspace; this.jsonInit({ message0: Blockly.Msg.MOTION_TURNRIGHT, @@ -62,7 +58,6 @@ Blockly.Blocks["motion_turnright"] = { name: "DEGREES", }, ], - category: Categories.motion, extensions: ["colours_motion", "shape_statement"], }); }, @@ -71,9 +66,8 @@ Blockly.Blocks["motion_turnright"] = { Blockly.Blocks["motion_turnleft"] = { /** * Block to turn left. - * @this Blockly.Block */ - init: function () { + init: function (this: Blockly.Block) { const ws = this.workspace.options.parentWorkspace || this.workspace; this.jsonInit({ message0: Blockly.Msg.MOTION_TURNLEFT, @@ -89,7 +83,6 @@ Blockly.Blocks["motion_turnleft"] = { name: "DEGREES", }, ], - category: Categories.motion, extensions: ["colours_motion", "shape_statement"], }); }, @@ -98,9 +91,8 @@ Blockly.Blocks["motion_turnleft"] = { Blockly.Blocks["motion_pointindirection"] = { /** * Block to point in direction. - * @this Blockly.Block */ - init: function () { + init: function (this: Blockly.Block) { this.jsonInit({ message0: Blockly.Msg.MOTION_POINTINDIRECTION, args0: [ @@ -109,7 +101,6 @@ Blockly.Blocks["motion_pointindirection"] = { name: "DIRECTION", }, ], - category: Categories.motion, extensions: ["colours_motion", "shape_statement"], }); }, @@ -123,9 +114,8 @@ Blockly.Blocks["motion_pointtowards_menu"] = {}; Blockly.Blocks["motion_pointtowards"] = { /** * Block to point in direction. - * @this Blockly.Block */ - init: function () { + init: function (this: Blockly.Block) { this.jsonInit({ message0: Blockly.Msg.MOTION_POINTTOWARDS, args0: [ @@ -134,7 +124,6 @@ Blockly.Blocks["motion_pointtowards"] = { name: "TOWARDS", }, ], - category: Categories.motion, extensions: ["colours_motion", "shape_statement"], }); }, @@ -148,9 +137,8 @@ Blockly.Blocks["motion_goto_menu"] = {}; Blockly.Blocks["motion_gotoxy"] = { /** * Block to go to X, Y. - * @this Blockly.Block */ - init: function () { + init: function (this: Blockly.Block) { this.jsonInit({ message0: Blockly.Msg.MOTION_GOTOXY, args0: [ @@ -163,7 +151,6 @@ Blockly.Blocks["motion_gotoxy"] = { name: "Y", }, ], - category: Categories.motion, extensions: ["colours_motion", "shape_statement"], }); }, @@ -172,9 +159,8 @@ Blockly.Blocks["motion_gotoxy"] = { Blockly.Blocks["motion_goto"] = { /** * Block to go to a menu item. - * @this Blockly.Block */ - init: function () { + init: function (this: Blockly.Block) { this.jsonInit({ message0: Blockly.Msg.MOTION_GOTO, args0: [ @@ -183,7 +169,6 @@ Blockly.Blocks["motion_goto"] = { name: "TO", }, ], - category: Categories.motion, extensions: ["colours_motion", "shape_statement"], }); }, @@ -192,9 +177,8 @@ Blockly.Blocks["motion_goto"] = { Blockly.Blocks["motion_glidesecstoxy"] = { /** * Block to glide for a specified time. - * @this Blockly.Block */ - init: function () { + init: function (this: Blockly.Block) { this.jsonInit({ message0: Blockly.Msg.MOTION_GLIDESECSTOXY, args0: [ @@ -211,7 +195,6 @@ Blockly.Blocks["motion_glidesecstoxy"] = { name: "Y", }, ], - category: Categories.motion, extensions: ["colours_motion", "shape_statement"], }); }, @@ -225,9 +208,8 @@ Blockly.Blocks["motion_glideto_menu"] = {}; Blockly.Blocks["motion_glideto"] = { /** * Block to glide to a menu item - * @this Blockly.Block */ - init: function () { + init: function (this: Blockly.Block) { this.jsonInit({ message0: Blockly.Msg.MOTION_GLIDETO, args0: [ @@ -240,7 +222,6 @@ Blockly.Blocks["motion_glideto"] = { name: "TO", }, ], - category: Categories.motion, extensions: ["colours_motion", "shape_statement"], }); }, @@ -249,9 +230,8 @@ Blockly.Blocks["motion_glideto"] = { Blockly.Blocks["motion_changexby"] = { /** * Block to change X. - * @this Blockly.Block */ - init: function () { + init: function (this: Blockly.Block) { this.jsonInit({ message0: Blockly.Msg.MOTION_CHANGEXBY, args0: [ @@ -260,7 +240,6 @@ Blockly.Blocks["motion_changexby"] = { name: "DX", }, ], - category: Categories.motion, extensions: ["colours_motion", "shape_statement"], }); }, @@ -269,9 +248,8 @@ Blockly.Blocks["motion_changexby"] = { Blockly.Blocks["motion_setx"] = { /** * Block to set X. - * @this Blockly.Block */ - init: function () { + init: function (this: Blockly.Block) { this.jsonInit({ message0: Blockly.Msg.MOTION_SETX, args0: [ @@ -280,7 +258,6 @@ Blockly.Blocks["motion_setx"] = { name: "X", }, ], - category: Categories.motion, extensions: ["colours_motion", "shape_statement"], }); }, @@ -289,9 +266,8 @@ Blockly.Blocks["motion_setx"] = { Blockly.Blocks["motion_changeyby"] = { /** * Block to change Y. - * @this Blockly.Block */ - init: function () { + init: function (this: Blockly.Block) { this.jsonInit({ message0: Blockly.Msg.MOTION_CHANGEYBY, args0: [ @@ -300,7 +276,6 @@ Blockly.Blocks["motion_changeyby"] = { name: "DY", }, ], - category: Categories.motion, extensions: ["colours_motion", "shape_statement"], }); }, @@ -309,9 +284,8 @@ Blockly.Blocks["motion_changeyby"] = { Blockly.Blocks["motion_sety"] = { /** * Block to set Y. - * @this Blockly.Block */ - init: function () { + init: function (this: Blockly.Block) { this.jsonInit({ message0: Blockly.Msg.MOTION_SETY, args0: [ @@ -320,7 +294,6 @@ Blockly.Blocks["motion_sety"] = { name: "Y", }, ], - category: Categories.motion, extensions: ["colours_motion", "shape_statement"], }); }, @@ -329,12 +302,10 @@ Blockly.Blocks["motion_sety"] = { Blockly.Blocks["motion_ifonedgebounce"] = { /** * Block to bounce on edge. - * @this Blockly.Block */ - init: function () { + init: function (this: Blockly.Block) { this.jsonInit({ message0: Blockly.Msg.MOTION_IFONEDGEBOUNCE, - category: Categories.motion, extensions: ["colours_motion", "shape_statement"], }); }, @@ -343,9 +314,8 @@ Blockly.Blocks["motion_ifonedgebounce"] = { Blockly.Blocks["motion_setrotationstyle"] = { /** * Block to set rotation style. - * @this Blockly.Block */ - init: function () { + init: function (this: Blockly.Block) { this.jsonInit({ message0: Blockly.Msg.MOTION_SETROTATIONSTYLE, args0: [ @@ -359,7 +329,6 @@ Blockly.Blocks["motion_setrotationstyle"] = { ], }, ], - category: Categories.motion, extensions: ["colours_motion", "shape_statement"], }); }, @@ -368,12 +337,10 @@ Blockly.Blocks["motion_setrotationstyle"] = { Blockly.Blocks["motion_xposition"] = { /** * Block to report X. - * @this Blockly.Block */ - init: function () { + init: function (this: Blockly.Block) { this.jsonInit({ message0: Blockly.Msg.MOTION_XPOSITION, - category: Categories.motion, extensions: ["colours_motion", "output_number", "monitor_block"], }); }, @@ -382,12 +349,10 @@ Blockly.Blocks["motion_xposition"] = { Blockly.Blocks["motion_yposition"] = { /** * Block to report Y. - * @this Blockly.Block */ - init: function () { + init: function (this: Blockly.Block) { this.jsonInit({ message0: Blockly.Msg.MOTION_YPOSITION, - category: Categories.motion, extensions: ["colours_motion", "output_number", "monitor_block"], }); }, @@ -396,12 +361,10 @@ Blockly.Blocks["motion_yposition"] = { Blockly.Blocks["motion_direction"] = { /** * Block to report direction. - * @this Blockly.Block */ - init: function () { + init: function (this: Blockly.Block) { this.jsonInit({ message0: Blockly.Msg.MOTION_DIRECTION, - category: Categories.motion, extensions: ["colours_motion", "output_number", "monitor_block"], }); }, @@ -412,9 +375,8 @@ Blockly.Blocks["motion_scroll_right"] = { * Block to scroll the stage right. Does not actually do anything. This is * an obsolete block that is implemented for compatibility with Scratch 2.0 * projects. - * @this Blockly.Block */ - init: function () { + init: function (this: Blockly.Block) { this.jsonInit({ message0: Blockly.Msg.MOTION_SCROLLRIGHT, args0: [ @@ -423,7 +385,6 @@ Blockly.Blocks["motion_scroll_right"] = { name: "DISTANCE", }, ], - category: Categories.motion, extensions: ["colours_motion", "shape_statement"], }); }, @@ -434,9 +395,8 @@ Blockly.Blocks["motion_scroll_up"] = { * Block to scroll the stage up. Does not actually do anything. This is an * obsolete block that is implemented for compatibility with Scratch 2.0 * projects. - * @this Blockly.Block */ - init: function () { + init: function (this: Blockly.Block) { this.jsonInit({ message0: Blockly.Msg.MOTION_SCROLLUP, args0: [ @@ -445,7 +405,6 @@ Blockly.Blocks["motion_scroll_up"] = { name: "DISTANCE", }, ], - category: Categories.motion, extensions: ["colours_motion", "shape_statement"], }); }, @@ -456,9 +415,8 @@ Blockly.Blocks["motion_align_scene"] = { * Block to change the stage's scrolling alignment. Does not actually do * anything. This is an obsolete block that is implemented for compatibility * with Scratch 2.0 projects. - * @this Blockly.Block */ - init: function () { + init: function (this: Blockly.Block) { this.jsonInit({ message0: Blockly.Msg.MOTION_ALIGNSCENE, args0: [ @@ -474,7 +432,6 @@ Blockly.Blocks["motion_align_scene"] = { ], }, ], - category: Categories.motion, extensions: ["colours_motion", "shape_statement"], }); }, @@ -485,12 +442,10 @@ Blockly.Blocks["motion_xscroll"] = { * Block to report the stage's scroll position's X value. Does not actually * do anything. This is an obsolete block that is implemented for * compatibility with Scratch 2.0 projects. - * @this Blockly.Block */ - init: function () { + init: function (this: Blockly.Block) { this.jsonInit({ message0: Blockly.Msg.MOTION_XSCROLL, - category: Categories.motion, extensions: ["colours_motion", "output_number"], }); }, @@ -501,12 +456,10 @@ Blockly.Blocks["motion_yscroll"] = { * Block to report the stage's scroll position's Y value. Does not actually * do anything. This is an obsolete block that is implemented for * compatibility with Scratch 2.0 projects. - * @this Blockly.Block */ - init: function () { + init: function (this: Blockly.Block) { this.jsonInit({ message0: Blockly.Msg.MOTION_YSCROLL, - category: Categories.motion, extensions: ["colours_motion", "output_number"], }); }, diff --git a/src/blocks/note.js b/src/blocks/note.ts similarity index 92% rename from src/blocks/note.js rename to src/blocks/note.ts index 9a936744a0..540447a514 100644 --- a/src/blocks/note.js +++ b/src/blocks/note.ts @@ -23,14 +23,13 @@ * @author ericr@media.mit.edu (Eric Rosenbaum) */ import * as Blockly from "blockly/core"; -import * as Constants from "../constants.js"; +import * as Constants from "../constants"; Blockly.Blocks["note"] = { /** * Block for musical note value. - * @this Blockly.Block */ - init: function () { + init: function (this: Blockly.Block) { this.jsonInit({ message0: "%1", args0: [ diff --git a/src/blocks/operators.js b/src/blocks/operators.ts similarity index 84% rename from src/blocks/operators.js rename to src/blocks/operators.ts index be93a82334..3852579912 100644 --- a/src/blocks/operators.js +++ b/src/blocks/operators.ts @@ -19,14 +19,12 @@ */ import * as Blockly from "blockly/core"; -import { Categories } from "../categories.js"; Blockly.Blocks["operator_add"] = { /** * Block for adding two numbers. - * @this Blockly.Block */ - init: function () { + init: function (this: Blockly.Block) { this.jsonInit({ message0: Blockly.Msg.OPERATORS_ADD, args0: [ @@ -39,7 +37,6 @@ Blockly.Blocks["operator_add"] = { name: "NUM2", }, ], - category: Categories.operators, extensions: ["colours_operators", "output_number"], }); }, @@ -48,9 +45,8 @@ Blockly.Blocks["operator_add"] = { Blockly.Blocks["operator_subtract"] = { /** * Block for subtracting two numbers. - * @this Blockly.Block */ - init: function () { + init: function (this: Blockly.Block) { this.jsonInit({ message0: Blockly.Msg.OPERATORS_SUBTRACT, args0: [ @@ -63,7 +59,6 @@ Blockly.Blocks["operator_subtract"] = { name: "NUM2", }, ], - category: Categories.operators, extensions: ["colours_operators", "output_number"], }); }, @@ -72,9 +67,8 @@ Blockly.Blocks["operator_subtract"] = { Blockly.Blocks["operator_multiply"] = { /** * Block for multiplying two numbers. - * @this Blockly.Block */ - init: function () { + init: function (this: Blockly.Block) { this.jsonInit({ message0: Blockly.Msg.OPERATORS_MULTIPLY, args0: [ @@ -87,7 +81,6 @@ Blockly.Blocks["operator_multiply"] = { name: "NUM2", }, ], - category: Categories.operators, extensions: ["colours_operators", "output_number"], }); }, @@ -96,9 +89,8 @@ Blockly.Blocks["operator_multiply"] = { Blockly.Blocks["operator_divide"] = { /** * Block for dividing two numbers. - * @this Blockly.Block */ - init: function () { + init: function (this: Blockly.Block) { this.jsonInit({ message0: Blockly.Msg.OPERATORS_DIVIDE, args0: [ @@ -111,7 +103,6 @@ Blockly.Blocks["operator_divide"] = { name: "NUM2", }, ], - category: Categories.operators, extensions: ["colours_operators", "output_number"], }); }, @@ -120,9 +111,8 @@ Blockly.Blocks["operator_divide"] = { Blockly.Blocks["operator_random"] = { /** * Block for picking a random number. - * @this Blockly.Block */ - init: function () { + init: function (this: Blockly.Block) { this.jsonInit({ message0: Blockly.Msg.OPERATORS_RANDOM, args0: [ @@ -135,7 +125,6 @@ Blockly.Blocks["operator_random"] = { name: "TO", }, ], - category: Categories.operators, extensions: ["colours_operators", "output_number"], }); }, @@ -144,9 +133,8 @@ Blockly.Blocks["operator_random"] = { Blockly.Blocks["operator_lt"] = { /** * Block for less than comparator. - * @this Blockly.Block */ - init: function () { + init: function (this: Blockly.Block) { this.jsonInit({ message0: Blockly.Msg.OPERATORS_LT, args0: [ @@ -159,7 +147,6 @@ Blockly.Blocks["operator_lt"] = { name: "OPERAND2", }, ], - category: Categories.operators, extensions: ["colours_operators", "output_boolean"], }); }, @@ -168,9 +155,8 @@ Blockly.Blocks["operator_lt"] = { Blockly.Blocks["operator_equals"] = { /** * Block for equals comparator. - * @this Blockly.Block */ - init: function () { + init: function (this: Blockly.Block) { this.jsonInit({ message0: Blockly.Msg.OPERATORS_EQUALS, args0: [ @@ -183,7 +169,6 @@ Blockly.Blocks["operator_equals"] = { name: "OPERAND2", }, ], - category: Categories.operators, extensions: ["colours_operators", "output_boolean"], }); }, @@ -192,9 +177,8 @@ Blockly.Blocks["operator_equals"] = { Blockly.Blocks["operator_gt"] = { /** * Block for greater than comparator. - * @this Blockly.Block */ - init: function () { + init: function (this: Blockly.Block) { this.jsonInit({ message0: Blockly.Msg.OPERATORS_GT, args0: [ @@ -207,7 +191,6 @@ Blockly.Blocks["operator_gt"] = { name: "OPERAND2", }, ], - category: Categories.operators, extensions: ["colours_operators", "output_boolean"], }); }, @@ -216,9 +199,8 @@ Blockly.Blocks["operator_gt"] = { Blockly.Blocks["operator_and"] = { /** * Block for "and" boolean comparator. - * @this Blockly.Block */ - init: function () { + init: function (this: Blockly.Block) { this.jsonInit({ message0: Blockly.Msg.OPERATORS_AND, args0: [ @@ -233,7 +215,6 @@ Blockly.Blocks["operator_and"] = { check: "Boolean", }, ], - category: Categories.operators, extensions: ["colours_operators", "output_boolean"], }); }, @@ -242,9 +223,8 @@ Blockly.Blocks["operator_and"] = { Blockly.Blocks["operator_or"] = { /** * Block for "or" boolean comparator. - * @this Blockly.Block */ - init: function () { + init: function (this: Blockly.Block) { this.jsonInit({ message0: Blockly.Msg.OPERATORS_OR, args0: [ @@ -259,7 +239,6 @@ Blockly.Blocks["operator_or"] = { check: "Boolean", }, ], - category: Categories.operators, extensions: ["colours_operators", "output_boolean"], }); }, @@ -268,9 +247,8 @@ Blockly.Blocks["operator_or"] = { Blockly.Blocks["operator_not"] = { /** * Block for "not" unary boolean operator. - * @this Blockly.Block */ - init: function () { + init: function (this: Blockly.Block) { this.jsonInit({ message0: Blockly.Msg.OPERATORS_NOT, args0: [ @@ -280,7 +258,6 @@ Blockly.Blocks["operator_not"] = { check: "Boolean", }, ], - category: Categories.operators, extensions: ["colours_operators", "output_boolean"], }); }, @@ -289,9 +266,8 @@ Blockly.Blocks["operator_not"] = { Blockly.Blocks["operator_join"] = { /** * Block for string join operator. - * @this Blockly.Block */ - init: function () { + init: function (this: Blockly.Block) { this.jsonInit({ message0: Blockly.Msg.OPERATORS_JOIN, args0: [ @@ -304,7 +280,6 @@ Blockly.Blocks["operator_join"] = { name: "STRING2", }, ], - category: Categories.operators, extensions: ["colours_operators", "output_string"], }); }, @@ -313,9 +288,8 @@ Blockly.Blocks["operator_join"] = { Blockly.Blocks["operator_letter_of"] = { /** * Block for "letter _ of _" operator. - * @this Blockly.Block */ - init: function () { + init: function (this: Blockly.Block) { this.jsonInit({ message0: Blockly.Msg.OPERATORS_LETTEROF, args0: [ @@ -328,7 +302,6 @@ Blockly.Blocks["operator_letter_of"] = { name: "STRING", }, ], - category: Categories.operators, extensions: ["colours_operators", "output_string"], }); }, @@ -337,9 +310,8 @@ Blockly.Blocks["operator_letter_of"] = { Blockly.Blocks["operator_length"] = { /** * Block for string length operator. - * @this Blockly.Block */ - init: function () { + init: function (this: Blockly.Block) { this.jsonInit({ message0: Blockly.Msg.OPERATORS_LENGTH, args0: [ @@ -348,7 +320,6 @@ Blockly.Blocks["operator_length"] = { name: "STRING", }, ], - category: Categories.operators, extensions: ["colours_operators", "output_string"], }); }, @@ -357,9 +328,8 @@ Blockly.Blocks["operator_length"] = { Blockly.Blocks["operator_contains"] = { /** * Block for _ contains _ operator - * @this Blockly.Block */ - init: function () { + init: function (this: Blockly.Block) { this.jsonInit({ message0: Blockly.Msg.OPERATORS_CONTAINS, args0: [ @@ -372,7 +342,6 @@ Blockly.Blocks["operator_contains"] = { name: "STRING2", }, ], - category: Categories.operators, extensions: ["colours_operators", "output_boolean"], }); }, @@ -381,9 +350,8 @@ Blockly.Blocks["operator_contains"] = { Blockly.Blocks["operator_mod"] = { /** * Block for mod two numbers. - * @this Blockly.Block */ - init: function () { + init: function (this: Blockly.Block) { this.jsonInit({ message0: Blockly.Msg.OPERATORS_MOD, args0: [ @@ -396,7 +364,6 @@ Blockly.Blocks["operator_mod"] = { name: "NUM2", }, ], - category: Categories.operators, extensions: ["colours_operators", "output_number"], }); }, @@ -405,9 +372,8 @@ Blockly.Blocks["operator_mod"] = { Blockly.Blocks["operator_round"] = { /** * Block for rounding a numbers. - * @this Blockly.Block */ - init: function () { + init: function (this: Blockly.Block) { this.jsonInit({ message0: Blockly.Msg.OPERATORS_ROUND, args0: [ @@ -416,7 +382,6 @@ Blockly.Blocks["operator_round"] = { name: "NUM", }, ], - category: Categories.operators, extensions: ["colours_operators", "output_number"], }); }, @@ -425,9 +390,8 @@ Blockly.Blocks["operator_round"] = { Blockly.Blocks["operator_mathop"] = { /** * Block for "advanced" math ops on a number. - * @this Blockly.Block */ - init: function () { + init: function (this: Blockly.Block) { this.jsonInit({ message0: Blockly.Msg.OPERATORS_MATHOP, args0: [ @@ -456,7 +420,6 @@ Blockly.Blocks["operator_mathop"] = { name: "NUM", }, ], - category: Categories.operators, extensions: ["colours_operators", "output_number"], }); }, diff --git a/src/blocks/procedures.js b/src/blocks/procedures.ts similarity index 58% rename from src/blocks/procedures.js rename to src/blocks/procedures.ts index 9fd759037b..945b8ca873 100644 --- a/src/blocks/procedures.js +++ b/src/blocks/procedures.ts @@ -23,38 +23,78 @@ */ import * as Blockly from "blockly/core"; -import { FieldTextInputRemovable } from "../fields/field_textinput_removable.js"; +import { FieldTextInputRemovable } from "../fields/field_textinput_removable"; +import type { ScratchDragger } from "../scratch_dragger"; -class DuplicateOnDragDraggable { - constructor(block) { - this.block = block; - } +/** + * An object mapping argument IDs to blocks and shadow DOMs. + */ +type ConnectionMap = { + [key: string]: { + shadow: Element; + block: Blockly.BlockSvg; + }; +}; + +/** + * Possible types for procedure arguments. + */ +enum ArgumentType { + STRING = "s", + NUMBER = "n", + BOOLEAN = "b", +} - isMovable() { +/** + * Class representing a draggable block that copies itself on drag. + */ +class DuplicateOnDragDraggable implements Blockly.IDraggable { + /** + * The newly-created duplicate block. + */ + private copy?: Blockly.BlockSvg; + constructor(private block: Blockly.BlockSvg) {} + + /** + * Returns whether or not this draggable is movable. */ + isMovable(): boolean { return true; } - startDrag(e) { + /** + * Handles the start of a drag. + * + * @param e The event that triggered the drag. + */ + startDrag(e: PointerEvent) { const data = this.block.toCopyData(); - this.copy = Blockly.clipboard.paste(data, this.block.workspace); + this.copy = Blockly.clipboard.paste( + data, + this.block.workspace + ) as Blockly.BlockSvg; this.copy.startDrag(e); } - drag(e) { - this.block.workspace - .getGesture(e) - .getCurrentDragger() - .setDraggable(this.copy); - this.copy.drag(e); + drag(newLoc: Blockly.utils.Coordinate, e?: PointerEvent) { + ( + this.block.workspace.getGesture(e).getCurrentDragger() as ScratchDragger + ).setDraggable(this.copy); + this.copy.drag(newLoc, e); } - endDrag(e) { + endDrag(e: PointerEvent) { this.copy?.endDrag(e); } - revertDrag(e) { + revertDrag() { this.copy?.dispose(); } + + getRelativeToSurfaceXY() { + return this.copy + ? this.copy.getRelativeToSurfaceXY() + : this.block.getRelativeToSurfaceXY(); + } } // Serialization and deserialization. @@ -62,11 +102,11 @@ class DuplicateOnDragDraggable { /** * Create XML to represent the (non-editable) name and arguments of a procedure * call block. - * @return {!Element} XML storage element. - * @this Blockly.Block + * + * @returns XML storage element. */ -function callerMutationToDom() { - var container = document.createElement("mutation"); +function callerMutationToDom(this: ProcedureCallBlock): Element { + const container = document.createElement("mutation"); container.setAttribute("proccode", this.procCode_); container.setAttribute("argumentids", JSON.stringify(this.argumentIds_)); container.setAttribute("warp", JSON.stringify(this.warp_)); @@ -76,10 +116,10 @@ function callerMutationToDom() { /** * Parse XML to restore the (non-editable) name and arguments of a procedure * call block. - * @param {!Element} xmlElement XML storage element. - * @this Blockly.Block + * + * @param xmlElement XML storage element. */ -function callerDomToMutation(xmlElement) { +function callerDomToMutation(this: ProcedureCallBlock, xmlElement: Element) { this.procCode_ = xmlElement.getAttribute("proccode"); this.generateShadows_ = JSON.parse( xmlElement.getAttribute("generateshadows") @@ -92,16 +132,19 @@ function callerDomToMutation(xmlElement) { /** * Create XML to represent the (non-editable) name and arguments of a * procedures_prototype block or a procedures_declaration block. - * @param {boolean=} opt_generateShadows Whether to include the generateshadows - * flag in the generated XML. False if not provided. - * @return {!Element} XML storage element. - * @this Blockly.Block + * + * @param opt_generateShadows Whether to include the generateshadows flag in the + * generated XML. False if not provided. + * @returns XML storage element. */ -function definitionMutationToDom(opt_generateShadows) { - var container = document.createElement("mutation"); +function definitionMutationToDom( + this: ProcedurePrototypeBlock | ProcedureDeclarationBlock, + opt_generateShadows?: boolean +): Element { + const container = document.createElement("mutation"); if (opt_generateShadows) { - container.setAttribute("generateshadows", true); + container.setAttribute("generateshadows", "true"); } container.setAttribute("proccode", this.procCode_); container.setAttribute("argumentids", JSON.stringify(this.argumentIds_)); @@ -117,15 +160,18 @@ function definitionMutationToDom(opt_generateShadows) { /** * Parse XML to restore the (non-editable) name and arguments of a * procedures_prototype block or a procedures_declaration block. - * @param {!Element} xmlElement XML storage element. - * @this Blockly.Block + * + * @param xmlElement XML storage element. */ -function definitionDomToMutation(xmlElement) { +function definitionDomToMutation( + this: ProcedurePrototypeBlock | ProcedureDeclarationBlock, + xmlElement: Element +) { this.procCode_ = xmlElement.getAttribute("proccode"); this.warp_ = JSON.parse(xmlElement.getAttribute("warp")); - var prevArgIds = this.argumentIds_; - var prevDisplayNames = this.displayNames_; + const prevArgIds = this.argumentIds_; + const prevDisplayNames = this.displayNames_; this.argumentIds_ = JSON.parse(xmlElement.getAttribute("argumentids")); this.displayNames_ = JSON.parse(xmlElement.getAttribute("argumentnames")); @@ -133,7 +179,7 @@ function definitionDomToMutation(xmlElement) { xmlElement.getAttribute("argumentdefaults") ); this.updateDisplay_(); - if (this.updateArgumentReporterNames_) { + if ("updateArgumentReporterNames_" in this) { this.updateArgumentReporterNames_(prevArgIds, prevDisplayNames); } } @@ -145,21 +191,19 @@ function definitionDomToMutation(xmlElement) { /** * Returns the name of the procedure this block calls, or the empty string if * it has not yet been set. - * @return {string} Procedure name. - * @this Blockly.Block + * + * @returns Procedure name. */ -function getProcCode() { +function getProcCode(this: ProcedureBlock): string { return this.procCode_; } /** * Update the block's structure and appearance to match the internally stored * mutation. - * @private - * @this Blockly.Block */ -function updateDisplay_() { - var connectionMap = this.disconnectOldBlocks_(); +function updateDisplay_(this: ProcedureBlock) { + const connectionMap = this.disconnectOldBlocks_(); this.removeAllInputs_(); this.createAllInputs_(connectionMap); this.deleteShadows_(connectionMap); @@ -170,18 +214,16 @@ function updateDisplay_() { * in case they can be reattached later. Also save the shadow DOM if it exists. * The result is a map from argument ID to information that was associated with * that argument at the beginning of the mutation. - * @return {!Object.} An object - * mapping argument IDs to blocks and shadow DOMs. - * @private - * @this Blockly.Block + * + * @returns An object mapping argument IDs to blocks and shadow DOMs. */ -function disconnectOldBlocks_() { +function disconnectOldBlocks_(this: ProcedureBlock): ConnectionMap { // Remove old stuff - var connectionMap = {}; - for (var i = 0, input; (input = this.inputList[i]); i++) { + const connectionMap: ConnectionMap = {}; + for (const input of this.inputList) { if (input.connection) { - var target = input.connection.targetBlock(); - var saveInfo = { + const target = input.connection.targetBlock() as Blockly.BlockSvg; + const saveInfo = { shadow: input.connection.getShadowDom(), block: target, }; @@ -198,40 +240,39 @@ function disconnectOldBlocks_() { /** * Remove all inputs on the block, including dummy inputs. * Assumes no input has shadow DOM set. - * @private - * @this Blockly.Block */ -function removeAllInputs_() { +function removeAllInputs_(this: ProcedureBlock) { // Delete inputs directly instead of with block.removeInput to avoid splicing // out of the input list at every index. - for (var i = 0, input; (input = this.inputList[i]); i++) { - input.dispose(); - } + this.inputList.forEach((input: Blockly.Input) => input.dispose()); this.inputList = []; } /** * Create all inputs specified by the new procCode, and populate them with * shadow blocks or reconnected old blocks as appropriate. - * @param {!Object.} - * connectionMap An object mapping argument IDs to blocks and shadow DOMs. - * @private - * @this Blockly.Block + * + * @param connectionMap An object mapping argument IDs to blocks and shadow DOMs. */ -function createAllInputs_(connectionMap) { +function createAllInputs_(this: ProcedureBlock, connectionMap: ConnectionMap) { // Split the proc into components, by %n, %b, and %s (ignoring escaped). - var procComponents = this.procCode_.split(/(?=[^\\]%[nbs])/); - procComponents = procComponents.map(function (c) { - return c.trim(); // Strip whitespace. - }); + const procComponents = this.procCode_ + .split(/(?=[^\\]%[nbs])/) + .map(function (c: string) { + return c.trim(); // Strip whitespace. + }); // Create arguments and labels as appropriate. - var argumentCount = 0; - for (var i = 0, component; (component = procComponents[i]); i++) { - var labelText; - if (component.substring(0, 1) == "%") { - var argumentType = component.substring(1, 2); + let argumentCount = 0; + for (const component of procComponents) { + let labelText; + if (component.substring(0, 1) === "%") { + const argumentType = component.substring(1, 2); if ( - !(argumentType == "n" || argumentType == "b" || argumentType == "s") + !( + argumentType === ArgumentType.NUMBER || + argumentType === ArgumentType.BOOLEAN || + argumentType === ArgumentType.STRING + ) ) { throw new Error( "Found an custom procedure with an invalid type: " + argumentType @@ -239,10 +280,10 @@ function createAllInputs_(connectionMap) { } labelText = component.substring(2).trim(); - var id = this.argumentIds_[argumentCount]; + const id = this.argumentIds_[argumentCount]; - var input = this.appendValueInput(id); - if (argumentType == "b") { + const input = this.appendValueInput(id); + if (argumentType === ArgumentType.BOOLEAN) { input.setCheck("Boolean"); } this.populateArgument_( @@ -262,19 +303,17 @@ function createAllInputs_(connectionMap) { /** * Delete all shadow blocks in the given map. - * @param {!Object.} connectionMap An object mapping - * argument IDs to the blocks that were connected to those IDs at the - * beginning of the mutation. - * @private - * @this Blockly.Block + * + * @param connectionMap An object mapping argument IDs to the blocks that were + * connected to those IDs at the beginning of the mutation. */ -function deleteShadows_(connectionMap) { +function deleteShadows_(this: ProcedureBlock, connectionMap: ConnectionMap) { // Get rid of all of the old shadow blocks if they aren't connected. if (connectionMap) { - for (var id in connectionMap) { - var saveInfo = connectionMap[id]; + for (const id in connectionMap) { + const saveInfo = connectionMap[id]; if (saveInfo) { - var block = saveInfo["block"]; + const block = saveInfo["block"]; if (block && block.isShadow()) { block.dispose(); connectionMap[id] = null; @@ -290,10 +329,13 @@ function deleteShadows_(connectionMap) { /** * Add a label field with the given text to a procedures_call or * procedures_prototype block. - * @param {string} text The label text. - * @private + * + * @param text The label text. */ -function addLabelField_(text) { +function addLabelField_( + this: ProcedureCallBlock | ProcedurePrototypeBlock, + text: string +) { this.appendDummyInput().appendField(text); } @@ -301,10 +343,10 @@ function addLabelField_(text) { * Add a label editor with the given text to a procedures_declaration * block. Editing the text in the label editor updates the text of the * corresponding label fields on function calls. - * @param {string} text The label text. - * @private + * + * @param text The label text. */ -function addLabelEditor_(text) { +function addLabelEditor_(this: ProcedureDeclarationBlock, text: string) { if (text) { this.appendDummyInput(Blockly.utils.idGenerator.genUid()).appendField( new FieldTextInputRemovable(text) @@ -314,24 +356,25 @@ function addLabelEditor_(text) { /** * Build a DOM node representing a shadow block of the given type. - * @param {string} type One of 's' (string) or 'n' (number). - * @return {!Element} The DOM node representing the new shadow block. - * @private - * @this Blockly.Block - */ -function buildShadowDom_(type) { - var shadowDom = goog.dom.createDom("shadow"); - if (type == "n") { - var shadowType = "math_number"; - var fieldName = "NUM"; - var fieldValue = "1"; + * + * @param type One of 's' (string) or 'n' (number). + * @returns The DOM node representing the new shadow block. + */ +function buildShadowDom_(type: ArgumentType): Element { + const shadowDom = document.createElement("shadow"); + let shadowType, fieldName, fieldValue; + if (type === ArgumentType.NUMBER) { + shadowType = "math_number"; + fieldName = "NUM"; + fieldValue = "1"; } else { - var shadowType = "text"; - var fieldName = "TEXT"; - var fieldValue = ""; + shadowType = "text"; + fieldName = "TEXT"; + fieldValue = ""; } shadowDom.setAttribute("type", shadowType); - var fieldDom = goog.dom.createDom("field", null, fieldValue); + const fieldDom = document.createElement("field"); + fieldDom.textContent = fieldValue; fieldDom.setAttribute("name", fieldName); shadowDom.appendChild(fieldDom); return shadowDom; @@ -339,19 +382,27 @@ function buildShadowDom_(type) { /** * Create a new shadow block and attach it to the given input. - * @param {!Blockly.Input} input The value input to attach a block to. - * @param {string} argumentType One of 'b' (boolean), 's' (string) or + * + * @param input The value input to attach a block to. + * @param argumentType One of 'b' (boolean), 's' (string) or * 'n' (number). - * @private - * @this Blockly.Block */ -function attachShadow_(input, argumentType) { - if (argumentType == "n" || argumentType == "s") { - var blockType = argumentType == "n" ? "math_number" : "text"; +function attachShadow_( + this: ProcedureCallBlock, + input: Blockly.Input, + argumentType: ArgumentType +) { + if ( + argumentType === ArgumentType.NUMBER || + argumentType === ArgumentType.STRING + ) { + const blockType = + argumentType === ArgumentType.NUMBER ? "math_number" : "text"; Blockly.Events.disable(); + let newBlock; try { - var newBlock = this.workspace.newBlock(blockType); - if (argumentType == "n") { + newBlock = this.workspace.newBlock(blockType); + if (argumentType === ArgumentType.NUMBER) { newBlock.setFieldValue("1", "NUM"); } else { newBlock.setFieldValue("", "TEXT"); @@ -359,7 +410,7 @@ function attachShadow_(input, argumentType) { newBlock.setShadow(true); if (!this.isInsertionMarker()) { newBlock.initSvg(); - newBlock.render(false); + newBlock.render(); } } finally { Blockly.Events.enable(); @@ -375,28 +426,36 @@ function attachShadow_(input, argumentType) { /** * Create a new argument reporter block. - * @param {string} argumentType One of 'b' (boolean), 's' (string) or + * + * @param argumentType One of 'b' (boolean), 's' (string) or * 'n' (number). - * @param {string} displayName The name of the argument as provided by the + * @param displayName The name of the argument as provided by the * user, which becomes the text of the label on the argument reporter block. - * @return {!Blockly.BlockSvg} The newly created argument reporter block. - * @private - * @this Blockly.Block + * @returns The newly created argument reporter block. */ -function createArgumentReporter_(argumentType, displayName) { - if (argumentType == "n" || argumentType == "s") { - var blockType = "argument_reporter_string_number"; +function createArgumentReporter_( + this: ProcedurePrototypeBlock, + argumentType: ArgumentType, + displayName: string +): Blockly.BlockSvg { + let blockType; + if ( + argumentType === ArgumentType.NUMBER || + argumentType === ArgumentType.STRING + ) { + blockType = "argument_reporter_string_number"; } else { - var blockType = "argument_reporter_boolean"; + blockType = "argument_reporter_boolean"; } Blockly.Events.disable(); + let newBlock; try { - var newBlock = this.workspace.newBlock(blockType); + newBlock = this.workspace.newBlock(blockType); newBlock.setShadow(true); newBlock.setFieldValue(displayName, "VALUE"); if (!this.isInsertionMarker()) { newBlock.initSvg(); - newBlock.render(false); + newBlock.render(); } } finally { Blockly.Events.enable(); @@ -412,20 +471,25 @@ function createArgumentReporter_(argumentType, displayName) { /** * Populate the argument by attaching the correct child block or shadow to the * given input. - * @param {string} type One of 'b' (boolean), 's' (string) or 'n' (number). - * @param {number} index The index of this argument into the argument id array. - * @param {!Object.} - * connectionMap An object mapping argument IDs to blocks and shadow DOMs. - * @param {string} id The ID of the input to populate. - * @param {!Blockly.Input} input The newly created input to populate. - * @private - * @this Blockly.Block - */ -function populateArgumentOnCaller_(type, index, connectionMap, id, input) { - var oldBlock = null; - var oldShadow = null; + * + * @param type One of 'b' (boolean), 's' (string) or 'n' (number). + * @param index The index of this argument into the argument id array. + * @param connectionMap An object mapping argument IDs to blocks and shadow DOMs. + * @param id The ID of the input to populate. + * @param input The newly created input to populate. + */ +function populateArgumentOnCaller_( + this: ProcedureCallBlock, + type: ArgumentType, + index: number, + connectionMap: ConnectionMap, + id: string, + input: Blockly.Input +) { + let oldBlock: Blockly.BlockSvg; + let oldShadow: Element; if (connectionMap && id in connectionMap) { - var saveInfo = connectionMap[id]; + const saveInfo = connectionMap[id]; oldBlock = saveInfo["block"]; oldShadow = saveInfo["shadow"]; } @@ -434,9 +498,8 @@ function populateArgumentOnCaller_(type, index, connectionMap, id, input) { // Reattach the old block and shadow DOM. connectionMap[input.name] = null; oldBlock.outputConnection.connect(input.connection); - if (type != "b" && this.generateShadows_) { - var shadowDom = oldShadow || this.buildShadowDom_(type); - console.log("setting shadow dom: " + shadowDom); + if (type !== ArgumentType.BOOLEAN && this.generateShadows_) { + const shadowDom = oldShadow || this.buildShadowDom_(type); input.connection.setShadowDom(shadowDom); } } else if (this.generateShadows_) { @@ -447,35 +510,41 @@ function populateArgumentOnCaller_(type, index, connectionMap, id, input) { /** * Populate the argument by attaching the correct argument reporter to the given * input. - * @param {string} type One of 'b' (boolean), 's' (string) or 'n' (number). - * @param {number} index The index of this argument into the argument ID and + * + * @param type One of 'b' (boolean), 's' (string) or 'n' (number). + * @param index The index of this argument into the argument ID and * argument display name arrays. - * @param {!Object.} - * connectionMap An object mapping argument IDs to blocks and shadow DOMs. - * @param {string} id The ID of the input to populate. - * @param {!Blockly.Input} input The newly created input to populate. - * @private - * @this Blockly.Block - */ -function populateArgumentOnPrototype_(type, index, connectionMap, id, input) { - var oldBlock = null; + * @param connectionMap An object mapping argument IDs to blocks and shadow DOMs. + * @param id The ID of the input to populate. + * @param input The newly created input to populate. + */ +function populateArgumentOnPrototype_( + this: ProcedurePrototypeBlock, + type: ArgumentType, + index: number, + connectionMap: ConnectionMap, + id: string, + input: Blockly.Input +) { + let oldBlock = null; if (connectionMap && id in connectionMap) { - var saveInfo = connectionMap[id]; + const saveInfo = connectionMap[id]; oldBlock = saveInfo["block"]; } - var oldTypeMatches = checkOldTypeMatches_(oldBlock, type); - var displayName = this.displayNames_[index]; + const oldTypeMatches = checkOldTypeMatches_(oldBlock, type); + const displayName = this.displayNames_[index]; // Decide which block to attach. + let argumentReporter: Blockly.BlockSvg; if (connectionMap && oldBlock && oldTypeMatches) { // Update the text if needed. The old argument reporter is the same type, // and on the same input, but the argument's display name may have changed. - var argumentReporter = oldBlock; + argumentReporter = oldBlock; argumentReporter.setFieldValue(displayName, "VALUE"); connectionMap[input.name] = null; } else { - var argumentReporter = this.createArgumentReporter_(type, displayName); + argumentReporter = this.createArgumentReporter_(type, displayName); } // Attach the block. @@ -485,36 +554,42 @@ function populateArgumentOnPrototype_(type, index, connectionMap, id, input) { /** * Populate the argument by attaching the correct argument editor to the given * input. - * @param {string} type One of 'b' (boolean), 's' (string) or 'n' (number). - * @param {number} index The index of this argument into the argument id and - * argument display name arrays. - * @param {!Object.} - * connectionMap An object mapping argument IDs to blocks and shadow DOMs. - * @param {string} id The ID of the input to populate. - * @param {!Blockly.Input} input The newly created input to populate. - * @private - * @this Blockly.Block - */ -function populateArgumentOnDeclaration_(type, index, connectionMap, id, input) { - var oldBlock = null; + * + * @param type One of 'b' (boolean), 's' (string) or 'n' (number). + * @param index The index of this argument into the argument id and argument + * display name arrays. + * @param connectionMap An object mapping argument IDs to blocks and shadow DOMs. + * @param id The ID of the input to populate. + * @param input The newly created input to populate. + */ +function populateArgumentOnDeclaration_( + this: ProcedureDeclarationBlock, + type: ArgumentType, + index: number, + connectionMap: ConnectionMap, + id: string, + input: Blockly.Input +) { + let oldBlock = null; if (connectionMap && id in connectionMap) { - var saveInfo = connectionMap[id]; + const saveInfo = connectionMap[id]; oldBlock = saveInfo["block"]; } // TODO: This always returns false, because it checks for argument reporter // blocks instead of argument editor blocks. Create a new version for argument // editors. - var oldTypeMatches = checkOldTypeMatches_(oldBlock, type); - var displayName = this.displayNames_[index]; + const oldTypeMatches = checkOldTypeMatches_(oldBlock, type); + const displayName = this.displayNames_[index]; // Decide which block to attach. + let argumentEditor: Blockly.BlockSvg; if (oldBlock && oldTypeMatches) { - var argumentEditor = oldBlock; + argumentEditor = oldBlock; oldBlock.setFieldValue(displayName, "TEXT"); connectionMap[input.name] = null; } else { - var argumentEditor = this.createArgumentEditor_(type, displayName); + argumentEditor = this.createArgumentEditor_(type, displayName); } // Attach the block. @@ -524,21 +599,28 @@ function populateArgumentOnDeclaration_(type, index, connectionMap, id, input) { /** * Check whether the type of the old block corresponds to the given argument * type. - * @param {Blockly.BlockSvg} oldBlock The old block to check. - * @param {string} type The argument type. One of 'n', 'n', or 's'. - * @return {boolean} True if the type matches, false otherwise. + * + * @param oldBlock The old block to check. + * @param type The argument type. One of 'n', 'n', or 's'. + * @returns True if the type matches, false otherwise. */ -function checkOldTypeMatches_(oldBlock, type) { +function checkOldTypeMatches_( + oldBlock: Blockly.BlockSvg | null, + type: string +): boolean { if (!oldBlock) { return false; } if ( - (type == "n" || type == "s") && - oldBlock.type == "argument_reporter_string_number" + (type === ArgumentType.NUMBER || type === ArgumentType.STRING) && + oldBlock.type === "argument_reporter_string_number" ) { return true; } - if (type == "b" && oldBlock.type == "argument_reporter_boolean") { + if ( + type === ArgumentType.BOOLEAN && + oldBlock.type === "argument_reporter_boolean" + ) { return true; } return false; @@ -548,21 +630,27 @@ function checkOldTypeMatches_(oldBlock, type) { * Create an argument editor. * An argument editor is a shadow block with a single text field, which is used * to set the display name of the argument. - * @param {string} argumentType One of 'b' (boolean), 's' (string) or - * 'n' (number). - * @param {string} displayName The display name of this argument, which is the - * text of the field on the shadow block. - * @return {!Blockly.BlockSvg} The newly created argument editor block. - * @private - * @this Blockly.Block + * + * @param argumentType One of 'b' (boolean), 's' (string) or 'n' (number). + * @param displayName The display name of this argument, which is the text of + * the field on the shadow block. + * @returns The newly created argument editor block. */ -function createArgumentEditor_(argumentType, displayName) { +function createArgumentEditor_( + this: ProcedureDeclarationBlock, + argumentType: ArgumentType, + displayName: string +): Blockly.BlockSvg { Blockly.Events.disable(); + let newBlock; try { - if (argumentType == "n" || argumentType == "s") { - var newBlock = this.workspace.newBlock("argument_editor_string_number"); + if ( + argumentType === ArgumentType.NUMBER || + argumentType === ArgumentType.STRING + ) { + newBlock = this.workspace.newBlock("argument_editor_string_number"); } else { - var newBlock = this.workspace.newBlock("argument_editor_boolean"); + newBlock = this.workspace.newBlock("argument_editor_boolean"); } newBlock.setFieldValue(displayName, "TEXT"); newBlock.setShadow(true); @@ -585,23 +673,23 @@ function createArgumentEditor_(argumentType, displayName) { * Update the serializable information on the block based on the existing inputs * and their text. */ -function updateDeclarationProcCode_() { +function updateDeclarationProcCode_(this: ProcedureDeclarationBlock) { this.procCode_ = ""; this.displayNames_ = []; this.argumentIds_ = []; - for (var i = 0; i < this.inputList.length; i++) { - if (i != 0) { + for (let i = 0; i < this.inputList.length; i++) { + if (i !== 0) { this.procCode_ += " "; } - var input = this.inputList[i]; - if (input.type == Blockly.inputs.inputTypes.DUMMY) { + const input = this.inputList[i]; + if (input.type === Blockly.inputs.inputTypes.DUMMY) { this.procCode_ += input.fieldRow[0].getValue(); - } else if (input.type == Blockly.inputs.inputTypes.VALUE) { + } else if (input.type === Blockly.inputs.inputTypes.VALUE) { // Inspect the argument editor. - var target = input.connection.targetBlock(); + const target = input.connection.targetBlock(); this.displayNames_.push(target.getFieldValue("TEXT")); this.argumentIds_.push(input.name); - if (target.type == "argument_editor_boolean") { + if (target.type === "argument_editor_boolean") { this.procCode_ += "%b"; } else { this.procCode_ += "%s"; @@ -616,27 +704,25 @@ function updateDeclarationProcCode_() { /** * Focus on the last argument editor or label editor on the block. - * @private */ -function focusLastEditor_() { +function focusLastEditor_(this: ProcedureDeclarationBlock) { if (this.inputList.length > 0) { - var newInput = this.inputList[this.inputList.length - 1]; - if (newInput.type == Blockly.inputs.inputTypes.DUMMY) { - newInput.fieldRow[0].showEditor_(); - } else if (newInput.type == Blockly.inputs.inputTypes.VALUE) { + const newInput = this.inputList[this.inputList.length - 1]; + if (newInput.type === Blockly.inputs.inputTypes.DUMMY) { + newInput.fieldRow[0].showEditor(); + } else if (newInput.type === Blockly.inputs.inputTypes.VALUE) { // Inspect the argument editor. - var target = newInput.connection.targetBlock(); - target.getField("TEXT").showEditor_(); + const target = newInput.connection.targetBlock(); + target.getField("TEXT").showEditor(); } } } /** * Externally-visible function to add a label to the procedure declaration. - * @public */ -function addLabelExternal() { - Blockly.WidgetDiv.hide(true); +function addLabelExternal(this: ProcedureDeclarationBlock) { + Blockly.WidgetDiv.hide(); this.procCode_ = this.procCode_ + " label text"; this.updateDisplay_(); this.focusLastEditor_(); @@ -645,10 +731,9 @@ function addLabelExternal() { /** * Externally-visible function to add a boolean argument to the procedure * declaration. - * @public */ -function addBooleanExternal() { - Blockly.WidgetDiv.hide(true); +function addBooleanExternal(this: ProcedureDeclarationBlock) { + Blockly.WidgetDiv.hide(); this.procCode_ = this.procCode_ + " %b"; this.displayNames_.push("boolean"); this.argumentIds_.push(Blockly.utils.idGenerator.genUid()); @@ -660,10 +745,9 @@ function addBooleanExternal() { /** * Externally-visible function to add a string/number argument to the procedure * declaration. - * @public */ -function addStringNumberExternal() { - Blockly.WidgetDiv.hide(true); +function addStringNumberExternal(this: ProcedureDeclarationBlock) { + Blockly.WidgetDiv.hide(); this.procCode_ = this.procCode_ + " %s"; this.displayNames_.push("number or text"); this.argumentIds_.push(Blockly.utils.idGenerator.genUid()); @@ -674,28 +758,31 @@ function addStringNumberExternal() { /** * Externally-visible function to get the warp on procedure declaration. - * @return {boolean} The value of the warp_ property. - * @public + * + * @returns The value of the warp_ property. */ -function getWarp() { +function getWarp(this: ProcedureDeclarationBlock): boolean { return this.warp_; } /** * Externally-visible function to set the warp on procedure declaration. - * @param {boolean} warp The value of the warp_ property. - * @public + * + * @param warp The value of the warp_ property. */ -function setWarp(warp) { +function setWarp(this: ProcedureDeclarationBlock, warp: boolean) { this.warp_ = warp; } /** * Callback to remove a field, only for the declaration block. - * @param {Blockly.Field} field The field being removed. - * @public + * + * @param field The field being removed. */ -function removeFieldCallback(field) { +function removeFieldCallback( + this: ProcedureDeclarationBlock, + field: Blockly.Field +) { // Do not delete if there is only one input if (this.inputList.length === 1) { return; @@ -705,19 +792,19 @@ function removeFieldCallback(field) { var input = this.inputList[n]; if (input.connection) { var target = input.connection.targetBlock(); - if (field.name && target.getField(field.name) == field) { + if (field.name && target.getField(field.name) === field) { inputNameToRemove = input.name; } } else { for (var j = 0; j < input.fieldRow.length; j++) { - if (input.fieldRow[j] == field) { + if (input.fieldRow[j] === field) { inputNameToRemove = input.name; } } } } if (inputNameToRemove) { - Blockly.WidgetDiv.hide(true); + Blockly.WidgetDiv.hide(); this.removeInput(inputNameToRemove); this.onChangeFn(); this.updateDisplay_(); @@ -726,12 +813,16 @@ function removeFieldCallback(field) { /** * Callback to pass removeField up to the declaration block from arguments. - * @param {Blockly.Field} field The field being removed. - * @public + * + * @param field The field being removed. */ -function removeArgumentCallback_(field) { - if (this.parentBlock_ && this.parentBlock_.removeFieldCallback) { - this.parentBlock_.removeFieldCallback(field); +function removeArgumentCallback_( + this: ProcedureDeclarationBlock | ProcedureArgumentEditorBlock, + field: Blockly.Field +) { + const parent = this.getParent(); + if (parent && parent.removeFieldCallback) { + parent.removeFieldCallback(field); } } @@ -744,20 +835,22 @@ function removeArgumentCallback_(field) { * Until there is a more explicit way of identifying argument reporter blocks using ids, * be conservative and only update argument reporters that are used in the * stack below the prototype, ie the definition. - * @param {!Array} prevArgIds The previous ordering of argument ids. - * @param {!Array} prevDisplayNames The previous argument names. - * @this Blockly.Block - */ -function updateArgumentReporterNames_(prevArgIds, prevDisplayNames) { - var nameChanges = []; - var argReporters = []; - var definitionBlock = this.getParent(); + * + * @param prevArgIds The previous ordering of argument ids. + * @param prevDisplayNames The previous argument names. + */ +function updateArgumentReporterNames_( + this: ProcedurePrototypeBlock, + prevArgIds: string[], + prevDisplayNames: string[] +) { + const nameChanges: { newName: string; blocks: Blockly.BlockSvg[] }[] = []; + const argReporters: Blockly.BlockSvg[] = []; + const definitionBlock = this.getParent(); if (!definitionBlock) return; // Create a list of argument reporters that are descendants of the definition stack (see above comment) - var allBlocks = definitionBlock.getDescendants(false); - for (var i = 0; i < allBlocks.length; i++) { - var block = allBlocks[i]; + definitionBlock.getDescendants(false).forEach((block: Blockly.BlockSvg) => { if ( (block.type === "argument_reporter_string_number" || block.type === "argument_reporter_boolean") && @@ -766,20 +859,20 @@ function updateArgumentReporterNames_(prevArgIds, prevDisplayNames) { // Exclude arg reporters in the prototype block, which are shadows. argReporters.push(block); } - } + }); // Create a list of "name changes", including the new name and blocks matching the old name // Only search over the current set of argument ids, ignore args that have been removed - for (var i = 0, id; (id = this.argumentIds_[i]); i++) { + for (let i = 0, id; (id = this.argumentIds_[i]); i++) { // Find the previous index of this argument id. Could be -1 if it is newly added. - var prevIndex = prevArgIds.indexOf(id); - if (prevIndex == -1) continue; // Newly added argument, no corresponding previous argument to update. - var prevName = prevDisplayNames[prevIndex]; - if (prevName != this.displayNames_[i]) { + const prevIndex = prevArgIds.indexOf(id); + if (prevIndex === -1) continue; // Newly added argument, no corresponding previous argument to update. + const prevName = prevDisplayNames[prevIndex]; + if (prevName !== this.displayNames_[i]) { nameChanges.push({ newName: this.displayNames_[i], - blocks: argReporters.filter(function (block) { - return block.getFieldValue("VALUE") == prevName; + blocks: argReporters.filter((block) => { + return block.getFieldValue("VALUE") === prevName; }), }); } @@ -787,8 +880,8 @@ function updateArgumentReporterNames_(prevArgIds, prevDisplayNames) { // Finally update the blocks for each name change. // Do this after creating the lists to avoid cycles of renaming. - for (var j = 0, nameChange; (nameChange = nameChanges[j]); j++) { - for (var k = 0, block; (block = nameChange.blocks[k]); k++) { + for (const nameChange of nameChanges) { + for (const block of nameChange.blocks) { block.setFieldValue(nameChange.newName, "VALUE"); } } @@ -797,9 +890,8 @@ function updateArgumentReporterNames_(prevArgIds, prevDisplayNames) { Blockly.Blocks["procedures_definition"] = { /** * Block for defining a procedure with no return value. - * @this Blockly.Block */ - init: function () { + init: function (this: Blockly.Block) { this.jsonInit({ message0: Blockly.Msg.PROCEDURES_DEFINITION, args0: [ @@ -820,9 +912,8 @@ Blockly.Blocks["procedures_definition"] = { Blockly.Blocks["procedures_call"] = { /** * Block for calling a procedure with no return value. - * @this Blockly.Block */ - init: function () { + init: function (this: ProcedureCallBlock) { this.jsonInit({ extensions: [ "colours_more", @@ -858,9 +949,8 @@ Blockly.Blocks["procedures_prototype"] = { /** * Block for calling a procedure with no return value, for rendering inside * define block. - * @this Blockly.Block */ - init: function () { + init: function (this: ProcedurePrototypeBlock) { this.jsonInit({ extensions: ["colours_more", "shape_statement"], }); @@ -894,9 +984,8 @@ Blockly.Blocks["procedures_prototype"] = { Blockly.Blocks["procedures_declaration"] = { /** * The root block in the procedure declaration editor. - * @this Blockly.Block */ - init: function () { + init: function (this: ProcedureDeclarationBlock) { this.jsonInit({ extensions: ["colours_more", "shape_statement"], }); @@ -937,7 +1026,7 @@ Blockly.Blocks["procedures_declaration"] = { }; Blockly.Blocks["argument_reporter_boolean"] = { - init: function () { + init: function (this: Blockly.BlockSvg) { this.jsonInit({ message0: " %1", args0: [ @@ -954,7 +1043,7 @@ Blockly.Blocks["argument_reporter_boolean"] = { }; Blockly.Blocks["argument_reporter_string_number"] = { - init: function () { + init: function (this: Blockly.BlockSvg) { this.jsonInit({ message0: " %1", args0: [ @@ -971,7 +1060,7 @@ Blockly.Blocks["argument_reporter_string_number"] = { }; Blockly.Blocks["argument_editor_boolean"] = { - init: function () { + init: function (this: ProcedureArgumentEditorBlock) { this.jsonInit({ message0: " %1", args0: [ @@ -990,7 +1079,7 @@ Blockly.Blocks["argument_editor_boolean"] = { }; Blockly.Blocks["argument_editor_string_number"] = { - init: function () { + init: function (this: ProcedureArgumentEditorBlock) { this.jsonInit({ message0: " %1", args0: [ @@ -1007,3 +1096,63 @@ Blockly.Blocks["argument_editor_string_number"] = { this.removeFieldCallback = removeArgumentCallback_.bind(this); }, }; + +interface ProcedureBlock extends Blockly.BlockSvg { + procCode_: string; + argumentIds_: string[]; + warp_: boolean; + getProcCode: () => string; + removeAllInputs_: () => void; + disconnectOldBlocks_: () => ConnectionMap; + deleteShadows_: (connectionMap: ConnectionMap) => void; + createAllInputs_: (connectionMap: ConnectionMap) => void; + updateDisplay_: () => void; + populateArgument_: ( + type: ArgumentType, + index: number, + connectionMap: ConnectionMap, + id: string, + input: Blockly.Input + ) => void; + addProcedureLabel_: (text: string) => void; +} + +export interface ProcedureDeclarationBlock extends ProcedureBlock { + displayNames_: string[]; + argumentDefaults_: string[]; + removeFieldCallback: (field: Blockly.Field) => void; + createArgumentEditor_: ( + argumentType: ArgumentType, + displayName: string + ) => Blockly.BlockSvg; + focusLastEditor_: () => void; + getWarp: () => boolean; + setWarp: (warp: boolean) => void; + addLabelExternal: () => void; + addBooleanExternal: () => void; + addStringNumberExternal: () => void; + onChangeFn: () => void; +} + +interface ProcedureCallBlock extends ProcedureBlock { + generateShadows_: boolean; + attachShadow_: (input: Blockly.Input, argumentType: ArgumentType) => void; + buildShadowDom_: (type: ArgumentType) => Element; +} + +interface ProcedurePrototypeBlock extends ProcedureBlock { + displayNames_: string[]; + argumentDefaults_: string[]; + createArgumentReporter_: ( + argumentType: ArgumentType, + displayName: string + ) => Blockly.BlockSvg; + updateArgumentReporterNames_: ( + prevArgIds: string[], + prevDisplayNames: string[] + ) => void; +} + +interface ProcedureArgumentEditorBlock extends Blockly.BlockSvg { + removeFieldCallback: (field: Blockly.Field) => void; +} diff --git a/src/blocks/sensing.js b/src/blocks/sensing.ts similarity index 84% rename from src/blocks/sensing.js rename to src/blocks/sensing.ts index 87d1757e8f..bf8aa2b842 100644 --- a/src/blocks/sensing.js +++ b/src/blocks/sensing.ts @@ -19,15 +19,13 @@ */ import * as Blockly from "blockly/core"; -import { Categories } from "../categories.js"; -import * as Constants from "../constants.js"; +import * as Constants from "../constants"; Blockly.Blocks["sensing_touchingobject"] = { /** * Block to Report if its touching a Object. - * @this Blockly.Block */ - init: function () { + init: function (this: Blockly.Block) { this.jsonInit({ message0: Blockly.Msg.SENSING_TOUCHINGOBJECT, args0: [ @@ -36,7 +34,6 @@ Blockly.Blocks["sensing_touchingobject"] = { name: "TOUCHINGOBJECTMENU", }, ], - category: Categories.sensing, extensions: ["colours_sensing", "output_boolean"], }); }, @@ -50,9 +47,8 @@ Blockly.Blocks["sensing_touchingobjectmenu"] = {}; Blockly.Blocks["sensing_touchingcolor"] = { /** * Block to Report if its touching a certain Color. - * @this Blockly.Block */ - init: function () { + init: function (this: Blockly.Block) { this.jsonInit({ message0: Blockly.Msg.SENSING_TOUCHINGCOLOR, args0: [ @@ -61,7 +57,6 @@ Blockly.Blocks["sensing_touchingcolor"] = { name: "COLOR", }, ], - category: Categories.sensing, extensions: ["colours_sensing", "output_boolean"], }); }, @@ -70,9 +65,8 @@ Blockly.Blocks["sensing_touchingcolor"] = { Blockly.Blocks["sensing_coloristouchingcolor"] = { /** * Block to Report if a color is touching a certain Color. - * @this Blockly.Block */ - init: function () { + init: function (this: Blockly.Block) { this.jsonInit({ message0: Blockly.Msg.SENSING_COLORISTOUCHINGCOLOR, args0: [ @@ -85,7 +79,6 @@ Blockly.Blocks["sensing_coloristouchingcolor"] = { name: "COLOR2", }, ], - category: Categories.sensing, extensions: ["colours_sensing", "output_boolean"], }); }, @@ -94,9 +87,8 @@ Blockly.Blocks["sensing_coloristouchingcolor"] = { Blockly.Blocks["sensing_distanceto"] = { /** * Block to Report distance to another Object. - * @this Blockly.Block */ - init: function () { + init: function (this: Blockly.Block) { this.jsonInit({ message0: Blockly.Msg.SENSING_DISTANCETO, args0: [ @@ -105,7 +97,6 @@ Blockly.Blocks["sensing_distanceto"] = { name: "DISTANCETOMENU", }, ], - category: Categories.sensing, extensions: ["colours_sensing", "output_number"], }); }, @@ -119,9 +110,8 @@ Blockly.Blocks["sensing_distancetomenu"] = {}; Blockly.Blocks["sensing_askandwait"] = { /** * Block to ask a question and wait - * @this Blockly.Block */ - init: function () { + init: function (this: Blockly.Block) { this.jsonInit({ message0: Blockly.Msg.SENSING_ASKANDWAIT, args0: [ @@ -130,7 +120,6 @@ Blockly.Blocks["sensing_askandwait"] = { name: "QUESTION", }, ], - category: Categories.sensing, extensions: ["colours_sensing", "shape_statement"], }); }, @@ -139,12 +128,10 @@ Blockly.Blocks["sensing_askandwait"] = { Blockly.Blocks["sensing_answer"] = { /** * Block to report answer - * @this Blockly.Block */ - init: function () { + init: function (this: Blockly.Block) { this.jsonInit({ message0: Blockly.Msg.SENSING_ANSWER, - category: Categories.sensing, extensions: ["colours_sensing", "output_number", "monitor_block"], }); }, @@ -153,9 +140,8 @@ Blockly.Blocks["sensing_answer"] = { Blockly.Blocks["sensing_keypressed"] = { /** * Block to Report if a key is pressed. - * @this Blockly.Block */ - init: function () { + init: function (this: Blockly.Block) { this.jsonInit({ message0: Blockly.Msg.SENSING_KEYPRESSED, args0: [ @@ -164,7 +150,6 @@ Blockly.Blocks["sensing_keypressed"] = { name: "KEY_OPTION", }, ], - category: Categories.sensing, extensions: ["colours_sensing", "output_boolean"], }); }, @@ -173,9 +158,8 @@ Blockly.Blocks["sensing_keypressed"] = { Blockly.Blocks["sensing_keyoptions"] = { /** * Options for Keys - * @this Blockly.Block */ - init: function () { + init: function (this: Blockly.Block) { this.jsonInit({ message0: "%1", args0: [ @@ -236,12 +220,10 @@ Blockly.Blocks["sensing_keyoptions"] = { Blockly.Blocks["sensing_mousedown"] = { /** * Block to Report if the mouse is down. - * @this Blockly.Block */ - init: function () { + init: function (this: Blockly.Block) { this.jsonInit({ message0: Blockly.Msg.SENSING_MOUSEDOWN, - category: Categories.sensing, extensions: ["colours_sensing", "output_boolean"], }); }, @@ -250,12 +232,10 @@ Blockly.Blocks["sensing_mousedown"] = { Blockly.Blocks["sensing_mousex"] = { /** * Block to report mouse's x position - * @this Blockly.Block */ - init: function () { + init: function (this: Blockly.Block) { this.jsonInit({ message0: Blockly.Msg.SENSING_MOUSEX, - category: Categories.sensing, extensions: ["colours_sensing", "output_number"], }); }, @@ -264,12 +244,10 @@ Blockly.Blocks["sensing_mousex"] = { Blockly.Blocks["sensing_mousey"] = { /** * Block to report mouse's y position - * @this Blockly.Block */ - init: function () { + init: function (this: Blockly.Block) { this.jsonInit({ message0: Blockly.Msg.SENSING_MOUSEY, - category: Categories.sensing, extensions: ["colours_sensing", "output_number"], }); }, @@ -278,9 +256,8 @@ Blockly.Blocks["sensing_mousey"] = { Blockly.Blocks["sensing_setdragmode"] = { /** * Block to set drag mode. - * @this Blockly.Block */ - init: function () { + init: function (this: Blockly.Block) { this.jsonInit({ message0: Blockly.Msg.SENSING_SETDRAGMODE, args0: [ @@ -293,7 +270,6 @@ Blockly.Blocks["sensing_setdragmode"] = { ], }, ], - category: Categories.sensing, extensions: ["colours_sensing", "shape_statement"], }); }, @@ -302,12 +278,10 @@ Blockly.Blocks["sensing_setdragmode"] = { Blockly.Blocks["sensing_loudness"] = { /** * Block to report loudness - * @this Blockly.Block */ - init: function () { + init: function (this: Blockly.Block) { this.jsonInit({ message0: Blockly.Msg.SENSING_LOUDNESS, - category: Categories.sensing, extensions: ["colours_sensing", "output_number", "monitor_block"], }); }, @@ -318,12 +292,10 @@ Blockly.Blocks["sensing_loud"] = { * Block to report if the loudness is "loud" (greater than 10). This is an * obsolete block that is implemented for compatibility with Scratch 2.0 and * 1.4 projects. - * @this Blockly.Block */ - init: function () { + init: function (this: Blockly.Block) { this.jsonInit({ message0: Blockly.Msg.SENSING_LOUD, - category: Categories.sensing, extensions: ["colours_sensing", "output_boolean"], }); }, @@ -332,12 +304,10 @@ Blockly.Blocks["sensing_loud"] = { Blockly.Blocks["sensing_timer"] = { /** * Block to report timer - * @this Blockly.Block */ - init: function () { + init: function (this: Blockly.Block) { this.jsonInit({ message0: Blockly.Msg.SENSING_TIMER, - category: Categories.sensing, extensions: ["colours_sensing", "output_number", "monitor_block"], }); }, @@ -346,12 +316,10 @@ Blockly.Blocks["sensing_timer"] = { Blockly.Blocks["sensing_resettimer"] = { /** * Block to reset timer - * @this Blockly.Block */ - init: function () { + init: function (this: Blockly.Block) { this.jsonInit({ message0: Blockly.Msg.SENSING_RESETTIMER, - category: Categories.sensing, extensions: ["colours_sensing", "shape_statement"], }); }, @@ -370,9 +338,8 @@ Blockly.Blocks["sensing_of"] = {}; Blockly.Blocks["sensing_current"] = { /** * Block to Report the current option. - * @this Blockly.Block */ - init: function () { + init: function (this: Blockly.Block) { this.jsonInit({ message0: Blockly.Msg.SENSING_CURRENT, args0: [ @@ -390,7 +357,6 @@ Blockly.Blocks["sensing_current"] = { ], }, ], - category: Categories.sensing, extensions: ["colours_sensing", "output_number", "monitor_block"], }); }, @@ -399,12 +365,10 @@ Blockly.Blocks["sensing_current"] = { Blockly.Blocks["sensing_dayssince2000"] = { /** * Block to report days since 2000 - * @this Blockly.Block */ - init: function () { + init: function (this: Blockly.Block) { this.jsonInit({ message0: Blockly.Msg.SENSING_DAYSSINCE2000, - category: Categories.sensing, extensions: ["colours_sensing", "output_number"], }); }, @@ -413,12 +377,10 @@ Blockly.Blocks["sensing_dayssince2000"] = { Blockly.Blocks["sensing_username"] = { /** * Block to report user's username - * @this Blockly.Block */ - init: function () { + init: function (this: Blockly.Block) { this.jsonInit({ message0: Blockly.Msg.SENSING_USERNAME, - category: Categories.sensing, extensions: ["colours_sensing", "output_number", "monitor_block"], }); }, @@ -429,12 +391,10 @@ Blockly.Blocks["sensing_userid"] = { * Block to report user's ID. Does not actually do anything. This is an * obsolete block that is implemented for compatibility with Scratch 2.0 * projects. - * @this Blockly.Block */ - init: function () { + init: function (this: Blockly.Block) { this.jsonInit({ message0: Blockly.Msg.SENSING_USERID, - category: Categories.sensing, extensions: ["colours_sensing", "output_number"], }); }, diff --git a/src/blocks/sound.js b/src/blocks/sound.ts similarity index 83% rename from src/blocks/sound.js rename to src/blocks/sound.ts index 9b3372f0de..eea82bff59 100644 --- a/src/blocks/sound.js +++ b/src/blocks/sound.ts @@ -19,7 +19,6 @@ */ import * as Blockly from "blockly/core"; -import { Categories } from "../categories.js"; /** * Sound effects drop-down menu. Populated dynamically by scratch-gui. @@ -29,9 +28,8 @@ Blockly.Blocks["sound_sounds_menu"] = {}; Blockly.Blocks["sound_play"] = { /** * Block to play sound. - * @this Blockly.Block */ - init: function () { + init: function (this: Blockly.Block) { this.jsonInit({ message0: Blockly.Msg.SOUND_PLAY, args0: [ @@ -40,7 +38,6 @@ Blockly.Blocks["sound_play"] = { name: "SOUND_MENU", }, ], - category: Categories.sound, extensions: ["colours_sounds", "shape_statement"], }); }, @@ -49,9 +46,8 @@ Blockly.Blocks["sound_play"] = { Blockly.Blocks["sound_playuntildone"] = { /** * Block to play sound until done. - * @this Blockly.Block */ - init: function () { + init: function (this: Blockly.Block) { this.jsonInit({ message0: Blockly.Msg.SOUND_PLAYUNTILDONE, args0: [ @@ -60,7 +56,6 @@ Blockly.Blocks["sound_playuntildone"] = { name: "SOUND_MENU", }, ], - category: Categories.sound, extensions: ["colours_sounds", "shape_statement"], }); }, @@ -69,12 +64,10 @@ Blockly.Blocks["sound_playuntildone"] = { Blockly.Blocks["sound_stopallsounds"] = { /** * Block to stop all sounds - * @this Blockly.Block */ - init: function () { + init: function (this: Blockly.Block) { this.jsonInit({ message0: Blockly.Msg.SOUND_STOPALLSOUNDS, - category: Categories.sound, extensions: ["colours_sounds", "shape_statement"], }); }, @@ -83,9 +76,8 @@ Blockly.Blocks["sound_stopallsounds"] = { Blockly.Blocks["sound_seteffectto"] = { /** * Block to set the audio effect - * @this Blockly.Block */ - init: function () { + init: function (this: Blockly.Block) { this.jsonInit({ message0: Blockly.Msg.SOUND_SETEFFECTO, args0: [ @@ -102,7 +94,6 @@ Blockly.Blocks["sound_seteffectto"] = { name: "VALUE", }, ], - category: Categories.sound, extensions: ["colours_sounds", "shape_statement"], }); }, @@ -111,9 +102,8 @@ Blockly.Blocks["sound_seteffectto"] = { Blockly.Blocks["sound_changeeffectby"] = { /** * Block to change the audio effect - * @this Blockly.Block */ - init: function () { + init: function (this: Blockly.Block) { this.jsonInit({ message0: Blockly.Msg.SOUND_CHANGEEFFECTBY, args0: [ @@ -130,7 +120,6 @@ Blockly.Blocks["sound_changeeffectby"] = { name: "VALUE", }, ], - category: Categories.sound, extensions: ["colours_sounds", "shape_statement"], }); }, @@ -139,12 +128,10 @@ Blockly.Blocks["sound_changeeffectby"] = { Blockly.Blocks["sound_cleareffects"] = { /** * Block to clear audio effects - * @this Blockly.Block */ - init: function () { + init: function (this: Blockly.Block) { this.jsonInit({ message0: Blockly.Msg.SOUND_CLEAREFFECTS, - category: Categories.sound, extensions: ["colours_sounds", "shape_statement"], }); }, @@ -153,9 +140,8 @@ Blockly.Blocks["sound_cleareffects"] = { Blockly.Blocks["sound_changevolumeby"] = { /** * Block to change the sprite's volume by a certain value - * @this Blockly.Block */ - init: function () { + init: function (this: Blockly.Block) { this.jsonInit({ message0: Blockly.Msg.SOUND_CHANGEVOLUMEBY, args0: [ @@ -164,7 +150,6 @@ Blockly.Blocks["sound_changevolumeby"] = { name: "VOLUME", }, ], - category: Categories.sound, extensions: ["colours_sounds", "shape_statement"], }); }, @@ -173,9 +158,8 @@ Blockly.Blocks["sound_changevolumeby"] = { Blockly.Blocks["sound_setvolumeto"] = { /** * Block to set the sprite's volume to a certain percent - * @this Blockly.Block */ - init: function () { + init: function (this: Blockly.Block) { this.jsonInit({ message0: Blockly.Msg.SOUND_SETVOLUMETO, args0: [ @@ -184,7 +168,6 @@ Blockly.Blocks["sound_setvolumeto"] = { name: "VOLUME", }, ], - category: Categories.sound, extensions: ["colours_sounds", "shape_statement"], }); }, @@ -193,12 +176,10 @@ Blockly.Blocks["sound_setvolumeto"] = { Blockly.Blocks["sound_volume"] = { /** * Block to report volume - * @this Blockly.Block */ - init: function () { + init: function (this: Blockly.Block) { this.jsonInit({ message0: Blockly.Msg.SOUND_VOLUME, - category: Categories.sound, extensions: ["colours_sounds", "output_number", "monitor_block"], }); }, diff --git a/src/blocks/text.js b/src/blocks/text.ts similarity index 95% rename from src/blocks/text.js rename to src/blocks/text.ts index 5e2cc990ba..4e9335bb4c 100644 --- a/src/blocks/text.js +++ b/src/blocks/text.ts @@ -27,9 +27,8 @@ import * as Blockly from "blockly/core"; Blockly.Blocks["text"] = { /** * Block for text value. - * @this Blockly.Block */ - init: function () { + init: function (this: Blockly.Block) { this.jsonInit({ message0: "%1", args0: [ diff --git a/src/blocks/vertical_extensions.js b/src/blocks/vertical_extensions.ts similarity index 62% rename from src/blocks/vertical_extensions.js rename to src/blocks/vertical_extensions.ts index bbdc75c396..cfda376d16 100644 --- a/src/blocks/vertical_extensions.js +++ b/src/blocks/vertical_extensions.ts @@ -26,24 +26,22 @@ * @author fenichel@google.com (Rachel Fenichel) */ import * as Blockly from "blockly/core"; -import { ScratchProcedures } from "../procedures.js"; -import * as Constants from "../constants.js"; -import { FlyoutCheckboxIcon } from "../flyout_checkbox_icon.js"; +import { ScratchProcedures } from "../procedures"; +import * as Constants from "../constants"; +import { FlyoutCheckboxIcon } from "../flyout_checkbox_icon"; -const VerticalExtensions = {}; /** * Helper function that generates an extension based on a category name. * The generated function will set the block's style based on the category name. - * @param {String} category The name of the category to set colours for. - * @return {function} An extension function that sets colours based on the given - * category. + * + * @param category The name of the category to set colours for. + * @return An extension function that sets colours based on the given category. */ -VerticalExtensions.colourHelper = function (category) { +const colourHelper = function (category: string): () => void { /** * Set the block style on this block for the given category. - * @this {Blockly.Block} */ - return function () { + return function (this: Blockly.Block) { this.setStyle(category); }; }; @@ -51,18 +49,16 @@ VerticalExtensions.colourHelper = function (category) { /** * Extension to set the colours of a text field, which are all the same. */ -VerticalExtensions.COLOUR_TEXTFIELD = function () { - VerticalExtensions.colourHelper("textField").apply(this); +const COLOUR_TEXTFIELD = function (this: Blockly.Block) { + colourHelper("textField").apply(this); }; /** * Extension to make a block fit into a stack of statements, regardless of its * inputs. That means the block should have a previous connection and a next * connection and have inline inputs. - * @this {Blockly.Block} - * @readonly */ -VerticalExtensions.SHAPE_STATEMENT = function () { +const SHAPE_STATEMENT = function (this: Blockly.Block) { this.setInputsInline(true); this.setPreviousStatement(true, null); this.setNextStatement(true, null); @@ -72,10 +68,8 @@ VerticalExtensions.SHAPE_STATEMENT = function () { * Extension to make a block be shaped as a hat block, regardless of its * inputs. That means the block should have a next connection and have inline * inputs, but have no previous connection. - * @this {Blockly.Block} - * @readonly */ -VerticalExtensions.SHAPE_HAT = function () { +const SHAPE_HAT = function (this: Blockly.Block) { this.setInputsInline(true); this.setNextStatement(true, null); this.hat = "cap"; @@ -84,10 +78,8 @@ VerticalExtensions.SHAPE_HAT = function () { /** * Extension to make a block be shaped as a bowler hat block, with rounded * corners on both sides and no indentation for statement blocks. - * @this {Blockly.Block} - * @readonly */ -VerticalExtensions.SHAPE_BOWLER_HAT = function () { +const SHAPE_BOWLER_HAT = function (this: Blockly.Block) { this.setInputsInline(true); this.setNextStatement(true, null); this.hat = "bowler"; @@ -97,10 +89,8 @@ VerticalExtensions.SHAPE_BOWLER_HAT = function () { * Extension to make a block be shaped as an end block, regardless of its * inputs. That means the block should have a previous connection and have * inline inputs, but have no next connection. - * @this {Blockly.Block} - * @readonly */ -VerticalExtensions.SHAPE_END = function () { +const SHAPE_END = function (this: Blockly.Block) { this.setInputsInline(true); this.setPreviousStatement(true, null); }; @@ -109,10 +99,8 @@ VerticalExtensions.SHAPE_END = function () { * Extension to make represent a number reporter in Scratch-Blocks. * That means the block has inline inputs, a round output shape, and a 'Number' * output type. - * @this {Blockly.Block} - * @readonly */ -VerticalExtensions.OUTPUT_NUMBER = function () { +const OUTPUT_NUMBER = function (this: Blockly.Block) { this.setInputsInline(true); this.setOutputShape(Constants.OUTPUT_SHAPE_ROUND); this.setOutput(true, "Number"); @@ -122,10 +110,8 @@ VerticalExtensions.OUTPUT_NUMBER = function () { * Extension to make represent a string reporter in Scratch-Blocks. * That means the block has inline inputs, a round output shape, and a 'String' * output type. - * @this {Blockly.Block} - * @readonly */ -VerticalExtensions.OUTPUT_STRING = function () { +const OUTPUT_STRING = function (this: Blockly.Block) { this.setInputsInline(true); this.setOutputShape(Constants.OUTPUT_SHAPE_ROUND); this.setOutput(true, "String"); @@ -135,10 +121,8 @@ VerticalExtensions.OUTPUT_STRING = function () { * Extension to make represent a boolean reporter in Scratch-Blocks. * That means the block has inline inputs, a round output shape, and a 'Boolean' * output type. - * @this {Blockly.Block} - * @readonly */ -VerticalExtensions.OUTPUT_BOOLEAN = function () { +const OUTPUT_BOOLEAN = function (this: Blockly.Block) { this.setInputsInline(true); this.setOutputShape(Constants.OUTPUT_SHAPE_HEXAGONAL); this.setOutput(true, "Boolean"); @@ -149,34 +133,35 @@ VerticalExtensions.OUTPUT_BOOLEAN = function () { * value in a dropdown. These blocks also have an accompanying checkbox in the * flyout to toggle display of their current value in a chip on the stage. */ -VerticalExtensions.MONITOR_BLOCK = function () { +const MONITOR_BLOCK = function (this: Blockly.BlockSvg) { this.addIcon(new FlyoutCheckboxIcon(this)); - this.checkboxInFlyout = true; + (this as any).checkboxInFlyout = true; }; /** * Mixin to add a context menu for a procedure definition block. * It adds the "edit" option and removes the "duplicate" option. - * @mixin - * @augments Blockly.Block - * @package - * @readonly */ -VerticalExtensions.PROCEDURE_DEF_CONTEXTMENU = function () { +const PROCEDURE_DEF_CONTEXTMENU = function (this: Blockly.Block) { /** * Add the "edit" option and removes the "duplicate" option from the context * menu. - * @param {!Array.} menuOptions List of menu options to edit. - * @this Blockly.Block + * + * @param menuOptions List of menu options to edit. */ this.mixin( { - customContextMenu: function (menuOptions) { + customContextMenu: function ( + menuOptions: Array< + | Blockly.ContextMenuRegistry.ContextMenuOption + | Blockly.ContextMenuRegistry.LegacyContextMenuOption + > + ) { // Add the edit option at the end. menuOptions.push(ScratchProcedures.makeEditOption(this)); // Find and remove the duplicate option - for (var i = 0, option; (option = menuOptions[i]); i++) { + for (let i = 0, option; (option = menuOptions[i]); i++) { if (option.text == Blockly.Msg.DUPLICATE) { menuOptions.splice(i, 1); break; @@ -184,11 +169,11 @@ VerticalExtensions.PROCEDURE_DEF_CONTEXTMENU = function () { } }, checkAndDelete: function () { - var input = this.getInput("custom_block"); + const input = this.getInput("custom_block"); // this is the root block, not the shadow block. if (input && input.connection && input.connection.targetBlock()) { - var procCode = input.connection.targetBlock().getProcCode(); - var didDelete = ScratchProcedures.deleteProcedureDefCallback( + const procCode = input.connection.targetBlock().getProcCode(); + const didDelete = ScratchProcedures.deleteProcedureDefCallback( procCode, this ); @@ -208,29 +193,35 @@ VerticalExtensions.PROCEDURE_DEF_CONTEXTMENU = function () { * @mixin * @augments Blockly.Block * @package - * @readonly */ -VerticalExtensions.PROCEDURE_CALL_CONTEXTMENU = { +const PROCEDURE_CALL_CONTEXTMENU = { /** * Add the "edit" option to the context menu. + * * @todo Add "go to definition" option once implemented. - * @param {!Array.} menuOptions List of menu options to edit. - * @this Blockly.Block + * @param menuOptions List of menu options to edit. */ - customContextMenu: function (menuOptions) { + customContextMenu: function ( + this: Blockly.BlockSvg, + menuOptions: Array< + | Blockly.ContextMenuRegistry.ContextMenuOption + | Blockly.ContextMenuRegistry.LegacyContextMenuOption + > + ) { menuOptions.push(ScratchProcedures.makeEditOption(this)); }, }; -VerticalExtensions.SCRATCH_EXTENSION = function () { - this.isScratchExtension = true; +const SCRATCH_EXTENSION = function (this: Blockly.Block) { + (this as any).isScratchExtension = true; }; + /** * Register all extensions for scratch-blocks. * @package */ -VerticalExtensions.registerAll = function () { - var categoryNames = [ +function registerAll() { + const categoryNames = [ "control", "data", "data_lists", @@ -244,66 +235,38 @@ VerticalExtensions.registerAll = function () { "more", ]; // Register functions for all category colours. - for (var i = 0; i < categoryNames.length; i++) { - var name = categoryNames[i]; - Blockly.Extensions.register( - "colours_" + name, - VerticalExtensions.colourHelper(name) - ); + for (const name of categoryNames) { + Blockly.Extensions.register("colours_" + name, colourHelper(name)); } // Text fields transcend categories. - Blockly.Extensions.register( - "colours_textfield", - VerticalExtensions.COLOUR_TEXTFIELD - ); + Blockly.Extensions.register("colours_textfield", COLOUR_TEXTFIELD); // Register extensions for common block shapes. - Blockly.Extensions.register( - "shape_statement", - VerticalExtensions.SHAPE_STATEMENT - ); - Blockly.Extensions.register("shape_hat", VerticalExtensions.SHAPE_HAT); - Blockly.Extensions.register( - "shape_bowler_hat", - VerticalExtensions.SHAPE_BOWLER_HAT - ); - Blockly.Extensions.register("shape_end", VerticalExtensions.SHAPE_END); + Blockly.Extensions.register("shape_statement", SHAPE_STATEMENT); + Blockly.Extensions.register("shape_hat", SHAPE_HAT); + Blockly.Extensions.register("shape_bowler_hat", SHAPE_BOWLER_HAT); + Blockly.Extensions.register("shape_end", SHAPE_END); // Output shapes and types are related. - Blockly.Extensions.register( - "output_number", - VerticalExtensions.OUTPUT_NUMBER - ); - Blockly.Extensions.register( - "output_string", - VerticalExtensions.OUTPUT_STRING - ); - Blockly.Extensions.register( - "output_boolean", - VerticalExtensions.OUTPUT_BOOLEAN - ); + Blockly.Extensions.register("output_number", OUTPUT_NUMBER); + Blockly.Extensions.register("output_string", OUTPUT_STRING); + Blockly.Extensions.register("output_boolean", OUTPUT_BOOLEAN); // Custom procedures have interesting context menus. Blockly.Extensions.register( "procedure_def_contextmenu", - VerticalExtensions.PROCEDURE_DEF_CONTEXTMENU + PROCEDURE_DEF_CONTEXTMENU ); Blockly.Extensions.registerMixin( "procedure_call_contextmenu", - VerticalExtensions.PROCEDURE_CALL_CONTEXTMENU + PROCEDURE_CALL_CONTEXTMENU ); // Extension blocks have slightly different block rendering. - Blockly.Extensions.register( - "scratch_extension", - VerticalExtensions.SCRATCH_EXTENSION - ); + Blockly.Extensions.register("scratch_extension", SCRATCH_EXTENSION); - Blockly.Extensions.register( - "monitor_block", - VerticalExtensions.MONITOR_BLOCK - ); -}; + Blockly.Extensions.register("monitor_block", MONITOR_BLOCK); +} -VerticalExtensions.registerAll(); +registerAll(); diff --git a/src/categories.js b/src/categories.js deleted file mode 100644 index 1ea1a6640d..0000000000 --- a/src/categories.js +++ /dev/null @@ -1,15 +0,0 @@ -const Categories = { - motion: "motion", - looks: "looks", - sound: "sounds", - pen: "pen", - data: "data", - dataLists: "data-lists", - event: "events", - control: "control", - sensing: "sensing", - operators: "operators", - more: "more", -}; - -export { Categories }; diff --git a/src/checkable_continuous_flyout.js b/src/checkable_continuous_flyout.js index 741d83cf1c..c228131504 100644 --- a/src/checkable_continuous_flyout.js +++ b/src/checkable_continuous_flyout.js @@ -6,8 +6,8 @@ import * as Blockly from "blockly/core"; import { ContinuousFlyout } from "@blockly/continuous-toolbox"; -import { RecyclableBlockFlyoutInflater } from "./recyclable_block_flyout_inflater.js"; -import { StatusIndicatorLabel } from "./status_indicator_label.js"; +import { RecyclableBlockFlyoutInflater } from "./recyclable_block_flyout_inflater"; +import { StatusIndicatorLabel } from "./status_indicator_label"; export class CheckableContinuousFlyout extends ContinuousFlyout { /** diff --git a/src/checkbox_bubble.js b/src/checkbox_bubble.ts similarity index 75% rename from src/checkbox_bubble.js rename to src/checkbox_bubble.ts index e00d41f31f..30349d0da0 100644 --- a/src/checkbox_bubble.js +++ b/src/checkbox_bubble.ts @@ -8,30 +8,24 @@ import * as Blockly from "blockly/core"; /** * A checkbox shown next to reporter blocks in the flyout. - * @implements {Blockly.IBubble} - * @implements {Blockly.IRenderedElement} */ -export class CheckboxBubble { +export class CheckboxBubble + implements Blockly.IBubble, Blockly.IRenderedElement +{ /** * Size of a checkbox next to a variable reporter. - * @type {number} - * @const */ - static CHECKBOX_SIZE = 25; + static readonly CHECKBOX_SIZE = 25; /** * Amount of touchable padding around reporter checkboxes. - * @type {number} - * @const */ - static CHECKBOX_TOUCH_PADDING = 12; + static readonly CHECKBOX_TOUCH_PADDING = 12; /** * SVG path data for checkmark in checkbox. - * @type {string} - * @const */ - static CHECKMARK_PATH = + static readonly CHECKMARK_PATH = "M" + CheckboxBubble.CHECKBOX_SIZE / 4 + " " + @@ -46,59 +40,48 @@ export class CheckboxBubble { CheckboxBubble.CHECKBOX_SIZE / 3; /** - * Size of the checkbox corner radius - * @type {number} - * @const + * Size of the checkbox corner radius. */ - static CHECKBOX_CORNER_RADIUS = 5; + static readonly CHECKBOX_CORNER_RADIUS = 5; /** - * @type {number} - * @const + * The margin around a checkbox. */ - static CHECKBOX_MARGIN = 12; + static readonly CHECKBOX_MARGIN = 12; /** * Total additional width of a row that contains a checkbox. - * @type {number} - * @const */ - static CHECKBOX_SPACE_X = + static readonly CHECKBOX_SPACE_X = CheckboxBubble.CHECKBOX_SIZE + 2 * CheckboxBubble.CHECKBOX_MARGIN; /** * Root SVG element for this bubble. - * @type {!SVGGElement} */ - svgRoot; + svgRoot: SVGGElement; /** * Identifier for click handler, to allow unregistering during disposal. - * @type {!Blockly.browserEvents.Data} */ - clickListener; + clickListener: Blockly.browserEvents.Data; /** * Whether or not this bubble is displayed as checked. Note that the source of * truth is the Scratch VM. - * @type {boolean} */ checked = false; /** * The location of this bubble in workspace coordinates. - * @type {!Blockly.utils.Coordinate} */ location = new Blockly.utils.Coordinate(0, 0); /** * Creates a new flyout checkbox bubble. * - * @param {!Blockly.BlockSvg} sourceBlock The block this bubble should be - * associated with. + * @param sourceBlock The block this bubble should be associated with. */ - constructor(sourceBlock) { - this.sourceBlock = sourceBlock; + constructor(private sourceBlock: Blockly.BlockSvg) { this.svgRoot = Blockly.utils.dom.createSvgElement( Blockly.utils.Svg.G, {}, @@ -149,9 +132,9 @@ export class CheckboxBubble { this.clickListener = Blockly.browserEvents.bind( this.svgRoot, - "mousedown", + "pointerdown", null, - (event) => { + (event: PointerEvent) => { this.setChecked(!this.checked); event.stopPropagation(); event.preventDefault(); @@ -163,9 +146,9 @@ export class CheckboxBubble { /** * Sets whether or not this bubble should be displayed in the checked state. * - * @param {boolean} checked True if this bubble should be checked. + * @param checked True if this bubble should be checked. */ - setChecked(checked) { + setChecked(checked: boolean) { if (checked === this.checked) return; this.checked = checked; @@ -191,28 +174,28 @@ export class CheckboxBubble { * * This method is patched by scratch-gui to query the VM state. * - * @param {string} blockId The ID of the block in question. - * @returns {boolean} True if the block's checkbox should be checked. + * @param blockId The ID of the block in question. + * @returns True if the block's checkbox should be checked. */ - isChecked(blockId) { + isChecked(blockId: string): boolean { return false; } /** * Returns whether this bubble is movable by the user. * - * @returns {boolean} Always returns false. + * @returns Always returns false. */ - isMovable() { + isMovable(): boolean { return false; } /** * Returns the root SVG element for this bubble. * - * @returns {!SVGGElement} The root SVG element. + * @returns The root SVG element. */ - getSvgRoot() { + getSvgRoot(): SVGGElement { return this.svgRoot; } @@ -235,10 +218,10 @@ export class CheckboxBubble { /** * Moves this bubble to the specified location. * - * @param {number} x The location on the X axis to move to. - * @param {number} y The location on the Y axis to move to. + * @param x The location on the X axis to move to. + * @param y The location on the Y axis to move to. */ - moveTo(x, y) { + moveTo(x: number, y: number) { this.location.x = x; this.location.y = y; this.svgRoot.setAttribute("transform", `translate(${x}, ${y})`); @@ -247,9 +230,9 @@ export class CheckboxBubble { /** * Returns this bubble's location in workspace coordinates. * - * @returns {!Blockly.utils.Coordinate} The bubble's location. + * @returns The bubble's location. */ - getRelativeToSurfaceXY() { + getRelativeToSurfaceXY(): Blockly.utils.Coordinate { return this.location; } @@ -266,17 +249,17 @@ export class CheckboxBubble { // to its block and is not draggable by the user. showContextMenu() {} - setDragging(dragging) {} + setDragging(dragging: boolean) {} - startDrag(event) {} + startDrag(event: PointerEvent) {} - drag(newLocation, event) {} + drag(newLocation: Blockly.utils.Coordinate, event: PointerEvent) {} - moveDuringDrag(newLocation) {} + moveDuringDrag(newLocation: Blockly.utils.Coordinate) {} endDrag() {} revertDrag() {} - setDeleteStyle(enable) {} + setDeleteStyle(enable: boolean) {} } diff --git a/src/colours.js b/src/colours.ts similarity index 83% rename from src/colours.js rename to src/colours.ts index 87a2411487..00c95d31df 100644 --- a/src/colours.js +++ b/src/colours.ts @@ -55,10 +55,17 @@ const Colours = { contextualMenuHover: "rgba(77, 151, 255, .25)", }; -function varify(coloursObj, prefix = "--colour") { - return Object.keys(coloursObj) - .map((key) => { - const colour = coloursObj[key]; +/** + * Converts the given colours to CSS variables. + * + * @param coloursObj A (potentially nested) object whose keys are colour names + * and values are CSS colours. + * @param prefix A prefix to prepend to the CSS variables. + * @returns A string containing CSS variable definitions for the colours. + */ +function varify(coloursObj: Object, prefix = "--colour"): string { + return Object.entries(coloursObj) + .map(([key, colour]) => { if (typeof colour === "string") { return `${prefix}-${key}: ${colour};`; } else { diff --git a/src/constants.js b/src/constants.ts similarity index 87% rename from src/constants.js rename to src/constants.ts index ebee4147ab..5aedaf941d 100644 --- a/src/constants.js +++ b/src/constants.ts @@ -1,3 +1,9 @@ +/** + * @license + * Copyright 2024 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + /** * String representing the variable type of scalar variables. * This string, for use in differentiating between types of variables, @@ -32,6 +38,13 @@ export { LIST_VARIABLE_TYPE }; const PROCEDURES_DEFINITION_BLOCK_TYPE = "procedures_definition"; export { PROCEDURES_DEFINITION_BLOCK_TYPE }; +/* + * The type of all procedure declaration blocks. + * @const {string} + */ +const PROCEDURES_DECLARATION_BLOCK_TYPE = "procedures_declaration"; +export { PROCEDURES_DECLARATION_BLOCK_TYPE }; + /** * The type of all procedure prototype blocks. * @const {string} diff --git a/src/context_menu_items.js b/src/context_menu_items.ts similarity index 82% rename from src/context_menu_items.js rename to src/context_menu_items.ts index afa423b372..d79a114ae2 100644 --- a/src/context_menu_items.js +++ b/src/context_menu_items.ts @@ -11,19 +11,19 @@ import * as Blockly from "blockly/core"; */ export function registerDeleteBlock() { const deleteOption = { - displayText(scope) { + displayText(scope: Blockly.ContextMenuRegistry.Scope) { const descendantCount = getDeletableBlocksInStack(scope.block).length; return descendantCount === 1 ? Blockly.Msg["DELETE_BLOCK"] : Blockly.Msg["DELETE_X_BLOCKS"].replace("%1", `${descendantCount}`); }, - preconditionFn(scope) { + preconditionFn(scope: Blockly.ContextMenuRegistry.Scope) { if (!scope.block.isInFlyout && scope.block.isDeletable()) { return "enabled"; } return "hidden"; }, - callback(scope) { + callback(scope: Blockly.ContextMenuRegistry.Scope) { Blockly.Events.setGroup(true); scope.block.dispose(true, true); Blockly.Events.setGroup(false); @@ -35,7 +35,9 @@ export function registerDeleteBlock() { Blockly.ContextMenuRegistry.registry.register(deleteOption); } -function getDeletableBlocksInStack(block) { +function getDeletableBlocksInStack( + block: Blockly.BlockSvg +): Blockly.BlockSvg[] { let descendants = block.getDescendants(false).filter(isDeletable); if (block.getNextBlock()) { // Next blocks are not deleted. @@ -48,7 +50,7 @@ function getDeletableBlocksInStack(block) { return descendants; } -function isDeletable(block) { +function isDeletable(block: Blockly.BlockSvg): boolean { return block.isDeletable() && !block.isShadow(); } @@ -57,7 +59,7 @@ function isDeletable(block) { */ export function registerDeleteAll() { const deleteOption = { - displayText(scope) { + displayText(scope: Blockly.ContextMenuRegistry.Scope) { if (!scope.workspace) { return ""; } @@ -72,7 +74,7 @@ export function registerDeleteAll() { `${deletableBlocksLength}` ); }, - preconditionFn(scope) { + preconditionFn(scope: Blockly.ContextMenuRegistry.Scope) { if (!scope.workspace) { return "disabled"; } @@ -81,7 +83,7 @@ export function registerDeleteAll() { ).length; return deletableBlocksLength > 0 ? "enabled" : "disabled"; }, - callback(scope) { + callback(scope: Blockly.ContextMenuRegistry.Scope) { if (!scope.workspace) { return; } @@ -95,7 +97,7 @@ export function registerDeleteAll() { "%1", String(deletableBlocks.length) ), - function (ok) { + function (ok: boolean) { if (ok) { deleteNext(deletableBlocks); } @@ -116,10 +118,14 @@ export function registerDeleteAll() { * @param workspace to delete all blocks from. * @returns list of blocks to delete. */ -function getDeletableBlocksInWorkspace(workspace) { +function getDeletableBlocksInWorkspace( + workspace: Blockly.WorkspaceSvg +): Blockly.BlockSvg[] { return workspace .getTopBlocks(true) - .flatMap((b) => b.getDescendants(false).filter(isDeletable)); + .flatMap((b: Blockly.BlockSvg) => + b.getDescendants(false).filter(isDeletable) + ); } /** @@ -129,7 +135,7 @@ function getDeletableBlocksInWorkspace(workspace) { * @param eventGroup Event group ID with which all delete events should be * associated. If not specified, create a new group. */ -function deleteNext(deleteList, eventGroup) { +function deleteNext(deleteList: Blockly.BlockSvg[], eventGroup?: string) { const DELAY = 10; if (eventGroup) { Blockly.Events.setGroup(eventGroup); diff --git a/src/css.js b/src/css.ts similarity index 100% rename from src/css.js rename to src/css.ts diff --git a/src/data_category.js b/src/data_category.ts similarity index 60% rename from src/data_category.js rename to src/data_category.ts index 7e104cf2ef..7b9a417fd4 100644 --- a/src/data_category.js +++ b/src/data_category.ts @@ -22,35 +22,31 @@ * @fileoverview Data Flyout components including variable and list blocks. * @author marisaleung@google.com (Marisa Leung) */ -"use strict"; -/** - * @name Blockly.DataCategory - * @namespace - **/ import * as Blockly from "blockly/core"; -import { createVariable } from "./variables.js"; -import { LIST_VARIABLE_TYPE, SCALAR_VARIABLE_TYPE } from "./constants.js"; +import { createVariable } from "./variables"; +import { LIST_VARIABLE_TYPE, SCALAR_VARIABLE_TYPE } from "./constants"; /** * Construct the blocks required by the flyout for the variable category. - * @param {!Blockly.Workspace} workspace The workspace containing variables. - * @return {!Array.} Array of XML block elements. + * + * @param workspace The workspace containing variables. + * @returns Array of XML block elements. */ -export function getVariablesCategory(workspace) { - var variableModelList = workspace.getVariablesOfType(SCALAR_VARIABLE_TYPE); - variableModelList.sort(Blockly.Variables.compareByName); - var xmlList = []; +export function getVariablesCategory( + workspace: Blockly.WorkspaceSvg +): Element[] { + const scalarVariables = workspace.getVariablesOfType(SCALAR_VARIABLE_TYPE); + scalarVariables.sort(Blockly.Variables.compareByName); + const xmlList: Element[] = []; addCreateButton(xmlList, workspace, "VARIABLE"); - for (var i = 0; i < variableModelList.length; i++) { - addDataVariable(xmlList, variableModelList[i]); - } + scalarVariables.forEach((variable) => addDataVariable(xmlList, variable)); - if (variableModelList.length > 0) { - xmlList[xmlList.length - 1].setAttribute("gap", 24); - var firstVariable = variableModelList[0]; + if (scalarVariables.length > 0) { + xmlList[xmlList.length - 1].setAttribute("gap", "24"); + const firstVariable = scalarVariables[0]; addSetVariableTo(xmlList, firstVariable); addChangeVariableBy(xmlList, firstVariable); @@ -60,15 +56,13 @@ export function getVariablesCategory(workspace) { // Now add list variables to the flyout addCreateButton(xmlList, workspace, "LIST"); - variableModelList = workspace.getVariablesOfType(LIST_VARIABLE_TYPE); - variableModelList.sort(Blockly.Variables.compareByName); - for (var i = 0; i < variableModelList.length; i++) { - addDataList(xmlList, variableModelList[i]); - } + const listVariables = workspace.getVariablesOfType(LIST_VARIABLE_TYPE); + listVariables.sort(Blockly.Variables.compareByName); + listVariables.forEach((variable) => addDataList(xmlList, variable)); - if (variableModelList.length > 0) { - xmlList[xmlList.length - 1].setAttribute("gap", 24); - var firstVariable = variableModelList[0]; + if (listVariables.length > 0) { + xmlList[xmlList.length - 1].setAttribute("gap", "24"); + const firstVariable = listVariables[0]; addAddToList(xmlList, firstVariable); addSep(xmlList); @@ -91,10 +85,14 @@ export function getVariablesCategory(workspace) { /** * Construct and add a data_variable block to xmlList. - * @param {!Array.} xmlList Array of XML block elements. - * @param {?Blockly.VariableModel} variable Variable to select in the field. + * + * @param xmlList Array of XML block elements. + * @param variable Variable to select in the field. */ -function addDataVariable(xmlList, variable) { +function addDataVariable( + xmlList: Element[], + variable: Blockly.IVariableModel +) { // // variablename // @@ -105,10 +103,14 @@ function addDataVariable(xmlList, variable) { /** * Construct and add a data_setvariableto block to xmlList. - * @param {!Array.} xmlList Array of XML block elements. - * @param {?Blockly.VariableModel} variable Variable to select in the field. + * + * @param xmlList Array of XML block elements. + * @param variable Variable to select in the field. */ -function addSetVariableTo(xmlList, variable) { +function addSetVariableTo( + xmlList: Element[], + variable: Blockly.IVariableModel +) { // // // @@ -122,16 +124,20 @@ function addSetVariableTo(xmlList, variable) { addBlock(xmlList, variable, "data_setvariableto", "VARIABLE", [ "VALUE", "text", - 0, + "0", ]); } /** * Construct and add a data_changevariableby block to xmlList. - * @param {!Array.} xmlList Array of XML block elements. - * @param {?Blockly.VariableModel} variable Variable to select in the field. + * + * @param xmlList Array of XML block elements. + * @param variable Variable to select in the field. */ -function addChangeVariableBy(xmlList, variable) { +function addChangeVariableBy( + xmlList: Element[], + variable: Blockly.IVariableModel +) { // // // @@ -145,16 +151,20 @@ function addChangeVariableBy(xmlList, variable) { addBlock(xmlList, variable, "data_changevariableby", "VARIABLE", [ "VALUE", "math_number", - 1, + "1", ]); } /** * Construct and add a data_showVariable block to xmlList. - * @param {!Array.} xmlList Array of XML block elements. - * @param {?Blockly.VariableModel} variable Variable to select in the field. + * + * @param xmlList Array of XML block elements. + * @param variable Variable to select in the field. */ -function addShowVariable(xmlList, variable) { +function addShowVariable( + xmlList: Element[], + variable: Blockly.IVariableModel +) { // // // @@ -165,10 +175,14 @@ function addShowVariable(xmlList, variable) { /** * Construct and add a data_hideVariable block to xmlList. - * @param {!Array.} xmlList Array of XML block elements. - * @param {?Blockly.VariableModel} variable Variable to select in the field. + * + * @param xmlList Array of XML block elements. + * @param variable Variable to select in the field. */ -function addHideVariable(xmlList, variable) { +function addHideVariable( + xmlList: Element[], + variable: Blockly.IVariableModel +) { // // // @@ -179,10 +193,14 @@ function addHideVariable(xmlList, variable) { /** * Construct and add a data_listcontents block to xmlList. - * @param {!Array.} xmlList Array of XML block elements. - * @param {?Blockly.VariableModel} variable Variable to select in the field. + * + * @param xmlList Array of XML block elements. + * @param variable Variable to select in the field. */ -function addDataList(xmlList, variable) { +function addDataList( + xmlList: Element[], + variable: Blockly.IVariableModel +) { // // variablename // @@ -193,10 +211,14 @@ function addDataList(xmlList, variable) { /** * Construct and add a data_addtolist block to xmlList. - * @param {!Array.} xmlList Array of XML block elements. - * @param {?Blockly.VariableModel} variable Variable to select in the field. + * + * @param xmlList Array of XML block elements. + * @param variable Variable to select in the field. */ -function addAddToList(xmlList, variable) { +function addAddToList( + xmlList: Element[], + variable: Blockly.IVariableModel +) { // // variablename // @@ -214,10 +236,14 @@ function addAddToList(xmlList, variable) { /** * Construct and add a data_deleteoflist block to xmlList. - * @param {!Array.} xmlList Array of XML block elements. - * @param {?Blockly.VariableModel} variable Variable to select in the field. + * + * @param xmlList Array of XML block elements. + * @param variable Variable to select in the field. */ -function addDeleteOfList(xmlList, variable) { +function addDeleteOfList( + xmlList: Element[], + variable: Blockly.IVariableModel +) { // // variablename // @@ -229,16 +255,20 @@ function addDeleteOfList(xmlList, variable) { addBlock(xmlList, variable, "data_deleteoflist", "LIST", [ "INDEX", "math_integer", - 1, + "1", ]); } /** * Construct and add a data_deleteoflist block to xmlList. - * @param {!Array.} xmlList Array of XML block elements. - * @param {?Blockly.VariableModel} variable Variable to select in the field. + * + * @param xmlList Array of XML block elements. + * @param variable Variable to select in the field. */ -function addDeleteAllOfList(xmlList, variable) { +function addDeleteAllOfList( + xmlList: Element[], + variable: Blockly.IVariableModel +) { // // variablename // @@ -247,10 +277,14 @@ function addDeleteAllOfList(xmlList, variable) { /** * Construct and add a data_insertatlist block to xmlList. - * @param {!Array.} xmlList Array of XML block elements. - * @param {?Blockly.VariableModel} variable Variable to select in the field. + * + * @param xmlList Array of XML block elements. + * @param variable Variable to select in the field. */ -function addInsertAtList(xmlList, variable) { +function addInsertAtList( + xmlList: Element[], + variable: Blockly.IVariableModel +) { // // variablename // @@ -269,17 +303,21 @@ function addInsertAtList(xmlList, variable) { variable, "data_insertatlist", "LIST", - ["INDEX", "math_integer", 1], + ["INDEX", "math_integer", "1"], ["ITEM", "text", Blockly.Msg.DEFAULT_LIST_ITEM] ); } /** * Construct and add a data_replaceitemoflist block to xmlList. - * @param {!Array.} xmlList Array of XML block elements. - * @param {?Blockly.VariableModel} variable Variable to select in the field. + * + * @param xmlList Array of XML block elements. + * @param variable Variable to select in the field. */ -function addReplaceItemOfList(xmlList, variable) { +function addReplaceItemOfList( + xmlList: Element[], + variable: Blockly.IVariableModel +) { // // variablename // @@ -298,17 +336,21 @@ function addReplaceItemOfList(xmlList, variable) { variable, "data_replaceitemoflist", "LIST", - ["INDEX", "math_integer", 1], + ["INDEX", "math_integer", "1"], ["ITEM", "text", Blockly.Msg.DEFAULT_LIST_ITEM] ); } /** * Construct and add a data_itemoflist block to xmlList. - * @param {!Array.} xmlList Array of XML block elements. - * @param {?Blockly.VariableModel} variable Variable to select in the field. + * + * @param xmlList Array of XML block elements. + * @param variable Variable to select in the field. */ -function addItemOfList(xmlList, variable) { +function addItemOfList( + xmlList: Element[], + variable: Blockly.IVariableModel +) { // // variablename // @@ -320,15 +362,19 @@ function addItemOfList(xmlList, variable) { addBlock(xmlList, variable, "data_itemoflist", "LIST", [ "INDEX", "math_integer", - 1, + "1", ]); } /** Construct and add a data_itemnumoflist block to xmlList. - * @param {!Array.} xmlList Array of XML block elements. - * @param {?Blockly.VariableModel} variable Variable to select in the field. + * + * @param xmlList Array of XML block elements. + * @param variable Variable to select in the field. */ -function addItemNumberOfList(xmlList, variable) { +function addItemNumberOfList( + xmlList: Element[], + variable: Blockly.IVariableModel +) { // // // @@ -346,10 +392,14 @@ function addItemNumberOfList(xmlList, variable) { /** * Construct and add a data_lengthoflist block to xmlList. - * @param {!Array.} xmlList Array of XML block elements. - * @param {?Blockly.VariableModel} variable Variable to select in the field. + * + * @param xmlList Array of XML block elements. + * @param variable Variable to select in the field. */ -function addLengthOfList(xmlList, variable) { +function addLengthOfList( + xmlList: Element[], + variable: Blockly.IVariableModel +) { // // variablename // @@ -358,10 +408,14 @@ function addLengthOfList(xmlList, variable) { /** * Construct and add a data_listcontainsitem block to xmlList. - * @param {!Array.} xmlList Array of XML block elements. - * @param {?Blockly.VariableModel} variable Variable to select in the field. + * + * @param xmlList Array of XML block elements. + * @param variable Variable to select in the field. */ -function addListContainsItem(xmlList, variable) { +function addListContainsItem( + xmlList: Element[], + variable: Blockly.IVariableModel +) { // // variablename // @@ -379,10 +433,14 @@ function addListContainsItem(xmlList, variable) { /** * Construct and add a data_showlist block to xmlList. - * @param {!Array.} xmlList Array of XML block elements. - * @param {?Blockly.VariableModel} variable Variable to select in the field. + * + * @param xmlList Array of XML block elements. + * @param variable Variable to select in the field. */ -function addShowList(xmlList, variable) { +function addShowList( + xmlList: Element[], + variable: Blockly.IVariableModel +) { // // variablename // @@ -391,10 +449,14 @@ function addShowList(xmlList, variable) { /** * Construct and add a data_hidelist block to xmlList. - * @param {!Array.} xmlList Array of XML block elements. - * @param {?Blockly.VariableModel} variable Variable to select in the field. + * + * @param xmlList Array of XML block elements. + * @param variable Variable to select in the field. */ -function addHideList(xmlList, variable) { +function addHideList( + xmlList: Element[], + variable: Blockly.IVariableModel +) { // // variablename // @@ -403,24 +465,29 @@ function addHideList(xmlList, variable) { /** * Construct a create variable button and push it to the xmlList. - * @param {!Array.} xmlList Array of XML block elements. - * @param {Blockly.Workspace} workspace Workspace to register callback to. - * @param {string} type Type of variable this is for. For example, 'LIST' or + * + * @param xmlList Array of XML block elements. + * @param workspace Workspace to register callback to. + * @param type Type of variable this is for. For example, 'LIST' or * 'VARIABLE'. */ -function addCreateButton(xmlList, workspace, type) { - var button = document.createElement("button"); +function addCreateButton( + xmlList: Element[], + workspace: Blockly.WorkspaceSvg, + type: string +) { + const button = document.createElement("button"); // Set default msg, callbackKey, and callback values for type 'VARIABLE' - var msg = Blockly.Msg.NEW_VARIABLE; - var callbackKey = "CREATE_VARIABLE"; - var callback = function (button) { + let msg = Blockly.Msg.NEW_VARIABLE; + let callbackKey = "CREATE_VARIABLE"; + let callback = function (button: Blockly.FlyoutButton) { createVariable(button.getTargetWorkspace(), null, SCALAR_VARIABLE_TYPE); }; if (type === "LIST") { msg = Blockly.Msg.NEW_LIST; callbackKey = "CREATE_LIST"; - callback = function (button) { + callback = function (button: Blockly.FlyoutButton) { createVariable(button.getTargetWorkspace(), null, LIST_VARIABLE_TYPE); }; } @@ -442,28 +509,28 @@ function addCreateButton(xmlList, workspace, type) { /** * Construct a variable block with the given variable, blockType, and optional * value tags. Add the variable block to the given xmlList. - * @param {!Array.} xmlList Array of XML block elements. - * @param {?Blockly.VariableModel} variable Variable to select in the field. - * @param {string} blockType Type of block. For example, 'data_hidelist' or - * data_showlist'. - * @param {string} fieldName Name of field in block. For example: 'VARIABLE' or - * 'LIST'. - * @param {?Array.} opt_value Optional array containing the value name - * and shadow type of value tags. - * @param {?Array.} opt_secondValue Optional array containing the value - * name and shadow type of a second pair of value tags. + * + * @param xmlList Array of XML block elements. + * @param variable Variable to select in the field. + * @param blockType Type of block. For example, 'data_hidelist' or + * 'data_showlist'. + * @param fieldName Name of field in block. For example: 'VARIABLE' or 'LIST'. + * @param opt_value Optional array containing the value name and shadow type of + * value tags. + * @param opt_secondValue Optional array containing the value name and shadow + * type of a second pair of value tags. */ function addBlock( - xmlList, - variable, - blockType, - fieldName, - opt_value, - opt_secondValue + xmlList: Element[], + variable: Blockly.IVariableModel, + blockType: string, + fieldName: string, + opt_value?: string[], + opt_secondValue?: string[] ) { if (Blockly.Blocks[blockType]) { - var firstValueField; - var secondValueField; + let firstValueField; + let secondValueField; if (opt_value) { firstValueField = createValue(opt_value[0], opt_value[1], opt_value[2]); } @@ -476,24 +543,30 @@ function addBlock( } var gap = 8; - var blockText = - "" + - '' + - generateVariableFieldXml(variable, fieldName) + - firstValueField + - secondValueField + - "" + - ""; - var block = Blockly.utils.xml.textToDom(blockText).firstChild; + var blockText = ` + + + ${generateVariableFieldXml(variable, fieldName)} + ${firstValueField} + ${secondValueField} + + `; + var block = Blockly.utils.xml.textToDom(blockText).firstElementChild; xmlList.push(block); } } -function generateVariableFieldXml(variableModel, opt_name) { +/** + * Creates XML representing a variable field. + * + * @param variableModel The variable to represent in the field. + * @param opt_name A custom name for the field, if desired. + * @returns XML representation of a variable field. + */ +function generateVariableFieldXml( + variableModel: Blockly.IVariableModel, + opt_name?: string +): string { const field = document.createElement("field"); field.setAttribute("name", opt_name || "VARIABLE"); field.setAttribute("id", variableModel.getId()); @@ -505,13 +578,14 @@ function generateVariableFieldXml(variableModel, opt_name) { /** * Create the text representation of a value dom element with a shadow of the * indicated type inside. - * @param {string} valueName Name of the value tags. - * @param {string} type The type of the shadow tags. - * @param {string|number} value The default shadow value. - * @return {string} The generated dom element in text. + * + * @param valueName Name of the value tags. + * @param type The type of the shadow tags. + * @param value The default shadow value. + * @returns The generated dom element in text. */ -function createValue(valueName, type, value) { - var fieldName; +function createValue(valueName: string, type: string, value: string): string { + let fieldName; switch (valueName) { case "ITEM": fieldName = "TEXT"; @@ -527,30 +601,22 @@ function createValue(valueName, type, value) { } break; } - var valueField = - '' + - '' + - '' + - value + - "" + - "" + - ""; + const valueField = ` + + + ${value} + + `; return valueField; } /** * Construct a block separator. Add the separator to the given xmlList. - * @param {!Array.} xmlList Array of XML block elements. + * + * @param xmlList Array of XML block elements. */ -function addSep(xmlList) { - var gap = 36; - var sepText = "" + '' + ""; - var sep = Blockly.utils.xml.textToDom(sepText).firstChild; +function addSep(xmlList: Element[]) { + const sepText = ``; + const sep = Blockly.utils.xml.textToDom(sepText).firstElementChild; xmlList.push(sep); } diff --git a/src/events/events_block_comment_base.js b/src/events/events_block_comment_base.ts similarity index 52% rename from src/events/events_block_comment_base.js rename to src/events/events_block_comment_base.ts index 248f978f89..7cbdf92158 100644 --- a/src/events/events_block_comment_base.js +++ b/src/events/events_block_comment_base.ts @@ -5,9 +5,15 @@ */ import * as Blockly from "blockly/core"; +import type { ScratchCommentBubble } from "../scratch_comment_bubble"; export class BlockCommentBase extends Blockly.Events.Abstract { - constructor(opt_blockComment) { + isBlank = true; + commentId: string; + blockId: string; + workspaceId: string; + + constructor(opt_blockComment?: ScratchCommentBubble) { super(); this.isBlank = !opt_blockComment; @@ -18,7 +24,7 @@ export class BlockCommentBase extends Blockly.Events.Abstract { this.workspaceId = opt_blockComment.getSourceBlock()?.workspace.id; } - toJson() { + toJson(): BlockCommentBaseJson { return { ...super.toJson(), commentId: this.commentId, @@ -26,10 +32,23 @@ export class BlockCommentBase extends Blockly.Events.Abstract { }; } - static fromJson(json, workspace, event) { - const newEvent = super.fromJson(json, workspace, event); + static fromJson( + json: BlockCommentBaseJson, + workspace: Blockly.Workspace, + event?: any + ): BlockCommentBase { + const newEvent = super.fromJson( + json, + workspace, + event ?? new BlockCommentBase() + ) as BlockCommentBase; newEvent.commentId = json["commentId"]; newEvent.blockId = json["blockId"]; return newEvent; } } + +export interface BlockCommentBaseJson extends Blockly.Events.AbstractEventJson { + commentId: string; + blockId: string; +} diff --git a/src/events/events_block_comment_change.js b/src/events/events_block_comment_change.ts similarity index 55% rename from src/events/events_block_comment_change.js rename to src/events/events_block_comment_change.ts index 46299d942c..d265415da0 100644 --- a/src/events/events_block_comment_change.js +++ b/src/events/events_block_comment_change.ts @@ -5,10 +5,21 @@ */ import * as Blockly from "blockly/core"; -import { BlockCommentBase } from "./events_block_comment_base.js"; +import { + BlockCommentBase, + BlockCommentBaseJson, +} from "./events_block_comment_base"; +import type { ScratchCommentBubble } from "../scratch_comment_bubble"; class BlockCommentChange extends BlockCommentBase { - constructor(opt_blockComment, oldContents, newContents) { + oldContents_: string; + newContents_: string; + + constructor( + opt_blockComment?: ScratchCommentBubble, + oldContents?: string, + newContents?: string + ) { super(opt_blockComment); this.type = "block_comment_change"; this.oldContents_ = oldContents; @@ -19,7 +30,7 @@ class BlockCommentChange extends BlockCommentBase { this.recordUndo = false; } - toJson() { + toJson(): BlockCommentChangeJson { return { ...super.toJson(), newContents: this.newContents_, @@ -27,8 +38,16 @@ class BlockCommentChange extends BlockCommentBase { }; } - static fromJson(json, workspace, event) { - const newEvent = super.fromJson(json, workspace, event); + static fromJson( + json: BlockCommentChangeJson, + workspace: Blockly.Workspace, + event?: any + ): BlockCommentChange { + const newEvent = super.fromJson( + json, + workspace, + event ?? new BlockCommentChange() + ) as BlockCommentChange; newEvent.newContents_ = json["newContents"]; newEvent.oldContents_ = json["oldContents"]; @@ -36,6 +55,11 @@ class BlockCommentChange extends BlockCommentBase { } } +interface BlockCommentChangeJson extends BlockCommentBaseJson { + newContents: string; + oldContents: string; +} + Blockly.registry.register( Blockly.registry.Type.EVENT, "block_comment_change", diff --git a/src/events/events_block_comment_collapse.js b/src/events/events_block_comment_collapse.ts similarity index 54% rename from src/events/events_block_comment_collapse.js rename to src/events/events_block_comment_collapse.ts index ad982d79f8..30aaa533ca 100644 --- a/src/events/events_block_comment_collapse.js +++ b/src/events/events_block_comment_collapse.ts @@ -5,30 +5,44 @@ */ import * as Blockly from "blockly/core"; -import { BlockCommentBase } from "./events_block_comment_base.js"; +import { + BlockCommentBase, + BlockCommentBaseJson, +} from "./events_block_comment_base"; +import type { ScratchCommentBubble } from "../scratch_comment_bubble"; class BlockCommentCollapse extends BlockCommentBase { - constructor(opt_blockComment, collapsed) { + newCollapsed: boolean; + + constructor(opt_blockComment?: ScratchCommentBubble, collapsed?: boolean) { super(opt_blockComment); this.type = "block_comment_collapse"; this.newCollapsed = collapsed; } - toJson() { + toJson(): BlockCommentCollapseJson { return { ...super.toJson(), collapsed: this.newCollapsed, }; } - static fromJson(json, workspace, event) { - const newEvent = super.fromJson(json, workspace, event); + static fromJson( + json: BlockCommentCollapseJson, + workspace: Blockly.Workspace, + event?: any + ): BlockCommentCollapse { + const newEvent = super.fromJson( + json, + workspace, + event ?? new BlockCommentCollapse() + ) as BlockCommentCollapse; newEvent.newCollapsed = json["collapsed"]; return newEvent; } - run(forward) { + run(forward: boolean) { const workspace = this.getEventWorkspace_(); const block = workspace.getBlockById(this.blockId); const comment = block.getIcon(Blockly.icons.IconType.COMMENT); @@ -36,6 +50,10 @@ class BlockCommentCollapse extends BlockCommentBase { } } +interface BlockCommentCollapseJson extends BlockCommentBaseJson { + collapsed: boolean; +} + Blockly.registry.register( Blockly.registry.Type.EVENT, "block_comment_collapse", diff --git a/src/events/events_block_comment_create.js b/src/events/events_block_comment_create.ts similarity index 51% rename from src/events/events_block_comment_create.js rename to src/events/events_block_comment_create.ts index 97db3cf7dc..2d8a1b7c42 100644 --- a/src/events/events_block_comment_create.js +++ b/src/events/events_block_comment_create.ts @@ -5,10 +5,21 @@ */ import * as Blockly from "blockly/core"; -import { BlockCommentBase } from "./events_block_comment_base.js"; +import { + BlockCommentBase, + BlockCommentBaseJson, +} from "./events_block_comment_base"; +import type { ScratchCommentBubble } from "../scratch_comment_bubble"; class BlockCommentCreate extends BlockCommentBase { - constructor(opt_blockComment) { + json: { + x: number; + y: number; + width: number; + height: number; + }; + + constructor(opt_blockComment?: ScratchCommentBubble) { super(opt_blockComment); this.type = "block_comment_create"; const size = opt_blockComment.getSize(); @@ -25,26 +36,41 @@ class BlockCommentCreate extends BlockCommentBase { this.recordUndo = false; } - toJson() { + toJson(): BlockCommentCreateJson { return { ...super.toJson(), - json: this.json, + ...this.json, }; } - static fromJson(json, workspace, event) { - const newEvent = super.fromJson(json, workspace, event); + static fromJson( + json: BlockCommentCreateJson, + workspace: Blockly.Workspace, + event?: any + ): BlockCommentCreate { + const newEvent = super.fromJson( + json, + workspace, + event ?? new BlockCommentCreate() + ) as BlockCommentCreate; newEvent.json = { - x: json["json"]["x"], - y: json["json"]["y"], - width: json["json"]["width"], - height: json["json"]["height"], + x: json["x"], + y: json["y"], + width: json["width"], + height: json["height"], }; return newEvent; } } +interface BlockCommentCreateJson extends BlockCommentBaseJson { + x: number; + y: number; + width: number; + height: number; +} + Blockly.registry.register( Blockly.registry.Type.EVENT, "block_comment_create", diff --git a/src/events/events_block_comment_delete.js b/src/events/events_block_comment_delete.ts similarity index 73% rename from src/events/events_block_comment_delete.js rename to src/events/events_block_comment_delete.ts index d9a6e60ff9..4e118b3e1e 100644 --- a/src/events/events_block_comment_delete.js +++ b/src/events/events_block_comment_delete.ts @@ -5,10 +5,14 @@ */ import * as Blockly from "blockly/core"; -import { BlockCommentBase } from "./events_block_comment_base.js"; +import { BlockCommentBase } from "./events_block_comment_base"; +import type { ScratchCommentBubble } from "../scratch_comment_bubble"; class BlockCommentDelete extends BlockCommentBase { - constructor(opt_blockComment, sourceBlock) { + constructor( + opt_blockComment?: ScratchCommentBubble, + sourceBlock?: Blockly.Block + ) { super(opt_blockComment); this.type = "block_comment_delete"; this.blockId = sourceBlock.id; diff --git a/src/events/events_block_comment_move.js b/src/events/events_block_comment_move.ts similarity index 56% rename from src/events/events_block_comment_move.js rename to src/events/events_block_comment_move.ts index ffc098fd90..7bb9d925e9 100644 --- a/src/events/events_block_comment_move.js +++ b/src/events/events_block_comment_move.ts @@ -5,17 +5,28 @@ */ import * as Blockly from "blockly/core"; -import { BlockCommentBase } from "./events_block_comment_base.js"; +import { + BlockCommentBase, + BlockCommentBaseJson, +} from "./events_block_comment_base"; +import type { ScratchCommentBubble } from "../scratch_comment_bubble"; class BlockCommentMove extends BlockCommentBase { - constructor(opt_blockComment, oldCoordinate, newCoordinate) { + oldCoordinate_: Blockly.utils.Coordinate; + newCoordinate_: Blockly.utils.Coordinate; + + constructor( + opt_blockComment?: ScratchCommentBubble, + oldCoordinate?: Blockly.utils.Coordinate, + newCoordinate?: Blockly.utils.Coordinate + ) { super(opt_blockComment); this.type = "block_comment_move"; this.oldCoordinate_ = oldCoordinate; this.newCoordinate_ = newCoordinate; } - toJson() { + toJson(): BlockCommentMoveJson { return { ...super.toJson(), newCoordinate: this.newCoordinate_, @@ -23,8 +34,16 @@ class BlockCommentMove extends BlockCommentBase { }; } - static fromJson(json, workspace, event) { - const newEvent = super.fromJson(json, workspace, event); + static fromJson( + json: BlockCommentMoveJson, + workspace: Blockly.Workspace, + event?: any + ): BlockCommentMove { + const newEvent = super.fromJson( + json, + workspace, + event ?? new BlockCommentMove() + ) as BlockCommentMove; newEvent.newCoordinate_ = new Blockly.utils.Coordinate( json["newCoordinate"]["x"], json["newCoordinate"]["y"] @@ -37,7 +56,7 @@ class BlockCommentMove extends BlockCommentBase { return newEvent; } - run(forward) { + run(forward: boolean) { const workspace = this.getEventWorkspace_(); const block = workspace?.getBlockById(this.blockId); const comment = block?.getIcon(Blockly.icons.IconType.COMMENT); @@ -47,6 +66,17 @@ class BlockCommentMove extends BlockCommentBase { } } +interface BlockCommentMoveJson extends BlockCommentBaseJson { + newCoordinate: { + x: number; + y: number; + }; + oldCoordinate: { + x: number; + y: number; + }; +} + Blockly.registry.register( Blockly.registry.Type.EVENT, "block_comment_move", diff --git a/src/events/events_block_comment_resize.js b/src/events/events_block_comment_resize.js deleted file mode 100644 index 6c7b5953a7..0000000000 --- a/src/events/events_block_comment_resize.js +++ /dev/null @@ -1,52 +0,0 @@ -/** - * @license - * Copyright 2024 Google LLC - * SPDX-License-Identifier: Apache-2.0 - */ - -import * as Blockly from "blockly/core"; -import { BlockCommentBase } from "./events_block_comment_base.js"; - -class BlockCommentResize extends BlockCommentBase { - constructor(opt_blockComment, oldSize, newSize) { - super(opt_blockComment); - this.type = "block_comment_resize"; - this.oldSize = oldSize; - this.newSize = newSize; - } - - toJson() { - return { - ...super.toJson(), - newSize: this.newSize, - oldSize: this.oldSize, - }; - } - - static fromJson(json, workspace, event) { - const newEvent = super.fromJson(json, workspace, event); - newEvent.newSize = new Blockly.utils.Size( - json["newSize"]["width"], - json["newSize"]["height"] - ); - newEvent.oldSize = new Blockly.utils.Size( - json["oldSize"]["width"], - json["oldSize"]["height"] - ); - - return newEvent; - } - - run(forward) { - const workspace = this.getEventWorkspace_(); - const block = workspace?.getBlockById(this.blockId); - const comment = block?.getIcon(Blockly.icons.IconType.COMMENT); - comment?.setBubbleSize(forward ? this.newSize : this.oldSize); - } -} - -Blockly.registry.register( - Blockly.registry.Type.EVENT, - "block_comment_resize", - BlockCommentResize -); diff --git a/src/events/events_block_comment_resize.ts b/src/events/events_block_comment_resize.ts new file mode 100644 index 0000000000..9dfd159231 --- /dev/null +++ b/src/events/events_block_comment_resize.ts @@ -0,0 +1,88 @@ +/** + * @license + * Copyright 2024 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + +import * as Blockly from "blockly/core"; +import { + BlockCommentBase, + BlockCommentBaseJson, +} from "./events_block_comment_base"; +import type { ScratchCommentBubble } from "../scratch_comment_bubble"; + +class BlockCommentResize extends BlockCommentBase { + oldSize: Blockly.utils.Size; + newSize: Blockly.utils.Size; + + constructor( + opt_blockComment?: ScratchCommentBubble, + oldSize?: Blockly.utils.Size, + newSize?: Blockly.utils.Size + ) { + super(opt_blockComment); + this.type = "block_comment_resize"; + this.oldSize = oldSize; + this.newSize = newSize; + } + + toJson(): BlockCommentResizeJson { + return { + ...super.toJson(), + newSize: { + width: this.newSize.width, + height: this.newSize.height, + }, + oldSize: { + width: this.oldSize.width, + height: this.oldSize.height, + }, + }; + } + + static fromJson( + json: BlockCommentResizeJson, + workspace: Blockly.Workspace, + event?: any + ): BlockCommentResize { + const newEvent = super.fromJson( + json, + workspace, + event ?? new BlockCommentResize() + ) as BlockCommentResize; + newEvent.newSize = new Blockly.utils.Size( + json["newSize"]["width"], + json["newSize"]["height"] + ); + newEvent.oldSize = new Blockly.utils.Size( + json["oldSize"]["width"], + json["oldSize"]["height"] + ); + + return newEvent; + } + + run(forward: boolean) { + const workspace = this.getEventWorkspace_(); + const block = workspace?.getBlockById(this.blockId); + const comment = block?.getIcon(Blockly.icons.IconType.COMMENT); + comment?.setBubbleSize(forward ? this.newSize : this.oldSize); + } +} + +interface BlockCommentResizeJson extends BlockCommentBaseJson { + newSize: { + width: number; + height: number; + }; + oldSize: { + width: number; + height: number; + }; +} + +Blockly.registry.register( + Blockly.registry.Type.EVENT, + "block_comment_resize", + BlockCommentResize +); diff --git a/src/events/events_block_drag_end.js b/src/events/events_block_drag_end.js deleted file mode 100644 index 25def88961..0000000000 --- a/src/events/events_block_drag_end.js +++ /dev/null @@ -1,33 +0,0 @@ -/** - * @license - * Copyright 2024 Google LLC - * SPDX-License-Identifier: Apache-2.0 - */ - -import * as Blockly from "blockly/core"; - -export class BlockDragEnd extends Blockly.Events.BlockBase { - constructor(block, isOutside) { - super(block); - this.type = "endDrag"; - this.isOutside = isOutside; - this.recordUndo = false; - this.xml = Blockly.Xml.blockToDom(block, true); - } - - toJson() { - return { - ...super.toJson(), - isOutside: this.isOutside, - xml: this.xml, - }; - } - - static fromJson(json, workspace, event) { - const newEvent = super.fromJson(json, workspace, event); - newEvent.isOutside = json["isOutside"]; - newEvent.xml = json["xml"]; - - return newEvent; - } -} diff --git a/src/events/events_block_drag_end.ts b/src/events/events_block_drag_end.ts new file mode 100644 index 0000000000..34e2c410aa --- /dev/null +++ b/src/events/events_block_drag_end.ts @@ -0,0 +1,49 @@ +/** + * @license + * Copyright 2024 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + +import * as Blockly from "blockly/core"; + +export class BlockDragEnd extends Blockly.Events.BlockBase { + isOutside: boolean; + xml: Element | DocumentFragment; + + constructor(block?: Blockly.Block, isOutside?: boolean) { + super(block); + this.type = "endDrag"; + this.isOutside = isOutside; + this.recordUndo = false; + this.xml = Blockly.Xml.blockToDom(block, true); + } + + toJson(): BlockDragEndJson { + return { + ...super.toJson(), + isOutside: this.isOutside, + xml: Blockly.utils.xml.domToText(this.xml), + }; + } + + static fromJson( + json: BlockDragEndJson, + workspace: Blockly.Workspace, + event?: any + ): BlockDragEnd { + const newEvent = super.fromJson( + json, + workspace, + event ?? new BlockDragEnd() + ) as BlockDragEnd; + newEvent.isOutside = json["isOutside"]; + newEvent.xml = Blockly.utils.xml.textToDom(json["xml"]); + + return newEvent; + } +} + +interface BlockDragEndJson extends Blockly.Events.BlockBaseJson { + isOutside: boolean; + xml: string; +} diff --git a/src/events/events_block_drag_outside.js b/src/events/events_block_drag_outside.js deleted file mode 100644 index 1acdfe5b35..0000000000 --- a/src/events/events_block_drag_outside.js +++ /dev/null @@ -1,30 +0,0 @@ -/** - * @license - * Copyright 2024 Google LLC - * SPDX-License-Identifier: Apache-2.0 - */ - -import * as Blockly from "blockly/core"; - -export class BlockDragOutside extends Blockly.Events.BlockBase { - constructor(block, isOutside) { - super(block); - this.type = "dragOutside"; - this.isOutside = isOutside; - this.recordUndo = false; - } - - toJson() { - return { - ...super.toJson(), - isOutside: this.isOutside, - }; - } - - static fromJson(json, workspace, event) { - const newEvent = super.fromJson(json, workspace, event); - newEvent.isOutside = json["isOutside"]; - - return newEvent; - } -} diff --git a/src/events/events_block_drag_outside.ts b/src/events/events_block_drag_outside.ts new file mode 100644 index 0000000000..7f64722d72 --- /dev/null +++ b/src/events/events_block_drag_outside.ts @@ -0,0 +1,44 @@ +/** + * @license + * Copyright 2024 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + +import * as Blockly from "blockly/core"; + +export class BlockDragOutside extends Blockly.Events.BlockBase { + isOutside: boolean; + + constructor(block?: Blockly.Block, isOutside?: boolean) { + super(block); + this.type = "dragOutside"; + this.isOutside = isOutside; + this.recordUndo = false; + } + + toJson(): BlockDragOutsideJson { + return { + ...super.toJson(), + isOutside: this.isOutside, + }; + } + + static fromJson( + json: BlockDragOutsideJson, + workspace: Blockly.Workspace, + event?: any + ): BlockDragOutside { + const newEvent = super.fromJson( + json, + workspace, + event ?? new BlockDragOutside() + ) as BlockDragOutside; + newEvent.isOutside = json["isOutside"]; + + return newEvent; + } +} + +interface BlockDragOutsideJson extends Blockly.Events.BlockBaseJson { + isOutside: boolean; +} diff --git a/src/events/events_scratch_variable_create.js b/src/events/events_scratch_variable_create.ts similarity index 59% rename from src/events/events_scratch_variable_create.js rename to src/events/events_scratch_variable_create.ts index d5ab39d6e7..1f67e79359 100644 --- a/src/events/events_scratch_variable_create.js +++ b/src/events/events_scratch_variable_create.ts @@ -5,9 +5,13 @@ */ import * as Blockly from "blockly/core"; +import { ScratchVariableModel } from "../scratch_variable_model"; class ScratchVariableCreate extends Blockly.Events.VarCreate { - constructor(variable) { + isLocal: boolean; + isCloud: boolean; + + constructor(variable?: ScratchVariableModel) { super(variable); if (!variable) return; @@ -15,30 +19,34 @@ class ScratchVariableCreate extends Blockly.Events.VarCreate { this.isCloud = variable.isCloud; } - toJson() { - const json = super.toJson(); - json["isLocal"] = this.isLocal; - json["isCloud"] = this.isCloud; - return json; + toJson(): ScratchVariableCreateJson { + return { + ...super.toJson(), + isLocal: this.isLocal, + isCloud: this.isCloud, + }; } - static fromJson(json, workspace, event) { - const newEvent = super.fromJson(json, workspace, event); + static fromJson( + json: ScratchVariableCreateJson, + workspace: Blockly.Workspace, + event?: any + ): ScratchVariableCreate { + const newEvent = super.fromJson( + json, + workspace, + event ?? new ScratchVariableCreate() + ) as ScratchVariableCreate; newEvent.isLocal = json["isLocal"]; newEvent.isCloud = json["isCloud"]; return newEvent; } - run(forward) { + run(forward: boolean) { const workspace = this.getEventWorkspace_(); const variableMap = workspace.getVariableMap(); if (forward) { - const VariableModel = Blockly.registry.getObject( - Blockly.registry.Type.VARIABLE_MODEL, - Blockly.registry.DEFAULT, - true - ); - const variable = new VariableModel( + const variable = new ScratchVariableModel( workspace, this.varName, this.varType, @@ -59,6 +67,11 @@ class ScratchVariableCreate extends Blockly.Events.VarCreate { } } +interface ScratchVariableCreateJson extends Blockly.Events.VarCreateJson { + isCloud: boolean; + isLocal: boolean; +} + Blockly.registry.register( Blockly.registry.Type.EVENT, Blockly.Events.VAR_CREATE, diff --git a/src/fields/field_colour_slider.js b/src/fields/field_colour_slider.ts similarity index 62% rename from src/fields/field_colour_slider.js rename to src/fields/field_colour_slider.ts index 89c292b222..4b4966e5ec 100644 --- a/src/fields/field_colour_slider.js +++ b/src/fields/field_colour_slider.ts @@ -23,52 +23,60 @@ * @author fraser@google.com (Neil Fraser) */ import * as Blockly from "blockly/core"; -import { FieldColour } from "@blockly/field-colour"; +import { FieldColour, FieldColourFromJsonConfig } from "@blockly/field-colour"; + +enum ColourChannel { + HUE = "hue", + SATURATION = "saturation", + BRIGHTNESS = "brightness", +} /** * Class for a slider-based colour input field. - * @param {string} colour The initial colour in '#rrggbb' format. - * @param {Function=} opt_validator A function that is executed when a new - * colour is selected. Its sole argument is the new colour value. Its - * return value becomes the selected colour, unless it is undefined, in - * which case the new colour stands, or it is null, in which case the change - * is aborted. - * @extends {Blockly.Field} - * @constructor */ export class FieldColourSlider extends FieldColour { /** * Function to be called if eyedropper can be activated. * If defined, an eyedropper button will be added to the color picker. * The button calls this function with a callback to update the field value. - * BEWARE: This is not a stable API, so it is being marked as private. It may change. - * @private + * BEWARE: This is not a stable API. It may change. */ - static activateEyedropper_ = null; + static activateEyedropper_: ( + callback: (colour: string) => void + ) => void | null = null; - constructor(colour, opt_validator) { - super(colour, opt_validator); + /** + * Path to the eyedropper svg icon. + */ + EYEDROPPER_PATH = "eyedropper.svg"; + SERIALIZABLE = true; + EDITABLE = true; - /** - * Path to the eyedropper svg icon. - */ - this.EYEDROPPER_PATH = "eyedropper.svg"; - this.SERIALIZABLE = true; - this.EDITABLE = true; - } + private hueChangeEventKey_?: Blockly.browserEvents.Data; + private saturationChangeEventKey_?: Blockly.browserEvents.Data; + private brightnessChangeEventKey_?: Blockly.browserEvents.Data; + private hueSlider_?: HTMLInputElement; + private saturationSlider_?: HTMLInputElement; + private brightnessSlider_?: HTMLInputElement; + private hueReadout_?: Element; + private saturationReadout_?: Element; + private brightnessReadout_?: Element; + private hue_?: number; + private saturation_?: number; + private brightness_?: number; + private eyedropperEventData_?: Blockly.browserEvents.Data; /** * Construct a FieldColourSlider from a JSON arg object. - * @param {!Object} options A JSON object with options (colour). - * @returns {!Blockly.FieldColourSlider} The new field instance. - * @package - * @nocollapse + * + * @param options A JSON object with options (colour). + * @returns The new field instance. */ - static fromJson(options) { + static fromJson(options: FieldColourFromJsonConfig): FieldColourSlider { return new FieldColourSlider(options["colour"]); } - doValueUpdate_(newValue) { + doValueUpdate_(newValue: string) { super.doValueUpdate_(newValue); this.updateSliderHandles_(); this.updateDom_(); @@ -76,25 +84,25 @@ export class FieldColourSlider extends FieldColour { /** * Create the hue, saturation or value CSS gradient for the slide backgrounds. - * @param {string} channel – Either "hue", "saturation" or "value". - * @return {string} Array colour hex colour stops for the given channel - * @private + * + * @param channel – Either "hue", "saturation" or "value". + * @return Array colour hex colour stops for the given channel */ - createColourStops_(channel) { - var stops = []; - for (var n = 0; n <= 360; n += 20) { + private createColourStops_(channel: ColourChannel): string[] { + const stops = []; + for (let n = 0; n <= 360; n += 20) { switch (channel) { - case "hue": + case ColourChannel.HUE: stops.push( Blockly.utils.colour.hsvToHex(n, this.saturation_, this.brightness_) ); break; - case "saturation": + case ColourChannel.SATURATION: stops.push( Blockly.utils.colour.hsvToHex(this.hue_, n / 360, this.brightness_) ); break; - case "brightness": + case ColourChannel.BRIGHTNESS: stops.push( Blockly.utils.colour.hsvToHex( this.hue_, @@ -112,25 +120,24 @@ export class FieldColourSlider extends FieldColour { /** * Set the gradient CSS properties for the given node and channel - * @param {Node} node - The DOM node the gradient will be set on. - * @param {string} channel – Either "hue", "saturation" or "value". - * @private + * + * @param node The DOM node the gradient will be set on. + * @param channel Either "hue", "saturation" or "value". */ - setGradient_(node, channel) { - var gradient = this.createColourStops_(channel).join(","); + private setGradient_(node: HTMLElement, channel: ColourChannel) { + const gradient = this.createColourStops_(channel).join(","); node.style["background"] = `linear-gradient(to right, ${gradient})`; } /** * Update the readouts and slider backgrounds after value has changed. - * @private */ - updateDom_() { + private updateDom_() { if (this.hueSlider_) { // Update the slider backgrounds - this.setGradient_(this.hueSlider_, "hue"); - this.setGradient_(this.saturationSlider_, "saturation"); - this.setGradient_(this.brightnessSlider_, "brightness"); + this.setGradient_(this.hueSlider_, ColourChannel.HUE); + this.setGradient_(this.saturationSlider_, ColourChannel.SATURATION); + this.setGradient_(this.brightnessSlider_, ColourChannel.BRIGHTNESS); // Update the readouts this.hueReadout_.textContent = Math.floor( @@ -147,28 +154,27 @@ export class FieldColourSlider extends FieldColour { /** * Update the slider handle positions from the current field value. - * @private */ - updateSliderHandles_() { + private updateSliderHandles_() { if (this.hueSlider_) { - this.hueSlider_.value = this.hue_; - this.saturationSlider_.value = this.saturation_; - this.brightnessSlider_.value = this.brightness_; + this.hueSlider_.value = `${this.hue_}`; + this.saturationSlider_.value = `${this.saturation_}`; + this.brightnessSlider_.value = `${this.brightness_}`; } } /** - * Create label and readout DOM elements, returning the readout - * @param {string} labelText - Text for the label - * @return {Array} The container node and the readout node. - * @private + * Create label and readout DOM elements, returning the readout. + * + * @param labelText Text for the label + * @return The container node and the readout node. */ - createLabelDom_(labelText) { - var labelContainer = document.createElement("div"); + private createLabelDom_(labelText: string): Element[] { + const labelContainer = document.createElement("div"); labelContainer.setAttribute("class", "scratchColourPickerLabel"); - var readout = document.createElement("span"); + const readout = document.createElement("span"); readout.setAttribute("class", "scratchColourPickerReadout"); - var label = document.createElement("span"); + const label = document.createElement("span"); label.setAttribute("class", "scratchColourPickerLabelText"); label.textContent = labelText; labelContainer.appendChild(label); @@ -178,71 +184,69 @@ export class FieldColourSlider extends FieldColour { /** * Factory for creating the different slider callbacks - * @param {string} channel - One of "hue", "saturation" or "brightness" - * @return {function} the callback for slider update - * @private + * + * @param channel One of "hue", "saturation" or "brightness" + * @returns The callback for slider update */ - sliderCallbackFactory_(channel) { - var thisField = this; - return function (event) { - var channelValue = event.target.value; + private sliderCallbackFactory_( + channel: ColourChannel + ): (event: PointerEvent) => void { + return (event: PointerEvent) => { + const channelValue = (event.target as HTMLInputElement).value; switch (channel) { - case "hue": - thisField.hue_ = channelValue; + case ColourChannel.HUE: + this.hue_ = Number(channelValue); break; - case "saturation": - thisField.saturation_ = channelValue; + case ColourChannel.SATURATION: + this.saturation_ = Number(channelValue); break; - case "brightness": - thisField.brightness_ = channelValue; + case ColourChannel.BRIGHTNESS: + this.brightness_ = Number(channelValue); break; } - var colour = Blockly.utils.colour.hsvToHex( - thisField.hue_, - thisField.saturation_, - thisField.brightness_ + const colour = Blockly.utils.colour.hsvToHex( + this.hue_, + this.saturation_, + this.brightness_ ); if (colour !== null) { - thisField.setValue(colour, true); + this.setValue(colour, true); } }; } /** * Activate the eyedropper, passing in a callback for setting the field value. - * @private */ - activateEyedropperInternal_() { - var thisField = this; - FieldColourSlider.activateEyedropper_(function (chosenColour) { + private activateEyedropperInternal_() { + FieldColourSlider.activateEyedropper_((chosenColour: string) => { // Update the internal hue/saturation/brightness values so sliders update. const components = Blockly.utils.colour.hexToRgb(chosenColour); - const { hue, saturation, value } = thisField.rgbToHsv( + const { hue, saturation, value } = this.rgbToHsv( components[0], components[1], components[2] ); - thisField.hue_ = hue; - thisField.saturation_ = saturation; - thisField.brightness_ = value; - thisField.setValue(chosenColour); + this.hue_ = hue; + this.saturation_ = saturation; + this.brightness_ = value; + this.setValue(chosenColour); }); } /** * Create hue, saturation and brightness sliders under the colour field. - * @private */ showEditor_() { Blockly.DropDownDiv.hideWithoutAnimation(); Blockly.DropDownDiv.clearContent(); - var div = Blockly.DropDownDiv.getContentDiv(); + const div = Blockly.DropDownDiv.getContentDiv(); div.className = "scratchColourPicker"; // Init color component values that are used while the editor is open // in order to keep the slider values stable. const components = Blockly.utils.colour.hexToRgb(this.getValue()); - var { hue, saturation, value } = this.rgbToHsv( + const { hue, saturation, value } = this.rgbToHsv( components[0], components[1], components[2] @@ -251,45 +255,45 @@ export class FieldColourSlider extends FieldColour { this.saturation_ = saturation; this.brightness_ = value; - var hueElements = this.createLabelDom_(Blockly.Msg.COLOUR_HUE_LABEL); + const hueElements = this.createLabelDom_(Blockly.Msg.COLOUR_HUE_LABEL); div.appendChild(hueElements[0]); this.hueReadout_ = hueElements[1]; this.hueSlider_ = document.createElement("input"); this.hueSlider_.type = "range"; - this.hueSlider_.min = 0; - this.hueSlider_.max = 360; + this.hueSlider_.min = "0"; + this.hueSlider_.max = "360"; this.hueSlider_.className = "scratchColourSlider"; div.appendChild(this.hueSlider_); - var saturationElements = this.createLabelDom_( + const saturationElements = this.createLabelDom_( Blockly.Msg.COLOUR_SATURATION_LABEL ); div.appendChild(saturationElements[0]); this.saturationReadout_ = saturationElements[1]; this.saturationSlider_ = document.createElement("input"); this.saturationSlider_.type = "range"; - this.saturationSlider_.step = 0.001; - this.saturationSlider_.min = 0; - this.saturationSlider_.max = 1.0; + this.saturationSlider_.step = "0.001"; + this.saturationSlider_.min = "0"; + this.saturationSlider_.max = "1.0"; this.saturationSlider_.className = "scratchColourSlider"; div.appendChild(this.saturationSlider_); - var brightnessElements = this.createLabelDom_( + const brightnessElements = this.createLabelDom_( Blockly.Msg.COLOUR_BRIGHTNESS_LABEL ); div.appendChild(brightnessElements[0]); this.brightnessReadout_ = brightnessElements[1]; this.brightnessSlider_ = document.createElement("input"); this.brightnessSlider_.type = "range"; - this.brightnessSlider_.min = 0; - this.brightnessSlider_.max = 255; + this.brightnessSlider_.min = "0"; + this.brightnessSlider_.max = "255"; this.brightnessSlider_.className = "scratchColourSlider"; div.appendChild(this.brightnessSlider_); if (FieldColourSlider.activateEyedropper_) { - var button = document.createElement("button"); + const button = document.createElement("button"); button.setAttribute("class", "scratchEyedropper"); - var image = document.createElement("img"); + const image = document.createElement("img"); image.src = Blockly.getMainWorkspace().options.pathToMedia + this.EYEDROPPER_PATH; button.appendChild(image); @@ -303,7 +307,10 @@ export class FieldColourSlider extends FieldColour { } Blockly.DropDownDiv.setColour("#ffffff", "#dddddd"); - Blockly.DropDownDiv.showPositionedByBlock(this, this.sourceBlock_); + Blockly.DropDownDiv.showPositionedByBlock( + this, + this.getSourceBlock() as Blockly.BlockSvg + ); // Set value updates the slider positions // Do this before attaching callbacks to avoid extra events from initial set @@ -313,19 +320,19 @@ export class FieldColourSlider extends FieldColour { this.hueSlider_, "input", this, - this.sliderCallbackFactory_("hue") + this.sliderCallbackFactory_(ColourChannel.HUE) ); this.saturationChangeEventKey_ = Blockly.browserEvents.bind( this.saturationSlider_, "input", this, - this.sliderCallbackFactory_("saturation") + this.sliderCallbackFactory_(ColourChannel.SATURATION) ); this.brightnessChangeEventKey_ = Blockly.browserEvents.bind( this.brightnessSlider_, "input", this, - this.sliderCallbackFactory_("brightness") + this.sliderCallbackFactory_(ColourChannel.BRIGHTNESS) ); } @@ -347,7 +354,11 @@ export class FieldColourSlider extends FieldColour { } // From Closure - rgbToHsv(red, green, blue) { + rgbToHsv( + red: number, + green: number, + blue: number + ): { hue: number; saturation: number; value: number } { const max = Math.max(Math.max(red, green), blue); const min = Math.min(Math.min(red, green), blue); let hue; diff --git a/src/fields/field_matrix.js b/src/fields/field_matrix.ts similarity index 59% rename from src/fields/field_matrix.js rename to src/fields/field_matrix.ts index 1a242585d7..1ac385328c 100644 --- a/src/fields/field_matrix.js +++ b/src/fields/field_matrix.ts @@ -25,181 +25,152 @@ */ import * as Blockly from "blockly/core"; +enum PaintStyle { + FILL = "fill", + CLEAR = "clear", +} + +enum LEDState { + ON = "1", + OFF = "0", +} + /** * Class for a matrix field. - * @param {number} matrix The default matrix value represented by a 25-bit integer. - * @extends {Blockly.Field} - * @constructor */ -class FieldMatrix extends Blockly.Field { - originalStyle; - - constructor(matrix) { - super(matrix); - /** - * Array of SVGElement for matrix thumbnail image on block field. - * @type {!Array} - * @private - */ - this.ledThumbNodes_ = []; - /** - * Array of SVGElement for matrix editor in dropdown menu. - * @type {!Array} - * @private - */ - this.ledButtons_ = []; - /** - * SVGElement for LED matrix in editor. - * @type {?SVGElement} - * @private - */ - this.matrixStage_ = null; - /** - * SVG image for dropdown arrow. - * @type {?SVGElement} - * @private - */ - this.arrow_ = null; - /** - * String indicating matrix paint style. - * value can be [null, 'fill', 'clear']. - * @type {?String} - * @private - */ - this.paintStyle_ = null; - /** - * Touch event wrapper. - * Runs when the field is selected. - * @type {!Array} - * @private - */ - this.mouseDownWrapper_ = null; - /** - * Touch event wrapper. - * Runs when the clear button editor button is selected. - * @type {!Array} - * @private - */ - this.clearButtonWrapper_ = null; - /** - * Touch event wrapper. - * Runs when the fill button editor button is selected. - * @type {!Array} - * @private - */ - this.fillButtonWrapper_ = null; - /** - * Touch event wrapper. - * Runs when the matrix editor is touched. - * @type {!Array} - * @private - */ - this.matrixTouchWrapper_ = null; - /** - * Touch event wrapper. - * Runs when the matrix editor touch event moves. - * @type {!Array} - * @private - */ - this.matrixMoveWrapper_ = null; - /** - * Touch event wrapper. - * Runs when the matrix editor is released. - * @type {!Array} - * @private - */ - this.matrixReleaseWrapper_ = null; +class FieldMatrix extends Blockly.Field { + private originalStyle?: string; - this.SERIALIZABLE = true; - } + /** + * Array of SVGElement for matrix thumbnail image on block field. + */ + private ledThumbNodes_: SVGElement[] = []; + /** + * Array of SVGElement for matrix editor in dropdown menu. + */ + private ledButtons_: SVGElement[] = []; + + /** + * SVGElement for LED matrix in editor. + */ + private matrixStage_: SVGElement | null = null; + + /** + * SVG image for dropdown arrow. + */ + private arrow_: SVGElement | null = null; + + /** + * String indicating matrix paint style. + * value can be [null, 'fill', 'clear']. + */ + private paintStyle_: PaintStyle | null = null; + + /** + * Touch event wrapper. + * Runs when the field is selected. + */ + private mouseDownWrapper: Blockly.browserEvents.Data | null = null; + + /** + * Touch event wrapper. + * Runs when the clear button editor button is selected. + */ + private clearButtonWrapper_: Blockly.browserEvents.Data | null = null; + + /** + * Touch event wrapper. + * Runs when the fill button editor button is selected. + */ + private fillButtonWrapper_: Blockly.browserEvents.Data | null = null; + + /** + * Touch event wrapper. + * Runs when the matrix editor is touched. + */ + private matrixTouchWrapper_: Blockly.browserEvents.Data | null = null; + + /** + * Touch event wrapper. + * Runs when the matrix editor touch event moves. + */ + private matrixMoveWrapper_: Blockly.browserEvents.Data | null = null; + + /** + * Touch event wrapper. + * Runs when the matrix editor is released. + */ + private matrixReleaseWrapper_: Blockly.browserEvents.Data | null = null; + + SERIALIZABLE = true; /** * Construct a FieldMatrix from a JSON arg object. - * @param {!Object} options A JSON object with options (matrix). - * @returns {!Blockly.FieldMatrix} The new field instance. - * @package - * @nocollapse + * @param options A JSON object with options (matrix). + * @returns The new field instance. */ - static fromJson(options) { + static fromJson(options: FieldMatrixConfig): FieldMatrix { return new FieldMatrix(options["matrix"]); } /** * Fixed size of the matrix thumbnail in the input field, in px. - * @type {number} - * @const */ - static THUMBNAIL_SIZE = 26; + static readonly THUMBNAIL_SIZE = 26; /** * Fixed size of each matrix thumbnail node, in px. - * @type {number} - * @const */ - static THUMBNAIL_NODE_SIZE = 4; + static readonly THUMBNAIL_NODE_SIZE = 4; /** * Fixed size of each matrix thumbnail node, in px. - * @type {number} - * @const */ - static THUMBNAIL_NODE_PAD = 1; + static readonly THUMBNAIL_NODE_PAD = 1; /** * Fixed size of arrow icon in drop down menu, in px. - * @type {number} - * @const */ - static ARROW_SIZE = 12; + static readonly ARROW_SIZE = 12; /** * Fixed size of each button inside the 5x5 matrix, in px. - * @type {number} - * @const */ - static MATRIX_NODE_SIZE = 18; + static readonly MATRIX_NODE_SIZE = 18; /** * Fixed corner radius for 5x5 matrix buttons, in px. - * @type {number} - * @const */ - static MATRIX_NODE_RADIUS = 4; + static readonly MATRIX_NODE_RADIUS = 4; /** * Fixed padding for 5x5 matrix buttons, in px. - * @type {number} - * @const */ - static MATRIX_NODE_PAD = 5; + static readonly MATRIX_NODE_PAD = 5; /** * String with 25 '0' chars. * Used for clearing a matrix or filling an LED node array. - * @type {string} - * @const */ - static ZEROS = "0000000000000000000000000"; + static readonly ZEROS = "0000000000000000000000000"; /** * String with 25 '1' chars. * Used for filling a matrix. - * @type {string} - * @const */ - static ONES = "1111111111111111111111111"; + static readonly ONES = "1111111111111111111111111"; /** * Called when the field is placed on a block. - * @param {Block} block The owning block. */ initView() { // Build the DOM. this.updateSize_(); - const dropdownArrowPadding = this.getConstants().GRID_UNIT * 2; - var thumbX = dropdownArrowPadding / 2; - var thumbY = (this.size_.height - FieldMatrix.THUMBNAIL_SIZE) / 2; - var thumbnail = Blockly.utils.dom.createSvgElement( + const dropdownArrowPadding = + (this.getConstants() as Blockly.zelos.ConstantProvider).GRID_UNIT * 2; + const thumbX = dropdownArrowPadding / 2; + const thumbY = (this.size_.height - FieldMatrix.THUMBNAIL_SIZE) / 2; + const thumbnail = Blockly.utils.dom.createSvgElement( "g", { transform: "translate(" + thumbX + ", " + thumbY + ")", @@ -209,11 +180,11 @@ class FieldMatrix extends Blockly.Field { this.fieldGroup_ ); this.ledThumbNodes_ = []; - var nodeSize = FieldMatrix.THUMBNAIL_NODE_SIZE; - var nodePad = FieldMatrix.THUMBNAIL_NODE_PAD; - for (var i = 0; i < 5; i++) { - for (var n = 0; n < 5; n++) { - var attr = { + const nodeSize = FieldMatrix.THUMBNAIL_NODE_SIZE; + const nodePad = FieldMatrix.THUMBNAIL_NODE_PAD; + for (let i = 0; i < 5; i++) { + for (let n = 0; n < 5; n++) { + const attr = { x: (nodeSize + nodePad) * n + nodePad, y: (nodeSize + nodePad) * i + nodePad, width: nodeSize, @@ -230,8 +201,8 @@ class FieldMatrix extends Blockly.Field { } if (!this.arrow_) { - var arrowX = FieldMatrix.THUMBNAIL_SIZE + dropdownArrowPadding * 1.5; - var arrowY = (this.size_.height - FieldMatrix.ARROW_SIZE) / 2; + const arrowX = FieldMatrix.THUMBNAIL_SIZE + dropdownArrowPadding * 1.5; + const arrowY = (this.size_.height - FieldMatrix.ARROW_SIZE) / 2; this.arrow_ = Blockly.utils.dom.createSvgElement( "image", { @@ -250,13 +221,13 @@ class FieldMatrix extends Blockly.Field { } } - doClassValidation_(matrix) { + doClassValidation_(matrix: string) { return matrix ? matrix + FieldMatrix.ZEROS.substr(0, 25 - matrix.length) : matrix; } - doValueUpdate_(newValue) { + doValueUpdate_(newValue: string) { super.doValueUpdate_(newValue); if (newValue) { this.updateMatrix_(); @@ -265,12 +236,11 @@ class FieldMatrix extends Blockly.Field { /** * Show the drop-down menu for editing this field. - * @private */ showEditor_() { - var div = Blockly.DropDownDiv.getContentDiv(); + const div = Blockly.DropDownDiv.getContentDiv(); // Build the SVG DOM. - var matrixSize = + const matrixSize = FieldMatrix.MATRIX_NODE_SIZE * 5 + FieldMatrix.MATRIX_NODE_PAD * 6; this.matrixStage_ = Blockly.utils.dom.createSvgElement( "svg", @@ -286,15 +256,15 @@ class FieldMatrix extends Blockly.Field { ); // Create the 5x5 matrix this.ledButtons_ = []; - for (var i = 0; i < 5; i++) { - for (var n = 0; n < 5; n++) { - var x = + for (let i = 0; i < 5; i++) { + for (let n = 0; n < 5; n++) { + const x = FieldMatrix.MATRIX_NODE_SIZE * n + FieldMatrix.MATRIX_NODE_PAD * (n + 1); - var y = + const y = FieldMatrix.MATRIX_NODE_SIZE * i + FieldMatrix.MATRIX_NODE_PAD * (i + 1); - var attr = { + const attr = { x: x + "px", y: y + "px", width: FieldMatrix.MATRIX_NODE_SIZE, @@ -302,7 +272,7 @@ class FieldMatrix extends Blockly.Field { rx: FieldMatrix.MATRIX_NODE_RADIUS, ry: FieldMatrix.MATRIX_NODE_RADIUS, }; - var led = Blockly.utils.dom.createSvgElement( + const led = Blockly.utils.dom.createSvgElement( "rect", attr, this.matrixStage_ @@ -312,18 +282,17 @@ class FieldMatrix extends Blockly.Field { } } // Div for lower button menu - var buttonDiv = document.createElement("div"); + const buttonDiv = document.createElement("div"); // Button to clear matrix - var clearButtonDiv = document.createElement("div"); + const clearButtonDiv = document.createElement("div"); clearButtonDiv.className = "scratchMatrixButtonDiv"; - var clearButton = this.createButton_( - this.sourceBlock_.getColourSecondary() - ); + const sourceBlock = this.getSourceBlock() as Blockly.BlockSvg; + const clearButton = this.createButton_(sourceBlock.getColourSecondary()); clearButtonDiv.appendChild(clearButton); // Button to fill matrix - var fillButtonDiv = document.createElement("div"); + const fillButtonDiv = document.createElement("div"); fillButtonDiv.className = "scratchMatrixButtonDiv"; - var fillButton = this.createButton_("#FFFFFF"); + const fillButton = this.createButton_("#FFFFFF"); fillButtonDiv.appendChild(fillButton); buttonDiv.appendChild(clearButtonDiv); @@ -331,12 +300,12 @@ class FieldMatrix extends Blockly.Field { div.appendChild(buttonDiv); Blockly.DropDownDiv.setColour( - this.sourceBlock_.getColour(), - this.sourceBlock_.getColourTertiary() + sourceBlock.getColour(), + sourceBlock.getColourTertiary() ); Blockly.DropDownDiv.showPositionedByBlock( this, - this.sourceBlock_, + sourceBlock, this.dropdownDispose_.bind(this) ); @@ -359,7 +328,6 @@ class FieldMatrix extends Blockly.Field { this.fillMatrix_ ); - const sourceBlock = this.getSourceBlock(); const style = sourceBlock.style; if (sourceBlock.isShadow()) { this.originalStyle = sourceBlock.getStyleName(); @@ -367,7 +335,9 @@ class FieldMatrix extends Blockly.Field { } else if (this.borderRect_) { this.borderRect_.setAttribute( "fill", - style.colourQuaternary ?? style.colourTertiary + "colourQuaternary" in style + ? `${style.colourQuaternary}` + : style.colourTertiary ); } @@ -384,11 +354,12 @@ class FieldMatrix extends Blockly.Field { /** * Make an svg object that resembles a 3x3 matrix to be used as a button. - * @param {string} fill The color to fill the matrix nodes. - * @return {SvgElement} The button svg element. + * + * @param fill The color to fill the matrix nodes. + * @returns The button svg element. */ - createButton_(fill) { - var button = Blockly.utils.dom.createSvgElement("svg", { + createButton_(fill: string): SVGElement { + const button = Blockly.utils.dom.createSvgElement("svg", { xmlns: "http://www.w3.org/2000/svg", "xmlns:html": "http://www.w3.org/1999/xhtml", "xmlns:xlink": "http://www.w3.org/1999/xlink", @@ -396,10 +367,10 @@ class FieldMatrix extends Blockly.Field { height: FieldMatrix.MATRIX_NODE_SIZE + "px", width: FieldMatrix.MATRIX_NODE_SIZE + "px", }); - var nodeSize = FieldMatrix.MATRIX_NODE_SIZE / 4; - var nodePad = FieldMatrix.MATRIX_NODE_SIZE / 16; - for (var i = 0; i < 3; i++) { - for (var n = 0; n < 3; n++) { + const nodeSize = FieldMatrix.MATRIX_NODE_SIZE / 4; + const nodePad = FieldMatrix.MATRIX_NODE_SIZE / 16; + for (let i = 0; i < 3; i++) { + for (let n = 0; n < 3; n++) { Blockly.utils.dom.createSvgElement( "rect", { @@ -420,22 +391,18 @@ class FieldMatrix extends Blockly.Field { /** * Redraw the matrix with the current value. - * @private */ - updateMatrix_() { + private updateMatrix_() { const matrix = this.getValue(); - for (var i = 0; i < matrix.length; i++) { - if (matrix[i] === "0") { + const sourceBlock = this.getSourceBlock() as Blockly.BlockSvg; + for (let i = 0; i < matrix.length; i++) { + if (matrix[i] === LEDState.OFF) { this.fillMatrixNode_( this.ledButtons_, i, - this.sourceBlock_.getColourSecondary() - ); - this.fillMatrixNode_( - this.ledThumbNodes_, - i, - this.sourceBlock_.getColour() + sourceBlock.getColourSecondary() ); + this.fillMatrixNode_(this.ledThumbNodes_, i, sourceBlock.getColour()); } else { this.fillMatrixNode_(this.ledButtons_, i, "#FFFFFF"); this.fillMatrixNode_(this.ledThumbNodes_, i, "#FFFFFF"); @@ -445,34 +412,37 @@ class FieldMatrix extends Blockly.Field { /** * Clear the matrix. - * @param {!Event} e Mouse event. + * + * @param e Mouse event. */ - clearMatrix_(e) { + clearMatrix_(e: PointerEvent) { if (e.button != 0) return; this.setValue(FieldMatrix.ZEROS); } /** * Fill the matrix. - * @param {!Event} e Mouse event. + * + * @param e Mouse event. */ - fillMatrix_(e) { + fillMatrix_(e: PointerEvent) { if (e.button != 0) return; this.setValue(FieldMatrix.ONES); } /** * Fill matrix node with specified colour. - * @param {!Array} node The array of matrix nodes. - * @param {!number} index The index of the matrix node. - * @param {!string} fill The fill colour in '#rrggbb' format. + * + * @param node The array of matrix nodes. + * @param index The index of the matrix node. + * @param fill The fill colour in '#rrggbb' format. */ - fillMatrixNode_(node, index, fill) { + fillMatrixNode_(node: SVGElement[], index: number, fill: string) { if (!node || !node[index] || !fill) return; node[index].setAttribute("fill", fill); } - setLEDNode_(led, state) { + setLEDNode_(led: number, state: LEDState) { if (led < 0 || led > 24) return; const oldMatrix = this.getValue(); const newMatrix = @@ -480,30 +450,31 @@ class FieldMatrix extends Blockly.Field { this.setValue(newMatrix); } - fillLEDNode_(led) { + fillLEDNode_(led: number) { if (led < 0 || led > 24) return; - this.setLEDNode_(led, "1"); + this.setLEDNode_(led, LEDState.ON); } - clearLEDNode_(led) { + clearLEDNode_(led: number) { if (led < 0 || led > 24) return; - this.setLEDNode_(led, "0"); + this.setLEDNode_(led, LEDState.OFF); } - toggleLEDNode_(led) { + toggleLEDNode_(led: number) { if (led < 0 || led > 24) return; - if (this.getValue().charAt(led) === "0") { - this.setLEDNode_(led, "1"); + if (this.getValue().charAt(led) === LEDState.OFF) { + this.setLEDNode_(led, LEDState.ON); } else { - this.setLEDNode_(led, "0"); + this.setLEDNode_(led, LEDState.OFF); } } /** * Toggle matrix nodes on and off. - * @param {!Event} e Mouse event. + * + * @param e Mouse event. */ - onMouseDown(e) { + onMouseDown(e: PointerEvent) { this.matrixMoveWrapper_ = Blockly.browserEvents.bind( document.body, "mousemove", @@ -516,12 +487,12 @@ class FieldMatrix extends Blockly.Field { this, this.onMouseUp ); - var ledHit = this.checkForLED_(e); + const ledHit = this.checkForLED_(e); if (ledHit > -1) { - if (this.getValue().charAt(ledHit) === "0") { - this.paintStyle_ = "fill"; + if (this.getValue().charAt(ledHit) === LEDState.OFF) { + this.paintStyle_ = PaintStyle.FILL; } else { - this.paintStyle_ = "clear"; + this.paintStyle_ = PaintStyle.CLEAR; } this.toggleLEDNode_(ledHit); this.updateMatrix_(); @@ -532,7 +503,6 @@ class FieldMatrix extends Blockly.Field { /** * Unbind mouse move event and clear the paint style. - * @param {!Event} e Mouse move event. */ onMouseUp() { Blockly.browserEvents.unbind(this.matrixMoveWrapper_); @@ -544,16 +514,17 @@ class FieldMatrix extends Blockly.Field { /** * Toggle matrix nodes on and off by dragging mouse. - * @param {!Event} e Mouse move event. + * + * @param e Mouse move event. */ - onMouseMove(e) { + onMouseMove(e: PointerEvent) { e.preventDefault(); if (this.paintStyle_) { - var led = this.checkForLED_(e); + const led = this.checkForLED_(e); if (led < 0) return; - if (this.paintStyle_ === "clear") { + if (this.paintStyle_ === PaintStyle.CLEAR) { this.clearLEDNode_(led); - } else if (this.paintStyle_ === "fill") { + } else if (this.paintStyle_ === PaintStyle.FILL) { this.fillLEDNode_(led); } } @@ -561,35 +532,34 @@ class FieldMatrix extends Blockly.Field { /** * Check if mouse coordinates collide with a matrix node. - * @param {!Event} e Mouse move event. - * @return {number} The matching matrix node or -1 for none. - */ - checkForLED_(e) { - var bBox = this.matrixStage_.getBoundingClientRect(); - var nodeSize = FieldMatrix.MATRIX_NODE_SIZE; - var nodePad = FieldMatrix.MATRIX_NODE_PAD; - var dx = e.clientX - bBox.left; - var dy = e.clientY - bBox.top; - var min = nodePad / 2; - var max = bBox.width - nodePad / 2; + * + * @param e Mouse move event. + * @returns The matching matrix node or -1 for none. + */ + checkForLED_(e: PointerEvent): number { + const bBox = this.matrixStage_.getBoundingClientRect(); + const nodeSize = FieldMatrix.MATRIX_NODE_SIZE; + const nodePad = FieldMatrix.MATRIX_NODE_PAD; + const dx = e.clientX - bBox.left; + const dy = e.clientY - bBox.top; + const min = nodePad / 2; + const max = bBox.width - nodePad / 2; if (dx < min || dx > max || dy < min || dy > max) { return -1; } - var xDiv = Math.trunc((dx - nodePad / 2) / (nodeSize + nodePad)); - var yDiv = Math.trunc((dy - nodePad / 2) / (nodeSize + nodePad)); + const xDiv = Math.trunc((dx - nodePad / 2) / (nodeSize + nodePad)); + const yDiv = Math.trunc((dy - nodePad / 2) / (nodeSize + nodePad)); return xDiv + yDiv * nodePad; } /** * Clean up this FieldMatrix, as well as the inherited Field. - * @return {!Function} Closure to call on destruction of the WidgetDiv. - * @private */ dispose() { super.dispose(); this.matrixStage_ = null; - if (this.mouseDownWrapper_) { - Blockly.browserEvents.unbind(this.mouseDownWrapper_); + if (this.mouseDownWrapper) { + Blockly.browserEvents.unbind(this.mouseDownWrapper); } if (this.matrixTouchWrapper_) { Blockly.browserEvents.unbind(this.matrixTouchWrapper_); @@ -608,8 +578,8 @@ class FieldMatrix extends Blockly.Field { } } - updateSize_(margin) { - const constants = this.getConstants(); + updateSize_() { + const constants = this.getConstants() as Blockly.zelos.ConstantProvider; let totalHeight = constants.FIELD_TEXT_HEIGHT; this.size_.height = totalHeight; @@ -622,10 +592,14 @@ class FieldMatrix extends Blockly.Field { } getClickTarget_() { - return this.sourceBlock_.getSvgRoot(); + return (this.getSourceBlock() as Blockly.BlockSvg).getSvgRoot(); } } +interface FieldMatrixConfig extends Blockly.FieldConfig { + matrix: string; +} + /** * Register the field and any dependencies. */ diff --git a/src/fields/field_note.js b/src/fields/field_note.ts similarity index 63% rename from src/fields/field_note.js rename to src/fields/field_note.ts index 63da4b4f0c..e9539cf55e 100644 --- a/src/fields/field_note.js +++ b/src/fields/field_note.ts @@ -36,124 +36,87 @@ import * as Blockly from "blockly/core"; * @constructor */ export class FieldNote extends Blockly.FieldTextInput { - constructor(opt_value, opt_validator) { - opt_value = opt_value && !isNaN(opt_value) ? String(opt_value) : "0"; - super(opt_value, opt_validator); - - /** - * Width of the field. Computed when drawing it, and used for animation. - * @type {number} - * @private - */ - this.fieldEditorWidth_ = 0; - - /** - * Height of the field. Computed when drawing it. - * @type {number} - * @private - */ - this.fieldEditorHeight_ = 0; - - /** - * The piano SVG. - * @type {SVGElement} - * @private - */ - this.pianoSVG_ = null; + /** + * Width of the field. Computed when drawing it, and used for animation. + */ + private fieldEditorWidth_ = 0; - /** - * Array of SVG elements representing the clickable piano keys. - * @type {!Array} - * @private - */ - this.keySVGs_ = []; + /** + * Height of the field. Computed when drawing it. + */ + private fieldEditorHeight_ = 0; - /** - * Note name indicator at the top of the field. - * @type {SVGElement} - * @private - */ - this.noteNameText_ = null; + /** + * The piano SVG. + */ + private pianoSVG_: SVGElement | null = null; - /** - * Note name indicator on the low C key. - * @type {SVGElement} - * @private - */ - this.lowCText_ = null; + /** + * Array of SVG elements representing the clickable piano keys. + */ + private keySVGs_: SVGElement[] = []; - /** - * Note name indicator on the low C key. - * @type {SVGElement} - * @private - */ - this.highCText_ = null; + /** + * Note name indicator at the top of the field. + */ + private noteNameText_: SVGElement | null = null; - /** - * Octave number of the currently displayed range of keys. - * @type {number} - * @private - */ - this.displayedOctave_ = null; - - /** - * Current animation position of the piano SVG, as it shifts left or right to - * change octaves. - * @type {number} - * @private - */ - this.animationPos_ = 0; + /** + * Note name indicator on the low C key. + */ + private lowCText_: SVGElement | null = null; - /** - * Target position for the animation as the piano SVG shifts left or right. - * @type {number} - * @private - */ - this.animationTarget_ = 0; - - /** - * A flag indicating that the mouse is currently down. Used in combination with - * mouse enter events to update the key selection while dragging. - * @type {boolean} - * @private - */ - this.mouseIsDown_ = false; + /** + * Note name indicator on the low C key. + */ + private highCText_: SVGElement | null = null; - /** - * An array of wrappers for mouse down events on piano keys. - * @type {!Array.} - * @private - */ - this.mouseDownWrappers_ = []; - - /** - * A wrapper for the mouse up event. - * @type {!Array.} - * @private - */ - this.mouseUpWrapper_ = null; + /** + * Octave number of the currently displayed range of keys. + */ + private displayedOctave_: number | null = null; - /** - * An array of wrappers for mouse enter events on piano keys. - * @type {!Array.} - * @private - */ - this.mouseEnterWrappers_ = []; - - /** - * A wrapper for the mouse down event on the octave down button. - * @type {!Array.} - * @private - */ - this.octaveDownMouseDownWrapper_ = null; - - /** - * A wrapper for the mouse down event on the octave up button. - * @type {!Array.} - * @private - */ - this.octaveUpMouseDownWrapper_ = null; - } + /** + * Current animation position of the piano SVG, as it shifts left or right to + * change octaves. + */ + private animationPos_ = 0; + + /** + * Target position for the animation as the piano SVG shifts left or right. + */ + private animationTarget_ = 0; + + /** + * A flag indicating that the mouse is currently down. Used in combination with + * mouse enter events to update the key selection while dragging. + */ + private mouseIsDown_ = false; + + /** + * An array of wrappers for mouse down events on piano keys. + */ + private mouseDownWrappers_: Blockly.browserEvents.Data[] = []; + + /** + * A wrapper for the mouse up event. + */ + private mouseUpWrapper_: Blockly.browserEvents.Data | null = null; + + /** + * An array of wrappers for mouse enter events on piano keys. + */ + private mouseEnterWrappers_: Blockly.browserEvents.Data[] = []; + + /** + * A wrapper for the mouse down event on the octave down button. + */ + private octaveDownMouseDownWrapper_: Blockly.browserEvents.Data | null = null; + + /** + * A wrapper for the mouse down event on the octave up button. + */ + private octaveUpMouseDownWrapper_: Blockly.browserEvents.Data | null = null; /** * Inset in pixels of content displayed in the field, caused by parent properties. @@ -164,122 +127,88 @@ export class FieldNote extends Blockly.FieldTextInput { /** * Height of the top area of the field, in px. - * @type {number} - * @const */ - static TOP_MENU_HEIGHT = 32 - FieldNote.INSET; + static readonly TOP_MENU_HEIGHT = 32 - FieldNote.INSET; /** * Padding on the top and sides of the field, in px. - * @type {number} - * @const */ - static EDGE_PADDING = 1; + static readonly EDGE_PADDING = 1; /** * Height of the drop shadow on the piano, in px. - * @type {number} - * @const */ - static SHADOW_HEIGHT = 4; + static readonly SHADOW_HEIGHT = 4; /** * Color for the shadow on the piano. - * @type {string} - * @const */ - static SHADOW_COLOR = "#000"; + static readonly SHADOW_COLOR = "#000"; /** * Opacity for the shadow on the piano. - * @type {string} - * @const */ - static SHADOW_OPACITY = 0.2; + static readonly SHADOW_OPACITY = 0.2; /** * A color for the white piano keys. - * @type {string} - * @const */ - static WHITE_KEY_COLOR = "#FFFFFF"; + static readonly WHITE_KEY_COLOR = "#FFFFFF"; /** * A color for the black piano keys. - * @type {string} - * @const */ - static BLACK_KEY_COLOR = "#323133"; + static readonly BLACK_KEY_COLOR = "#323133"; /** * A color for stroke around black piano keys. - * @type {string} - * @const */ - static BLACK_KEY_STROKE = "#555555"; + static readonly BLACK_KEY_STROKE = "#555555"; /** * A color for the selected state of a piano key. - * @type {string} - * @const */ - static KEY_SELECTED_COLOR = "#b0d6ff"; + static readonly KEY_SELECTED_COLOR = "#b0d6ff"; /** * The number of white keys in one octave on the piano. - * @type {number} - * @const */ - static NUM_WHITE_KEYS = 8; + static readonly NUM_WHITE_KEYS = 8; /** * Height of a white piano key, in px. - * @type {string} - * @const */ - static WHITE_KEY_HEIGHT = 72; + static readonly WHITE_KEY_HEIGHT = 72; /** * Width of a white piano key, in px. - * @type {string} - * @const */ - static WHITE_KEY_WIDTH = 40; + static readonly WHITE_KEY_WIDTH = 40; /** * Height of a black piano key, in px. - * @type {string} - * @const */ - static BLACK_KEY_HEIGHT = 40; + static readonly BLACK_KEY_HEIGHT = 40; /** * Width of a black piano key, in px. - * @type {string} - * @const */ - static BLACK_KEY_WIDTH = 32; + static readonly BLACK_KEY_WIDTH = 32; /** * Radius of the curved bottom corner of a piano key, in px. - * @type {string} - * @const */ - static KEY_RADIUS = 6; + static readonly KEY_RADIUS = 6; /** * Bottom padding for the labels on C keys. - * @type {string} - * @const */ - static KEY_LABEL_PADDING = 8; + static readonly KEY_LABEL_PADDING = 8; /** * An array of objects with data describing the keys on the piano. - * @type {Array.<{name: String, pitch: Number, isBlack: boolean}>} - * @const */ - static KEY_INFO = [ + static readonly KEY_INFO = [ { name: "C", pitch: 0 }, { name: "C♯", pitch: 1, isBlack: true }, { name: "D", pitch: 2 }, @@ -297,48 +226,37 @@ export class FieldNote extends Blockly.FieldTextInput { /** * The MIDI note number of the highest note selectable on the piano. - * @type {number} - * @const */ - static MAX_NOTE = 130; + static readonly MAX_NOTE = 130; /** * The fraction of the distance to the target location to move the piano at each * step of the animation. - * @type {number} - * @const */ - static ANIMATION_FRACTION = 0.2; + static readonly ANIMATION_FRACTION = 0.2; /** * Path to the arrow svg icon, used on the octave buttons. - * @type {string} - * @const */ - static ARROW_SVG_PATH = "icons/arrow_button.svg"; + static readonly ARROW_SVG_PATH = "icons/arrow_button.svg"; /** * The size of the square octave buttons. - * @type {number} - * @const */ - static OCTAVE_BUTTON_SIZE = 32; + static readonly OCTAVE_BUTTON_SIZE = 32; /** * Construct a FieldNote from a JSON arg object. - * @param {!Object} options A JSON object with options. - * @returns {!Blockly.FieldNote} The new field instance. - * @package - * @nocollapse + * + * @param options A JSON object with options. + * @returns The new field instance. */ - static fromJson(options) { + static fromJson(options: FieldNoteJsonConfig): FieldNote { return new FieldNote(options["note"]); } /** * Clean up this FieldNote, as well as the inherited FieldTextInput. - * @return {!Function} Closure to call on destruction of the WidgetDiv. - * @private */ dispose() { super.dispose(); @@ -366,13 +284,12 @@ export class FieldNote extends Blockly.FieldTextInput { /** * Show a field with piano keys. - * @private */ - showEditor_(event, quietInput = false) { + showEditor_(event: PointerEvent, quietInput = false) { super.showEditor_(event, quietInput); // Build the SVG DOM. - var div = Blockly.DropDownDiv.getContentDiv(); + const div = Blockly.DropDownDiv.getContentDiv(); this.fieldEditorWidth_ = FieldNote.NUM_WHITE_KEYS * FieldNote.WHITE_KEY_WIDTH + @@ -382,7 +299,7 @@ export class FieldNote extends Blockly.FieldTextInput { FieldNote.WHITE_KEY_HEIGHT + FieldNote.EDGE_PADDING; - var svg = Blockly.utils.dom.createSvgElement( + const svg = Blockly.utils.dom.createSvgElement( "svg", { xmlns: "http://www.w3.org/2000/svg", @@ -399,12 +316,12 @@ export class FieldNote extends Blockly.FieldTextInput { // Since we are adding the keys from left to right in order, they need // to be in two groups in order to layer correctly. this.pianoSVG_ = Blockly.utils.dom.createSvgElement("g", {}, svg); - var whiteKeyGroup = Blockly.utils.dom.createSvgElement( + const whiteKeyGroup = Blockly.utils.dom.createSvgElement( "g", {}, this.pianoSVG_ ); - var blackKeyGroup = Blockly.utils.dom.createSvgElement( + const blackKeyGroup = Blockly.utils.dom.createSvgElement( "g", {}, this.pianoSVG_ @@ -441,9 +358,9 @@ export class FieldNote extends Blockly.FieldTextInput { ); // Note names on the low and high C keys - var lowCX = FieldNote.WHITE_KEY_WIDTH / 2; + const lowCX = FieldNote.WHITE_KEY_WIDTH / 2; this.lowCText_ = this.addCKeyLabel_(lowCX, svg); - var highCX = + const highCX = lowCX + FieldNote.WHITE_KEY_WIDTH * (FieldNote.NUM_WHITE_KEYS - 1); this.highCText_ = this.addCKeyLabel_(highCX, svg); @@ -451,7 +368,9 @@ export class FieldNote extends Blockly.FieldTextInput { Blockly.utils.dom.createSvgElement( "line", { - stroke: this.sourceBlock_.parentBlock_.getColourTertiary(), + stroke: ( + this.sourceBlock_.getParent() as Blockly.BlockSvg + ).getColourTertiary(), x1: 0, y1: FieldNote.TOP_MENU_HEIGHT, x2: this.fieldEditorWidth_, @@ -475,8 +394,8 @@ export class FieldNote extends Blockly.FieldTextInput { ); // Octave buttons - this.octaveDownButton = this.addOctaveButton_(0, true, svg); - this.octaveUpButton = this.addOctaveButton_( + const octaveDownButton = this.addOctaveButton_(0, true, svg); + const octaveUpButton = this.addOctaveButton_( this.fieldEditorWidth_ + FieldNote.INSET * 2 - FieldNote.OCTAVE_BUTTON_SIZE, @@ -485,7 +404,7 @@ export class FieldNote extends Blockly.FieldTextInput { ); this.octaveDownMouseDownWrapper_ = Blockly.browserEvents.bind( - this.octaveDownButton, + octaveDownButton, "mousedown", this, function () { @@ -493,34 +412,40 @@ export class FieldNote extends Blockly.FieldTextInput { } ); this.octaveUpMouseDownWrapper_ = Blockly.browserEvents.bind( - this.octaveUpButton, + octaveUpButton, "mousedown", this, function () { this.changeOctaveBy_(1); } ); + const sourceBlock = this.getSourceBlock() as Blockly.BlockSvg; Blockly.DropDownDiv.setColour( - this.sourceBlock_.parentBlock_.getColour(), - this.sourceBlock_.parentBlock_.getColourTertiary() + sourceBlock.getParent().getColour(), + sourceBlock.getParent().getColourTertiary() ); - Blockly.DropDownDiv.showPositionedByBlock(this, this.sourceBlock_); + Blockly.DropDownDiv.showPositionedByBlock(this, sourceBlock); this.updateSelection_(); } /** * Add one octave of piano keys drawn using SVG. - * @param {number} x The x position of the left edge of this octave of keys. - * @param {SVGElement} whiteKeyGroup The group for all white piano keys. - * @param {SvgElement} blackKeyGroup The group for all black piano keys. - * @param {!Array.} keySVGarray An array containing all the key SVGs. - * @private - */ - addPianoOctave_(x, whiteKeyGroup, blackKeyGroup, keySVGarray) { - var xIncrement, width, height, fill, stroke, group; + * + * @param x The x position of the left edge of this octave of keys. + * @param whiteKeyGroup The group for all white piano keys. + * @param blackKeyGroup The group for all black piano keys. + * @param keySVGarray An array containing all the key SVGs. + */ + private addPianoOctave_( + x: number, + whiteKeyGroup: SVGElement, + blackKeyGroup: SVGElement, + keySVGarray: SVGElement[] + ) { + let xIncrement, width, height, fill, stroke, group; x += FieldNote.EDGE_PADDING / 2; - var y = FieldNote.TOP_MENU_HEIGHT; + const y = FieldNote.TOP_MENU_HEIGHT; for (var i = 0; i < FieldNote.KEY_INFO.length; i++) { // Draw a black or white key if (FieldNote.KEY_INFO[i].isBlack) { @@ -537,23 +462,25 @@ export class FieldNote extends Blockly.FieldTextInput { width = FieldNote.WHITE_KEY_WIDTH; height = FieldNote.WHITE_KEY_HEIGHT; fill = FieldNote.WHITE_KEY_COLOR; - stroke = this.sourceBlock_.parentBlock_.getColourTertiary(); + stroke = ( + this.sourceBlock_.getParent() as Blockly.BlockSvg + ).getColourTertiary(); group = whiteKeyGroup; } - var attr = { + const attr = { d: this.getPianoKeyPath_(x, y, width, height), fill: fill, stroke: stroke, }; x += xIncrement; - var keySVG = Blockly.utils.dom.createSvgElement("path", attr, group); + const keySVG = Blockly.utils.dom.createSvgElement("path", attr, group); if (keySVGarray) { keySVGarray[i] = keySVG; - keySVG.setAttribute("data-pitch", FieldNote.KEY_INFO[i].pitch); - keySVG.setAttribute("data-name", FieldNote.KEY_INFO[i].name); - keySVG.setAttribute("data-isBlack", FieldNote.KEY_INFO[i].isBlack); + keySVG.setAttribute("data-pitch", `${FieldNote.KEY_INFO[i].pitch}`); + keySVG.setAttribute("data-name", `${FieldNote.KEY_INFO[i].name}`); + keySVG.setAttribute("data-isBlack", `${FieldNote.KEY_INFO[i].isBlack}`); this.mouseDownWrappers_[i] = Blockly.browserEvents.bind( keySVG, @@ -574,14 +501,19 @@ export class FieldNote extends Blockly.FieldTextInput { /** * Construct the SVG path string for a piano key shape: a rectangle with rounded * corners at the bottom. - * @param {number} x the x position for the key. - * @param {number} y the y position for the key. - * @param {number} width the width of the key. - * @param {number} height the height of the key. - * @returns {string} the SVG path as a string. - * @private - */ - getPianoKeyPath_(x, y, width, height) { + * + * @param x the x position for the key. + * @param y the y position for the key. + * @param width the width of the key. + * @param height the height of the key. + * @returns the SVG path as a string. + */ + private getPianoKeyPath_( + x: number, + y: number, + width: number, + height: number + ): string { return ( "M" + x + @@ -630,16 +562,20 @@ export class FieldNote extends Blockly.FieldTextInput { /** * Add a button for switching the displayed octave of the piano up or down. - * @param {number} x The x position of the button. - * @param {boolean} flipped If true, the icon should be flipped. - * @param {SvgElement} svg The svg element to add the buttons to. - * @returns {SvgElement} A group containing the button SVG elements. - * @private - */ - addOctaveButton_(x, flipped, svg) { - var group = Blockly.utils.dom.createSvgElement("g", {}, svg); - var imageSize = FieldNote.OCTAVE_BUTTON_SIZE; - var arrow = Blockly.utils.dom.createSvgElement( + * + * @param x The x position of the button. + * @param flipped If true, the icon should be flipped. + * @param svg The svg element to add the buttons to. + * @returns A group containing the button SVG elements. + */ + private addOctaveButton_( + x: number, + flipped: boolean, + svg: SVGElement + ): SVGElement { + const group = Blockly.utils.dom.createSvgElement("g", {}, svg); + const imageSize = FieldNote.OCTAVE_BUTTON_SIZE; + const arrow = Blockly.utils.dom.createSvgElement( "image", { width: imageSize, @@ -657,7 +593,9 @@ export class FieldNote extends Blockly.FieldTextInput { Blockly.utils.dom.createSvgElement( "line", { - stroke: this.sourceBlock_.parentBlock_.getColourTertiary(), + stroke: ( + this.sourceBlock_.getParent() as Blockly.BlockSvg + ).getColourTertiary(), x1: x - FieldNote.INSET, y1: 0, x2: x - FieldNote.INSET, @@ -666,7 +604,8 @@ export class FieldNote extends Blockly.FieldTextInput { group ); if (flipped) { - var translateX = -1 * FieldNote.OCTAVE_BUTTON_SIZE + FieldNote.INSET * 2; + const translateX = + -1 * FieldNote.OCTAVE_BUTTON_SIZE + FieldNote.INSET * 2; group.setAttribute( "transform", "scale(-1, 1) " + "translate(" + translateX + ", 0)" @@ -677,12 +616,12 @@ export class FieldNote extends Blockly.FieldTextInput { /** * Add an SVG text label for display on the C keys of the piano. - * @param {number} x The x position for the label. - * @param {SvgElement} svg The SVG element to add the label to. - * @returns {SvgElement} The SVG element containing the label. - * @private + * + * @param x The x position for the label. + * @param svg The SVG element to add the label to. + * @returns The SVG element containing the label. */ - addCKeyLabel_(x, svg) { + private addCKeyLabel_(x: number, svg: SVGElement): SVGElement { return Blockly.utils.dom.createSvgElement( "text", { @@ -700,10 +639,10 @@ export class FieldNote extends Blockly.FieldTextInput { /** * Set the visibility of the C key labels. - * @param {boolean} visible If true, set labels to be visible. - * @private + * + * @param visible If true, set labels to be visible. */ - setCKeyLabelsVisible_(visible) { + private setCKeyLabelsVisible_(visible: boolean) { if (visible) { this.fadeSvgToOpacity_(this.lowCText_, 1); this.fadeSvgToOpacity_(this.highCText_, 1); @@ -715,11 +654,11 @@ export class FieldNote extends Blockly.FieldTextInput { /** * Animate an SVG to fade it in or out to a target opacity. - * @param {SvgElement} svg The SVG element to apply the fade to. - * @param {number} opacity The target opacity. - * @private + * + * @param svg The SVG element to apply the fade to. + * @param opacity The target opacity. */ - fadeSvgToOpacity_(svg, opacity) { + private fadeSvgToOpacity_(svg: SVGElement, opacity: number) { svg.setAttribute( "style", "opacity: " + opacity + "; transition: opacity 0.1s;" @@ -728,10 +667,10 @@ export class FieldNote extends Blockly.FieldTextInput { /** * Handle the mouse down event on a piano key. - * @param {!Event} e Mouse down event. - * @private + * + * @param e Mouse down event. */ - onMouseDownOnKey_(e) { + private onMouseDownOnKey_(e: PointerEvent) { this.mouseIsDown_ = true; this.mouseUpWrapper_ = Blockly.browserEvents.bind( document.body, @@ -744,9 +683,8 @@ export class FieldNote extends Blockly.FieldTextInput { /** * Handle the mouse up event following a mouse down on a piano key. - * @private */ - onMouseUp_() { + private onMouseUp_() { this.mouseIsDown_ = false; Blockly.browserEvents.unbind(this.mouseUpWrapper_); this.mouseUpWrapper_ = null; @@ -754,10 +692,10 @@ export class FieldNote extends Blockly.FieldTextInput { /** * Handle the event when the mouse enters a piano key. - * @param {!Event} e Mouse enter event. - * @private + * + * @param e Mouse enter event. */ - onMouseEnter_(e) { + private onMouseEnter_(e: PointerEvent) { if (this.mouseIsDown_) { this.selectNoteWithMouseEvent_(e); } @@ -765,21 +703,21 @@ export class FieldNote extends Blockly.FieldTextInput { /** * Use the data in a mouse event to select a new note, and play it. - * @param {!Event} e Mouse event. - * @private + * + * @param e Mouse event. */ - selectNoteWithMouseEvent_(e) { - var newNoteNum = - Number(e.target.getAttribute("data-pitch")) + this.displayedOctave_ * 12; + private selectNoteWithMouseEvent_(e: PointerEvent) { + const newNoteNum = + Number((e.target as HTMLElement).getAttribute("data-pitch")) + + this.displayedOctave_ * 12; this.setEditorValue_(newNoteNum); this.playNoteInternal_(); } /** * Play a note, by calling the externally overriden play note function. - * @private */ - playNoteInternal_() { + private playNoteInternal_() { if (FieldNote.playNote_) { FieldNote.playNote_(Number(this.getValue()), "Music"); } @@ -788,32 +726,32 @@ export class FieldNote extends Blockly.FieldTextInput { /** * Function to play a musical note corresponding to the key selected. * Overridden externally. - * @param {number} noteNum the MIDI note number to play. - * @param {string} id An id to select a scratch extension to play the note. - * @private + * + * @param noteNum the MIDI note number to play. + * @param id An id to select a scratch extension to play the note. */ - static playNote_ = function (/* noteNum, id*/) { + static playNote_ = function (noteNum: number, id: string) { return; }; /** * Change the selected note by a number of octaves, and start the animation. - * @param {number} octaves The number of octaves to change by. - * @private + * + * @param octaves The number of octaves to change by. */ - changeOctaveBy_(octaves) { + private changeOctaveBy_(octaves: number) { this.displayedOctave_ += octaves; if (this.displayedOctave_ < 0) { this.displayedOctave_ = 0; return; } - var maxOctave = Math.floor(FieldNote.MAX_NOTE / 12); + const maxOctave = Math.floor(FieldNote.MAX_NOTE / 12); if (this.displayedOctave_ > maxOctave) { this.displayedOctave_ = maxOctave; return; } - var newNote = Number(this.getText()) + octaves * 12; + const newNote = Number(this.getText()) + octaves * 12; this.setEditorValue_(newNote); this.animationTarget_ = this.fieldEditorWidth_ * octaves * -1; @@ -824,10 +762,9 @@ export class FieldNote extends Blockly.FieldTextInput { /** * Animate the piano up or down an octave by sliding it to the left or right. - * @private */ - stepOctaveAnimation_() { - var absDiff = Math.abs(this.animationPos_ - this.animationTarget_); + private stepOctaveAnimation_() { + const absDiff = Math.abs(this.animationPos_ - this.animationTarget_); if (absDiff < 1) { this.pianoSVG_.setAttribute("transform", "translate(0, 0)"); this.setCKeyLabelsVisible_(true); @@ -844,7 +781,7 @@ export class FieldNote extends Blockly.FieldTextInput { requestAnimationFrame(this.stepOctaveAnimation_.bind(this)); } - doValueUpdate_(newValue) { + doValueUpdate_(newValue: string) { super.doValueUpdate_(newValue); if (!this.textElement_) { @@ -857,20 +794,19 @@ export class FieldNote extends Blockly.FieldTextInput { /** * For a MIDI note number, find the index of the corresponding piano key. - * @param {number} noteNum The note number. - * @returns {number} The index of the piano key. - * @private + * + * @param noteNum The note number. + * @returns The index of the piano key. */ - noteNumToKeyIndex_(noteNum) { + private noteNumToKeyIndex_(noteNum: number): number { return Math.floor(noteNum) - this.displayedOctave_ * 12; } /** * Update the selected note and labels on the field. - * @private */ - updateSelection_() { - var noteNum = Number(this.getText()); + private updateSelection_() { + const noteNum = Number(this.getText()); // If the note is outside the currently displayed octave, update it if ( @@ -881,11 +817,11 @@ export class FieldNote extends Blockly.FieldTextInput { this.displayedOctave_ = Math.floor(noteNum / 12); } - var index = this.noteNumToKeyIndex_(noteNum); + const index = this.noteNumToKeyIndex_(noteNum); // Clear the highlight on all keys this.keySVGs_.forEach(function (svg) { - var isBlack = svg.getAttribute("data-isBlack"); + const isBlack = svg.getAttribute("data-isBlack"); if (isBlack === "true") { svg.setAttribute("fill", FieldNote.BLACK_KEY_COLOR); } else { @@ -896,11 +832,11 @@ export class FieldNote extends Blockly.FieldTextInput { if (this.keySVGs_[index]) { this.keySVGs_[index].setAttribute("fill", FieldNote.KEY_SELECTED_COLOR); // Update the note name text - var noteName = FieldNote.KEY_INFO[index].name; + const noteName = FieldNote.KEY_INFO[index].name; this.noteNameText_.textContent = noteName + " (" + Math.floor(noteNum) + ")"; // Update the low and high C note names - var lowCNum = this.displayedOctave_ * 12; + const lowCNum = this.displayedOctave_ * 12; this.lowCText_.textContent = "C(" + lowCNum + ")"; this.highCText_.textContent = "C(" + (lowCNum + 12) + ")"; } @@ -908,14 +844,15 @@ export class FieldNote extends Blockly.FieldTextInput { /** * Ensure that only a valid MIDI note number may be entered. - * @param {string} text The user's text. - * @return {?string} A string representing a valid note number, or null if invalid. + * + * @param text The user's text. + * @returns A string representing a valid note number, or null if invalid. */ - doClassValidation_(text) { + doClassValidation_(text: string): string | null { if (text === null) { return null; } - var n = parseFloat(text || 0); + var n = parseFloat(text || "0"); if (isNaN(n)) { return null; } @@ -929,6 +866,10 @@ export class FieldNote extends Blockly.FieldTextInput { } } +interface FieldNoteJsonConfig extends Blockly.FieldTextInputFromJsonConfig { + note: string; +} + /** * Register the field and any dependencies. */ diff --git a/src/fields/field_textinput_removable.js b/src/fields/field_textinput_removable.ts similarity index 72% rename from src/fields/field_textinput_removable.js rename to src/fields/field_textinput_removable.ts index 4ea60d19d7..9cc0243daf 100644 --- a/src/fields/field_textinput_removable.js +++ b/src/fields/field_textinput_removable.ts @@ -23,21 +23,14 @@ * @author pkaplan@media.mit.edu (Paul Kaplan) */ import * as Blockly from "blockly/core"; +import type { ProcedureDeclarationBlock } from "../blocks/procedures"; /** * Class for an editable text field displaying a deletion icon when selected. - * @param {string} text The initial content of the field. - * @param {Function=} opt_validator An optional function that is called - * to validate any constraints on what the user entered. Takes the new - * text as an argument and returns either the accepted text, a replacement - * text, or null to abort the change. - * @param {RegExp=} opt_restrictor An optional regular expression to restrict - * typed text to. Text that doesn't match the restrictor will never show - * in the text field. - * @extends {Blockly.FieldTextInput} - * @constructor */ export class FieldTextInputRemovable extends Blockly.FieldTextInput { + private removeButtonMouseWrapper_?: Blockly.browserEvents.Data; + /** * Show the inline free-text editor on top of the text with the remove button. */ @@ -68,11 +61,12 @@ export class FieldTextInputRemovable extends Blockly.FieldTextInput { /** * Function to call when remove button is called. Checks for removeFieldCallback * on sourceBlock and calls it if possible. - * @private */ - removeCallback_() { - if (this.sourceBlock_ && this.sourceBlock_.removeFieldCallback) { - this.sourceBlock_.removeFieldCallback(this); + private removeCallback_() { + if (this.sourceBlock_ && "removeFieldCallback" in this.sourceBlock_) { + (this.sourceBlock_ as ProcedureDeclarationBlock).removeFieldCallback( + this + ); } else { console.warn("Expected a source block with removeFieldCallback"); } @@ -81,13 +75,16 @@ export class FieldTextInputRemovable extends Blockly.FieldTextInput { /** * Helper function to construct a FieldTextInputRemovable from a JSON arg object, * dereferencing any string table references. - * @param {!Object} options A JSON object with options (text, class, and - * spellcheck). - * @returns {!Blockly.FieldTextInputRemovable} The new text input. - * @public + * + * @param options A JSON object with options (text, class, and spellcheck). + * @returns The new text input. */ - fromJson(options) { - const text = Blockly.utils.replaceMessageReferences(options["text"]); + fromJson( + options: Blockly.FieldTextInputFromJsonConfig + ): FieldTextInputRemovable { + const text = Blockly.utils.parsing.replaceMessageReferences( + options["text"] + ); const field = new FieldTextInputRemovable(text, null, options); if (typeof options["spellcheck"] == "boolean") { field.setSpellcheck(options["spellcheck"]); diff --git a/src/fields/field_variable_getter.js b/src/fields/field_variable_getter.ts similarity index 73% rename from src/fields/field_variable_getter.js rename to src/fields/field_variable_getter.ts index 75157c3612..b58b436560 100644 --- a/src/fields/field_variable_getter.js +++ b/src/fields/field_variable_getter.ts @@ -27,29 +27,36 @@ import * as Blockly from "blockly/core"; /** * Class for a variable getter field. - * @param {string} allowedVariableType The type of variables this field can display. */ class FieldVariableGetter extends Blockly.FieldLabel { - constructor(allowedVariableType = "") { + private variable: Blockly.IVariableModel | null = + null; + + /** + * Creates a new FieldVariableGetter. + * + * @param allowedVariableType The type of variables this field can display. + */ + constructor(private allowedVariableType = "") { super(Blockly.Field.SKIP_SETUP); this.SERIALIZABLE = true; - this.allowedVariableType = allowedVariableType; - this.variable = null; } /** * Returns the ID of this field's variable. - * @return {string} The ID of this field's variable. + * + * @returns The ID of this field's variable. */ - getValue() { + getValue(): string { return this.variable?.getId() ?? ""; } /** * Returns the name of this field's variable. - * @return {string} The name of this field's variable. + * + * @returns The name of this field's variable. */ - getText() { + getText(): string { return this.variable?.getName() ?? ""; } @@ -57,19 +64,19 @@ class FieldVariableGetter extends Blockly.FieldLabel { * Get the variable model for the variable associated with this field. * Not guaranteed to be in the variable map on the workspace (e.g. if accessed * after the variable has been deleted). - * @return {?Blockly.VariableModel} the selected variable, or null if none was - * selected. - * @package + * + * @returns the selected variable, or null if none was selected. */ - getVariable() { + getVariable(): Blockly.IVariableModel | null { return this.variable; } /** * Updates this field's variable to one with the given ID. - * @param {string} newVariableId ID of a variable this field should represent. + * + * @param newVariableId ID of a variable this field should represent. */ - doValueUpdate_(newVariableId) { + doValueUpdate_(newVariableId: string) { super.doValueUpdate_(newVariableId); const workspace = this.getSourceBlock().workspace; this.variable = Blockly.Variables.getVariable(workspace, newVariableId); @@ -85,15 +92,15 @@ class FieldVariableGetter extends Blockly.FieldLabel { this.forceRerender(); } - static fromJson(options) { + static fromJson(options: FieldVariableGetterConfig) { return new FieldVariableGetter(options["allowedVariableType"]); } - fromXml(element) { + fromXml(element: Element) { this.setValue(element.getAttribute("id")); } - toXml(element) { + toXml(element: Element): Element { element.setAttribute("id", this.variable.getId()); element.setAttribute("variabletype", this.variable.getType()); element.textContent = this.variable.getName(); @@ -101,6 +108,10 @@ class FieldVariableGetter extends Blockly.FieldLabel { } } +interface FieldVariableGetterConfig extends Blockly.FieldLabelConfig { + allowedVariableType?: string; +} + /** * Register the field and any dependencies. */ diff --git a/src/fields/field_vertical_separator.js b/src/fields/field_vertical_separator.ts similarity index 69% rename from src/fields/field_vertical_separator.js rename to src/fields/field_vertical_separator.ts index c7087642e0..f622a96df7 100644 --- a/src/fields/field_vertical_separator.js +++ b/src/fields/field_vertical_separator.ts @@ -26,10 +26,10 @@ import * as Blockly from "blockly/core"; /** * Class for a vertical separator line. - * @extends {Blockly.Field} - * @constructor */ class FieldVerticalSeparator extends Blockly.Field { + private lineElement?: SVGLineElement; + constructor() { super(Blockly.Field.SKIP_SETUP); /** @@ -39,17 +39,10 @@ class FieldVerticalSeparator extends Blockly.Field { } /** - * Construct a FieldVerticalSeparator from a JSON arg object. - * @param {!Object} _element A JSON object with options (unused, but passed in - * by Field.fromJson). - * @returns {!Blockly.FieldVerticalSeparator} The new field instance. - * @package - * @nocollapse + * Construct a FieldVerticalSeparator. + * @returns The new field instance. */ - static fromJson = function ( - /* eslint-disable no-unused-vars */ _element - /* eslint-enable no-unused-vars */ - ) { + static fromJson = function () { return new FieldVerticalSeparator(); }; @@ -57,14 +50,14 @@ class FieldVerticalSeparator extends Blockly.Field { * Install this field on a block. */ initView() { - const height = 10 * this.getConstants().GRID_UNIT; + const height = + 10 * (this.getConstants() as Blockly.zelos.ConstantProvider).GRID_UNIT; this.size_ = new Blockly.utils.Size(1, height); - /** @type {SVGElement} */ - this.lineElement_ = Blockly.utils.dom.createSvgElement( + this.lineElement = Blockly.utils.dom.createSvgElement( "line", { - stroke: this.sourceBlock_.getColourSecondary(), + stroke: (this.sourceBlock_ as Blockly.BlockSvg).getColourSecondary(), "stroke-linecap": "round", x1: 0, y1: 0, @@ -79,19 +72,17 @@ class FieldVerticalSeparator extends Blockly.Field { * Set the height of the line element, without adjusting the field's height. * This allows the line's height to be changed without causing it to be * centered with the new height (needed for correct rendering of hat blocks). - * @param {number} newHeight the new height for the line. + * @param newHeight the new height for the line. * @package */ - setLineHeight(newHeight) { - this.lineElement_.setAttribute("y2", newHeight); + setLineHeight(newHeight: number) { + this.lineElement.setAttribute("y2", `${newHeight}`); } /** * Get the value of this field. A no-op in this case. - * @return {string} null. - * @override */ - getValue() { + getValue(): string | null { return null; } @@ -101,19 +92,13 @@ class FieldVerticalSeparator extends Blockly.Field { /** * Set the value of this field. A no-op in this case. - * @param {?string} src New value. - * @override */ - setValue( - /* eslint-disable no-unused-vars */ src - /* eslint-enable no-unused-vars */ - ) { + setValue() { return; } /** * Separator lines are fixed width, no need to render. - * @private */ render_() { // NOP @@ -121,7 +106,6 @@ class FieldVerticalSeparator extends Blockly.Field { /** * Separator lines are fixed width, no need to update. - * @private */ updateWidth() { // NOP diff --git a/src/fields/field_angle.js b/src/fields/scratch_field_angle.ts similarity index 62% rename from src/fields/field_angle.js rename to src/fields/scratch_field_angle.ts index 0264c721eb..749c4e2498 100644 --- a/src/fields/field_angle.js +++ b/src/fields/scratch_field_angle.ts @@ -26,17 +26,42 @@ import * as Blockly from "blockly/core"; -class FieldAngle extends Blockly.FieldNumber { +class ScratchFieldAngle extends Blockly.FieldNumber { /** - * Construct a FieldAngle from a JSON arg object. - * @param {!Object} options A JSON object with options (angle). - * @returns {!Blockly.FieldAngle} The new field instance. - * @package - * @nocollapse + * The highlighted portion of the angle picker circle, between 0º and the + * selected angle. */ - fromJson(options) { - return new FieldAngle(options["angle"]); - } + private gauge?: SVGPathElement; + + /** + * The line to the angle picker handle. + */ + private line?: SVGLineElement; + + /** + * The grabbable handle used to choose an angle. + */ + private handle?: SVGGElement; + + /** + * The arrow graphic shown on the grab handle. + */ + private arrow?: SVGImageElement; + + /** + * Opaque identifier used to unbind event listener in dispose(). + */ + private mouseDownWrapper: Blockly.browserEvents.Data; + + /** + * Opaque identifier used to unbind event listener in dispose(). + */ + private mouseMoveWrapper: Blockly.browserEvents.Data; + + /** + * Opaque identifier used to unbind event listener in dispose(). + */ + private mouseUpWrapper: Blockly.browserEvents.Data; /** * Round angles to the nearest 15 degrees when using mouse. @@ -89,7 +114,8 @@ class FieldAngle extends Blockly.FieldNumber { ARROW_WIDTH = this.HANDLE_RADIUS; /** - * Half the stroke-width used for the "glow" around the drag handle, rounded up to nearest whole pixel + * Half the stroke-width used for the "glow" around the drag handle, rounded + * up to nearest whole pixel. */ HANDLE_GLOW_WIDTH = 3; @@ -111,36 +137,33 @@ class FieldAngle extends Blockly.FieldNumber { ARROW_SVG_PATH = "icons/arrow.svg"; /** - * Clean up this FieldAngle, as well as the inherited FieldTextInput. - * @return {!Function} Closure to call on destruction of the WidgetDiv. - * @private + * Clean up this FieldAngle, as well as the inherited FieldNumber. */ dispose() { super.dispose(); - this.gauge_ = null; - if (this.mouseDownWrapper_) { - Blockly.browserEvents.unbind(this.mouseDownWrapper_); + this.gauge = null; + if (this.mouseDownWrapper) { + Blockly.browserEvents.unbind(this.mouseDownWrapper); } - if (this.mouseUpWrapper_) { - Blockly.browserEvents.unbind(this.mouseUpWrapper_); + if (this.mouseUpWrapper) { + Blockly.browserEvents.unbind(this.mouseUpWrapper); } - if (this.mouseMoveWrapper_) { - Blockly.browserEvents.unbind(this.mouseMoveWrapper_); + if (this.mouseMoveWrapper) { + Blockly.browserEvents.unbind(this.mouseMoveWrapper); } } /** * Show the inline free-text editor on top of the text. - * @private */ - showEditor_(event) { + showEditor_(event: PointerEvent) { super.showEditor_(event); // If there is an existing drop-down someone else owns, hide it immediately and clear it. Blockly.DropDownDiv.hideWithoutAnimation(); Blockly.DropDownDiv.clearContent(); - var div = Blockly.DropDownDiv.getContentDiv(); + const div = Blockly.DropDownDiv.getContentDiv(); // Build the SVG DOM. - var svg = Blockly.utils.dom.createSvgElement( + const svg = Blockly.utils.dom.createSvgElement( "svg", { xmlns: "http://www.w3.org/2000/svg", @@ -158,19 +181,23 @@ class FieldAngle extends Blockly.FieldNumber { cx: this.HALF, cy: this.HALF, r: this.RADIUS, - fill: this.getSourceBlock().getParent().getColourSecondary(), - stroke: this.getSourceBlock().getParent().getColourTertiary(), + fill: ( + this.getSourceBlock().getParent() as Blockly.BlockSvg + ).getColourSecondary(), + stroke: ( + this.getSourceBlock().getParent() as Blockly.BlockSvg + ).getColourTertiary(), class: "blocklyAngleCircle", }, svg ); - this.gauge_ = Blockly.utils.dom.createSvgElement( + this.gauge = Blockly.utils.dom.createSvgElement( "path", { class: "blocklyAngleGauge" }, svg ); - // The moving line, x2 and y2 are set in updateGraph_ - this.line_ = Blockly.utils.dom.createSvgElement( + // The moving line, x2 and y2 are set in updateGraph + this.line = Blockly.utils.dom.createSvgElement( "line", { x1: this.HALF, @@ -180,7 +207,7 @@ class FieldAngle extends Blockly.FieldNumber { svg ); // The fixed vertical line at the offset - var offsetRadians = (Math.PI * this.OFFSET) / 180; + const offsetRadians = (Math.PI * this.OFFSET) / 180; Blockly.utils.dom.createSvgElement( "line", { @@ -193,7 +220,7 @@ class FieldAngle extends Blockly.FieldNumber { svg ); // Draw markers around the edge. - for (var angle = 0; angle < 360; angle += 15) { + for (let angle = 0; angle < 360; angle += 15) { Blockly.utils.dom.createSvgElement( "line", { @@ -220,7 +247,7 @@ class FieldAngle extends Blockly.FieldNumber { svg ); // Handle group: a circle and the arrow image - this.handle_ = Blockly.utils.dom.createSvgElement("g", {}, svg); + this.handle = Blockly.utils.dom.createSvgElement("g", {}, svg); Blockly.utils.dom.createSvgElement( "circle", { @@ -229,9 +256,9 @@ class FieldAngle extends Blockly.FieldNumber { r: this.HANDLE_RADIUS, class: "blocklyAngleDragHandle", }, - this.handle_ + this.handle ); - this.arrowSvg_ = Blockly.utils.dom.createSvgElement( + this.arrow = Blockly.utils.dom.createSvgElement( "image", { width: this.ARROW_WIDTH, @@ -240,9 +267,9 @@ class FieldAngle extends Blockly.FieldNumber { y: -this.ARROW_WIDTH / 2, class: "blocklyAngleDragArrow", }, - this.handle_ + this.handle ); - this.arrowSvg_.setAttributeNS( + this.arrow.setAttributeNS( "http://www.w3.org/1999/xlink", "xlink:href", Blockly.getMainWorkspace().options.pathToMedia + this.ARROW_SVG_PATH @@ -250,32 +277,36 @@ class FieldAngle extends Blockly.FieldNumber { Blockly.DropDownDiv.setColour( this.getSourceBlock().getParent().getColour(), - this.getSourceBlock().getParent().getColourTertiary() + ( + this.getSourceBlock().getParent() as Blockly.BlockSvg + ).getColourTertiary() + ); + Blockly.DropDownDiv.showPositionedByBlock( + this, + this.getSourceBlock() as Blockly.BlockSvg ); - Blockly.DropDownDiv.showPositionedByBlock(this, this.getSourceBlock()); - this.mouseDownWrapper_ = Blockly.browserEvents.bind( - this.handle_, + this.mouseDownWrapper = Blockly.browserEvents.bind( + this.handle, "mousedown", this, this.onMouseDown ); - this.updateGraph_(); + this.updateGraph(); } /** * Set the angle to match the mouse's position. - * @param {!Event} e Mouse move event. */ onMouseDown() { - this.mouseMoveWrapper_ = Blockly.browserEvents.bind( + this.mouseMoveWrapper = Blockly.browserEvents.bind( document.body, "mousemove", this, this.onMouseMove ); - this.mouseUpWrapper_ = Blockly.browserEvents.bind( + this.mouseUpWrapper = Blockly.browserEvents.bind( document.body, "mouseup", this, @@ -285,23 +316,22 @@ class FieldAngle extends Blockly.FieldNumber { /** * Set the angle to match the mouse's position. - * @param {!Event} e Mouse move event. */ onMouseUp() { - Blockly.browserEvents.unbind(this.mouseMoveWrapper_); - Blockly.browserEvents.unbind(this.mouseUpWrapper_); + Blockly.browserEvents.unbind(this.mouseMoveWrapper); + Blockly.browserEvents.unbind(this.mouseUpWrapper); } /** * Set the angle to match the mouse's position. - * @param {!Event} e Mouse move event. + * @param e Mouse move event. */ - onMouseMove(e) { + onMouseMove(e: PointerEvent) { e.preventDefault(); - var bBox = this.gauge_.ownerSVGElement.getBoundingClientRect(); - var dx = e.clientX - bBox.left - this.HALF; - var dy = e.clientY - bBox.top - this.HALF; - var angle = Math.atan(-dy / dx); + const bBox = this.gauge.ownerSVGElement.getBoundingClientRect(); + const dx = e.clientX - bBox.left - this.HALF; + const dy = e.clientY - bBox.top - this.HALF; + let angle = Math.atan(-dy / dx); if (isNaN(angle)) { // This shouldn't happen, but let's not let this error propagate further. return; @@ -328,29 +358,28 @@ class FieldAngle extends Blockly.FieldNumber { /** * Redraw the graph with the current angle. - * @private */ - updateGraph_() { - if (!this.gauge_) { + private updateGraph() { + if (!this.gauge) { return; } - var angleDegrees = (this.getValue() % 360) + this.OFFSET; - var angleRadians = this.toRadians(angleDegrees); - var path = ["M ", this.HALF, ",", this.HALF]; - var x2 = this.HALF; - var y2 = this.HALF; + const angleDegrees = (Number(this.getValue()) % 360) + this.OFFSET; + let angleRadians = this.toRadians(angleDegrees); + const path = ["M ", this.HALF, ",", this.HALF]; + let x2 = this.HALF; + let y2 = this.HALF; if (!isNaN(angleRadians)) { - var angle1 = this.toRadians(this.OFFSET); - var x1 = Math.cos(angle1) * this.RADIUS; - var y1 = Math.sin(angle1) * -this.RADIUS; + const angle1 = this.toRadians(this.OFFSET); + const x1 = Math.cos(angle1) * this.RADIUS; + const y1 = Math.sin(angle1) * -this.RADIUS; if (this.CLOCKWISE) { angleRadians = 2 * angle1 - angleRadians; } x2 += Math.cos(angleRadians) * this.RADIUS; y2 -= Math.sin(angleRadians) * this.RADIUS; // Use large arc only if input value is greater than wrap - var largeFlag = Math.abs(angleDegrees - this.OFFSET) > 180 ? 1 : 0; - var sweepFlag = Number(this.CLOCKWISE); + const largeFlag = Math.abs(angleDegrees - this.OFFSET) > 180 ? 1 : 0; + let sweepFlag = Number(this.CLOCKWISE); if (angleDegrees < this.OFFSET) { sweepFlag = 1 - sweepFlag; // Sweep opposite direction if less than the offset } @@ -375,29 +404,30 @@ class FieldAngle extends Blockly.FieldNumber { ); // Image rotation needs to be set in degrees + let imageRotation: number; if (this.CLOCKWISE) { - var imageRotation = angleDegrees + 2 * this.OFFSET; + imageRotation = angleDegrees + 2 * this.OFFSET; } else { - var imageRotation = -angleDegrees; + imageRotation = -angleDegrees; } - this.arrowSvg_.setAttribute("transform", "rotate(" + imageRotation + ")"); + this.arrow.setAttribute("transform", "rotate(" + imageRotation + ")"); } - this.gauge_.setAttribute("d", path.join("")); - this.line_.setAttribute("x2", x2); - this.line_.setAttribute("y2", y2); - this.handle_.setAttribute("transform", "translate(" + x2 + "," + y2 + ")"); + this.gauge.setAttribute("d", path.join("")); + this.line.setAttribute("x2", `${x2}`); + this.line.setAttribute("y2", `${y2}`); + this.handle.setAttribute("transform", "translate(" + x2 + "," + y2 + ")"); } /** * Ensure that only an angle may be entered. - * @param {string} text The user's text. - * @return {?string} A string representing a valid angle, or null if invalid. + * @param text The user's text. + * @returns A string representing a valid angle, or null if invalid. */ - doClassValidation_(text) { + doClassValidation_(text: string): number | null { if (text === null) { return null; } - var n = parseFloat(text || 0); + let n = parseFloat(text || "0"); if (isNaN(n)) { return null; } @@ -411,23 +441,37 @@ class FieldAngle extends Blockly.FieldNumber { return Number(n); } - doValueUpdate_(newValue) { + doValueUpdate_(newValue: number) { super.doValueUpdate_(newValue); - this.updateGraph_(); + this.updateGraph(); } - toDegrees(radians) { + toDegrees(radians: number) { return (radians * 180) / Math.PI; } - toRadians(degrees) { + toRadians(degrees: number) { return (degrees * Math.PI) / 180; } + + /** + * Construct a FieldAngle from a JSON arg object. + * + * @param options A JSON object with options (angle). + * @returns The new field instance. + */ + fromJson(options: ScratchFieldAngleJsonConfig): ScratchFieldAngle { + return new ScratchFieldAngle(options["angle"]); + } +} + +export interface ScratchFieldAngleJsonConfig { + angle?: number; } /** * Register the field and any dependencies. */ -export function registerFieldAngle() { - Blockly.fieldRegistry.register("field_angle", FieldAngle); +export function registerScratchFieldAngle() { + Blockly.fieldRegistry.register("field_angle", ScratchFieldAngle); } diff --git a/src/fields/field_dropdown.js b/src/fields/scratch_field_dropdown.ts similarity index 64% rename from src/fields/field_dropdown.js rename to src/fields/scratch_field_dropdown.ts index ff8869fb82..d0a13d2ad1 100644 --- a/src/fields/field_dropdown.js +++ b/src/fields/scratch_field_dropdown.ts @@ -6,12 +6,12 @@ import * as Blockly from "blockly/core"; -class FieldDropdown extends Blockly.FieldDropdown { - originalStyle; +class ScratchFieldDropdown extends Blockly.FieldDropdown { + private originalStyle: string; - showEditor_(event) { + showEditor_(event: PointerEvent) { super.showEditor_(event); - const sourceBlock = this.getSourceBlock(); + const sourceBlock = this.getSourceBlock() as Blockly.BlockSvg; const style = sourceBlock.style; if (sourceBlock.isShadow()) { this.originalStyle = sourceBlock.getStyleName(); @@ -19,7 +19,9 @@ class FieldDropdown extends Blockly.FieldDropdown { } else if (this.borderRect_) { this.borderRect_.setAttribute( "fill", - style.colourQuaternary ?? style.colourTertiary + "colourQuaternary" in style + ? `${style.colourQuaternary}` + : style.colourTertiary ); } } @@ -36,7 +38,7 @@ class FieldDropdown extends Blockly.FieldDropdown { /** * Register the field and any dependencies. */ -export function registerFieldDropdown() { +export function registerScratchFieldDropdown() { Blockly.fieldRegistry.unregister("field_dropdown"); - Blockly.fieldRegistry.register("field_dropdown", FieldDropdown); + Blockly.fieldRegistry.register("field_dropdown", ScratchFieldDropdown); } diff --git a/src/fields/field_number.js b/src/fields/scratch_field_number.ts similarity index 77% rename from src/fields/field_number.js rename to src/fields/scratch_field_number.ts index 8f829434eb..79e1c155a5 100644 --- a/src/fields/field_number.js +++ b/src/fields/scratch_field_number.ts @@ -23,7 +23,7 @@ * @author tmickel@mit.edu (Tim Mickel) */ import * as Blockly from "blockly/core"; -import { Colours } from "../colours.js"; +import { Colours } from "../colours"; /** * Class for an editable number field. @@ -45,7 +45,10 @@ import { Colours } from "../colours.js"; * @extends {Blockly.FieldTextInput} * @constructor */ -class FieldNumberPicker extends Blockly.FieldTextInput { +class ScratchFieldNumber extends Blockly.FieldTextInput { + private negativeAllowed_ = true; + private decimalAllowed_ = true; + private exponentialAllowed_ = true; /** * Fixed width of the num-pad drop-down, in px. * @type {number} @@ -96,7 +99,7 @@ class FieldNumberPicker extends Blockly.FieldTextInput { Colours.numPadText + '"/>'; - configure_(config) { + configure_(config: Blockly.FieldNumberFromJsonConfig) { super.configure_(config); this.decimalAllowed_ = typeof config.precision == "undefined" || @@ -114,7 +117,7 @@ class FieldNumberPicker extends Blockly.FieldTextInput { * @return {!RegExp} Regular expression for this FieldNumber's restrictor. */ getNumRestrictor() { - var pattern = "[\\d]"; // Always allow digits. + let pattern = "[\\d]"; // Always allow digits. if (this.decimalAllowed_) { pattern += "|[\\.]"; } @@ -130,11 +133,10 @@ class FieldNumberPicker extends Blockly.FieldTextInput { /** * Show the inline free-text editor on top of the text and the num-pad if * appropriate. - * @private */ - showEditor_(e) { + showEditor_(e: PointerEvent) { // Do not focus on mobile devices so we can show the num-pad - var showNumPad = e && e.pointerType === "touch"; + const showNumPad = e && e.pointerType === "touch"; super.showEditor_(e, showNumPad); // Show a numeric keypad in the drop-down on touch @@ -144,7 +146,7 @@ class FieldNumberPicker extends Blockly.FieldTextInput { } } - onHtmlInputKeyDown_(e) { + onHtmlInputKeyDown_(e: KeyboardEvent) { super.onHtmlInputKeyDown_(e); // key can be things like "Backspace", so only validate when it represents a single // character so as to allow non-textual input to work as normal. @@ -158,10 +160,9 @@ class FieldNumberPicker extends Blockly.FieldTextInput { /** * Show the number pad. - * @private */ - showNumPad_() { - var contentDiv = Blockly.DropDownDiv.getContentDiv(); + private showNumPad_() { + const contentDiv = Blockly.DropDownDiv.getContentDiv(); // Accessibility properties contentDiv.setAttribute("role", "menu"); @@ -170,36 +171,37 @@ class FieldNumberPicker extends Blockly.FieldTextInput { this.addButtons_(contentDiv); // Set colour and size of drop-down + const sourceBlock = this.getSourceBlock() as Blockly.BlockSvg; Blockly.DropDownDiv.setColour( - this.sourceBlock_.parentBlock_.getColour(), - this.sourceBlock_.getColourTertiary() + sourceBlock.getParent().getColour(), + sourceBlock.getColourTertiary() ); - contentDiv.style.width = FieldNumberPicker.DROPDOWN_WIDTH + "px"; + contentDiv.style.width = ScratchFieldNumber.DROPDOWN_WIDTH + "px"; this.position_(); } /** * Figure out where to place the drop-down, and move it there. - * @private */ - position_() { + private position_() { // Calculate positioning for the drop-down // sourceBlock_ is the rendered shadow field input box - var scale = this.sourceBlock_.workspace.scale; - var bBox = this.sourceBlock_.getHeightWidth(); + const sourceBlock = this.getSourceBlock() as Blockly.BlockSvg; + const scale = sourceBlock.workspace.scale; + let bBox = sourceBlock.getHeightWidth(); bBox.width *= scale; bBox.height *= scale; - var position = this.getAbsoluteXY_(); + const position = this.getAbsoluteXY_(); // If we can fit it, render below the shadow block - var primaryX = position.x + bBox.width / 2; - var primaryY = position.y + bBox.height; + const primaryX = position.x + bBox.width / 2; + const primaryY = position.y + bBox.height; // If we can't fit it, render above the entire parent block - var secondaryX = primaryX; - var secondaryY = position.y; + const secondaryX = primaryX; + const secondaryY = position.y; Blockly.DropDownDiv.setBoundsElement( - this.sourceBlock_.workspace.getParentSvg().parentNode + sourceBlock.workspace.getParentSvg().parentElement ); Blockly.DropDownDiv.show( this, @@ -215,17 +217,18 @@ class FieldNumberPicker extends Blockly.FieldTextInput { /** * Add number, punctuation, and erase buttons to the numeric keypad's content * div. - * @param {Element} contentDiv The div for the numeric keypad. - * @private + * + * @param contentDiv The div for the numeric keypad. */ - addButtons_(contentDiv) { - var buttonColour = this.sourceBlock_.parentBlock_.getColour(); - var buttonBorderColour = this.sourceBlock_.parentBlock_.getColourTertiary(); + private addButtons_(contentDiv: Element) { + const sourceBlock = this.getSourceBlock() as Blockly.BlockSvg; + const buttonColour = sourceBlock.getParent().getColour(); + const buttonBorderColour = sourceBlock.getParent().getColourTertiary(); // Add numeric keypad buttons - var buttons = FieldNumberPicker.NUMPAD_BUTTONS; - for (var i = 0, buttonText; (buttonText = buttons[i]); i++) { - var button = document.createElement("button"); + const buttons = ScratchFieldNumber.NUMPAD_BUTTONS; + for (let i = 0, buttonText; (buttonText = buttons[i]); i++) { + const button = document.createElement("button"); button.setAttribute("role", "menuitem"); button.setAttribute("class", "blocklyNumPadButton"); button.setAttribute( @@ -258,7 +261,7 @@ class FieldNumberPicker extends Blockly.FieldTextInput { contentDiv.appendChild(button); } // Add erase button to the end - var eraseButton = document.createElement("button"); + const eraseButton = document.createElement("button"); eraseButton.setAttribute("role", "menuitem"); eraseButton.setAttribute("class", "blocklyNumPadButton"); eraseButton.setAttribute( @@ -272,8 +275,8 @@ class FieldNumberPicker extends Blockly.FieldTextInput { ); eraseButton.title = "Delete"; - var eraseImage = document.createElement("img"); - eraseImage.src = FieldNumberPicker.NUMPAD_DELETE_ICON; + const eraseImage = document.createElement("img"); + eraseImage.src = ScratchFieldNumber.NUMPAD_DELETE_ICON; eraseButton.appendChild(eraseImage); Blockly.browserEvents.bind( @@ -288,19 +291,20 @@ class FieldNumberPicker extends Blockly.FieldTextInput { /** * Call for when a num-pad number or punctuation button is touched. * Determine what the user is inputting and update the text field appropriately. - * @param {Event} e DOM event triggering the touch. + * + * @param e DOM event triggering the touch. */ - numPadButtonTouch(e) { + numPadButtonTouch(e: PointerEvent) { // String of the button (e.g., '7') - var spliceValue = e.target.innerText; + const spliceValue = (e.target as HTMLElement).innerText; // Old value of the text field - var oldValue = this.htmlInput_.value; + const oldValue = this.htmlInput_.value; // Determine the selected portion of the text field - var selectionStart = this.htmlInput_.selectionStart; - var selectionEnd = this.htmlInput_.selectionEnd; + const selectionStart = this.htmlInput_.selectionStart; + const selectionEnd = this.htmlInput_.selectionEnd; // Splice in the new value - var newValue = + const newValue = oldValue.slice(0, selectionStart) + spliceValue + oldValue.slice(selectionEnd); @@ -318,14 +322,15 @@ class FieldNumberPicker extends Blockly.FieldTextInput { /** * Call for when the num-pad erase button is touched. * Determine what the user is asking to erase, and erase it. - * @param {Event} e DOM event triggering the touch. + * + * @param e DOM event triggering the touch. */ - numPadEraseButtonTouch(e) { + numPadEraseButtonTouch(e: PointerEvent) { // Old value of the text field - var oldValue = this.htmlInput_.value; + const oldValue = this.htmlInput_.value; // Determine what is selected to erase (if anything) - var selectionStart = this.htmlInput_.selectionStart; - var selectionEnd = this.htmlInput_.selectionEnd; + let selectionStart = this.htmlInput_.selectionStart; + const selectionEnd = this.htmlInput_.selectionEnd; // If selection is zero-length, shift start to the left 1 character if (selectionStart == selectionEnd) { @@ -333,7 +338,7 @@ class FieldNumberPicker extends Blockly.FieldTextInput { } // Cut out selected range - var newValue = + const newValue = oldValue.slice(0, selectionStart) + oldValue.slice(selectionEnd); this.updateDisplay_(newValue, selectionStart); @@ -347,11 +352,11 @@ class FieldNumberPicker extends Blockly.FieldTextInput { /** * Update the displayed value and resize/scroll the text field as needed. - * @param {string} newValue The new text to display. - * @param {string} newSelection The new index to put the cursor - * @private + * + * @param newValue The new text to display. + * @param newSelection The new index to put the cursor */ - updateDisplay_(newValue, newSelection) { + private updateDisplay_(newValue: string, newSelection: number) { this.setEditorValue_(newValue); // Resize and scroll the text field appropriately const htmlInput = this.htmlInput_; @@ -369,12 +374,12 @@ class FieldNumberPicker extends Blockly.FieldTextInput { } } -FieldNumberPicker.prototype.DEFAULT_VALUE = ""; +ScratchFieldNumber.prototype.DEFAULT_VALUE = ""; /** * Register the field and any dependencies. */ -export function registerFieldNumber() { +export function registerScratchFieldNumber() { Blockly.fieldRegistry.unregister("field_number"); - Blockly.fieldRegistry.register("field_number", FieldNumberPicker); + Blockly.fieldRegistry.register("field_number", ScratchFieldNumber); } diff --git a/src/fields/field_variable.js b/src/fields/scratch_field_variable.ts similarity index 69% rename from src/fields/field_variable.js rename to src/fields/scratch_field_variable.ts index d3219e35f8..7166d6ad03 100644 --- a/src/fields/field_variable.js +++ b/src/fields/scratch_field_variable.ts @@ -23,24 +23,31 @@ * @author fraser@google.com (Neil Fraser) */ import * as Blockly from "blockly/core"; -import * as Constants from "../constants.js"; +import * as Constants from "../constants"; import { ScratchMsgs } from "../../msg/scratch_msgs.js"; -import { createVariable, renameVariable } from "../variables.js"; +import { createVariable, renameVariable } from "../variables"; +import type { ScratchVariableModel } from "../scratch_variable_model"; -class FieldVariable extends Blockly.FieldVariable { - originalStyle; +export class ScratchFieldVariable extends Blockly.FieldVariable { + private originalStyle: string; - constructor(varName, validator, variableTypes, defaultType, config) { + constructor( + varName: string | null | typeof Blockly.Field.SKIP_SETUP, + validator?: Blockly.FieldVariableValidator, + variableTypes?: string[], + defaultType?: string, + config?: Blockly.FieldVariableConfig + ) { super(varName, validator, variableTypes, defaultType, config); - this.menuGenerator_ = FieldVariable.dropdownCreate; + this.menuGenerator_ = ScratchFieldVariable.dropdownCreate; } initModel() { - if (!this.variable) { + if (!this.getVariable()) { const sourceBlock = this.getSourceBlock(); if (sourceBlock) { const broadcastVariable = this.initFlyoutBroadcast( - sourceBlock.workspace + sourceBlock.workspace as Blockly.WorkspaceSvg ); if (broadcastVariable) { this.doValueUpdate_(broadcastVariable.getId()); @@ -59,12 +66,14 @@ class FieldVariable extends Blockly.FieldVariable { * selected option when the workspace is refreshed. * Re-sort the broadcast messages by name, and set the field value to the id * of the variable that comes first in sorted order. - * @param {!Blockly.Workspace} workspace The flyout workspace containing the - * broadcast block. - * @return {string} The variable of type 'broadcast_msg' that comes - * first in sorted order. + * + * @param workspace The flyout workspace containing the broadcast block. + * @returns The variable of type 'broadcast_msg' that comes first in sorted + * order. */ - initFlyoutBroadcast(workspace) { + initFlyoutBroadcast( + workspace: Blockly.WorkspaceSvg + ): Blockly.IVariableModel { const broadcastVars = workspace.getVariablesOfType( Constants.BROADCAST_MESSAGE_VARIABLE_TYPE ); @@ -81,10 +90,10 @@ class FieldVariable extends Blockly.FieldVariable { /** * Return a sorted list of variable names for variable dropdown menus. * Include a special option at the end for creating a new variable name. - * @return {!Array.} Array of variable names. - * @this {Blockly.FieldVariable} + * + * @returns Array of variable names. */ - static dropdownCreate() { + static dropdownCreate(this: ScratchFieldVariable): Blockly.MenuOption[] { const options = super.dropdownCreate(); const type = this.getDefaultType(); if (type === Constants.BROADCAST_MESSAGE_VARIABLE_TYPE) { @@ -112,16 +121,17 @@ class FieldVariable extends Blockly.FieldVariable { * Special case the 'Rename variable...', 'Delete variable...', * and 'New message...' options. * In the rename case, prompt the user for a new name. - * @param {!Blockly.Menu} menu The Menu component clicked. - * @param {!Blockly.MenuItem} menuItem The MenuItem selected within menu. + * + * @param menu The Menu component clicked. + * @param menuItem The MenuItem selected within menu. */ - onItemSelected_(menu, menuItem) { + onItemSelected_(menu: Blockly.Menu, menuItem: Blockly.MenuItem) { const sourceBlock = this.getSourceBlock(); if (sourceBlock && !sourceBlock.isDeadOrDying()) { const selectedItem = menuItem.getValue(); if (selectedItem === Constants.NEW_BROADCAST_MESSAGE_ID) { createVariable( - sourceBlock.workspace, + sourceBlock.workspace as Blockly.WorkspaceSvg, (varId) => { if (varId) { this.setValue(varId); @@ -131,24 +141,33 @@ class FieldVariable extends Blockly.FieldVariable { ); return; } else if (selectedItem === Blockly.RENAME_VARIABLE_ID) { - renameVariable(sourceBlock.workspace, this.variable); + renameVariable( + sourceBlock.workspace as Blockly.WorkspaceSvg, + this.getVariable() as ScratchVariableModel + ); return; } } super.onItemSelected_(menu, menuItem); } - showEditor_(event) { + showEditor_(event: PointerEvent) { super.showEditor_(event); const sourceBlock = this.getSourceBlock(); - const style = sourceBlock.style; + const styleName = sourceBlock.getStyleName(); + const style = (sourceBlock.workspace as Blockly.WorkspaceSvg) + .getRenderer() + .getConstants() + .getBlockStyle(styleName); if (sourceBlock.isShadow()) { - this.originalStyle = sourceBlock.getStyleName(); + this.originalStyle = styleName; sourceBlock.setStyle(`${this.originalStyle}_selected`); } else if (this.borderRect_) { this.borderRect_.setAttribute( "fill", - style.colourQuaternary ?? style.colourTertiary + "colourQuaternary" in style + ? `${style.colourQuaternary}` + : style.colourTertiary ); } } @@ -165,7 +184,7 @@ class FieldVariable extends Blockly.FieldVariable { /** * Register the field and any dependencies. */ -export function registerFieldVariable() { +export function registerScratchFieldVariable() { Blockly.fieldRegistry.unregister("field_variable"); - Blockly.fieldRegistry.register("field_variable", FieldVariable); + Blockly.fieldRegistry.register("field_variable", ScratchFieldVariable); } diff --git a/src/flyout_checkbox_icon.js b/src/flyout_checkbox_icon.ts similarity index 62% rename from src/flyout_checkbox_icon.js rename to src/flyout_checkbox_icon.ts index 68c285fb5c..36d273b97a 100644 --- a/src/flyout_checkbox_icon.js +++ b/src/flyout_checkbox_icon.ts @@ -5,55 +5,51 @@ */ import * as Blockly from "blockly/core"; -import { CheckboxBubble } from "./checkbox_bubble.js"; +import { CheckboxBubble } from "./checkbox_bubble"; /** * Invisible icon that exists solely to host the corresponding checkbox bubble. - * @implements {Blockly.IIcon} - * @implements {Blockly.IHasBubble} */ -export class FlyoutCheckboxIcon { - sourceBlock; - checkboxBubble; - type = new Blockly.icons.IconType("checkbox"); +export class FlyoutCheckboxIcon implements Blockly.IIcon, Blockly.IHasBubble { + private checkboxBubble: CheckboxBubble; + private type = new Blockly.icons.IconType("checkbox"); - constructor(sourceBlock) { - this.sourceBlock = sourceBlock; + constructor(private sourceBlock: Blockly.BlockSvg) { if (this.sourceBlock.workspace.isFlyout) { this.checkboxBubble = new CheckboxBubble(this.sourceBlock); } } - getType() { + getType(): Blockly.icons.IconType { return this.type; } - getWeight() { + getWeight(): number { return -1; } - getSize() { + getSize(): Blockly.utils.Size { // Awful hack to cancel out the default padding added to icons. return new Blockly.utils.Size(-8, 0); } - isShownWhenCollapsed() { + isShownWhenCollapsed(): boolean { return false; } - isClickableInFlyout() { + isClickableInFlyout(): boolean { return false; } - bubbleIsVisible() { + bubbleIsVisible(): boolean { return this.sourceBlock.workspace.isFlyout; } - onLocationChange(blockOrigin) { + onLocationChange(blockOrigin: Blockly.utils.Coordinate) { this.checkboxBubble?.updateLocation(); } - setChecked(checked) { + setChecked(checked: boolean) { this.checkboxBubble?.setChecked(checked); } @@ -75,9 +71,9 @@ export class FlyoutCheckboxIcon { onClick() {} - async setBubbleVisible(visible) {} + async setBubbleVisible(visible: boolean) {} - initView(pointerDownListener) {} + initView(pointerDownListener: (e: PointerEvent) => void) {} } Blockly.registry.register( diff --git a/src/glows.js b/src/glows.ts similarity index 63% rename from src/glows.js rename to src/glows.ts index af5808833f..cb5ca49dfa 100644 --- a/src/glows.js +++ b/src/glows.ts @@ -1,30 +1,41 @@ +/** + * @license + * Copyright 2024 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + import * as Blockly from "blockly/core"; -import { Colours } from "./colours.js"; +import { Colours } from "./colours"; /** * Glow/unglow a stack in the workspace. - * @param {?string} id ID of block which starts the stack. - * @param {boolean} isGlowingStack Whether to glow the stack. + * + * @param id ID of block which starts the stack. + * @param isGlowingStack Whether to glow the stack. */ -export function glowStack(id, isGlowingStack) { - if (id) { - const block = - Blockly.getMainWorkspace().getBlockById(id) || - Blockly.getMainWorkspace().getFlyout().getWorkspace().getBlockById(id); - if (!block) { - throw "Tried to glow block that does not exist."; - } +export function glowStack(id: string, isGlowingStack: boolean) { + const block = (Blockly.getMainWorkspace().getBlockById(id) || + (Blockly.getMainWorkspace() as Blockly.WorkspaceSvg) + .getFlyout() + .getWorkspace() + .getBlockById(id)) as Blockly.BlockSvg; + if (!block) { + throw "Tried to glow block that does not exist."; + } - const svg = block.getSvgRoot(); - if (isGlowingStack && !svg.hasAttribute("filter")) { - svg.setAttribute("filter", "url(#blocklyStackGlowFilter)"); - } else if (!isGlowingStack && svg.hasAttribute("filter")) { - svg.removeAttribute("filter"); - } + const svg = block.getSvgRoot(); + if (isGlowingStack && !svg.hasAttribute("filter")) { + svg.setAttribute("filter", "url(#blocklyStackGlowFilter)"); + } else if (!isGlowingStack && svg.hasAttribute("filter")) { + svg.removeAttribute("filter"); } } -export function buildGlowFilter(workspace) { +/** + * Creates an SVG filter to render block glows and adds it to the DOM. + * @param workspace The workspace whose DOM the filter will be inserted in. + */ +export function buildGlowFilter(workspace: Blockly.WorkspaceSvg) { const svg = workspace.getParentSvg(); const defs = Blockly.utils.dom.createSvgElement( Blockly.utils.Svg.DEFS, diff --git a/src/index.ts b/src/index.ts index c914f058e4..eeeac8aa32 100644 --- a/src/index.ts +++ b/src/index.ts @@ -5,94 +5,93 @@ */ import * as Blockly from "blockly/core"; -import "./blocks/colour.js"; -import "./blocks/math.js"; -import "./blocks/matrix.js"; -import "./blocks/note.js"; -import "./blocks/text.js"; -import "./blocks/vertical_extensions.js"; -import "./blocks/control.js"; -import "./blocks/data.js"; -import "./blocks/event.js"; -import "./blocks/looks.js"; -import "./blocks/motion.js"; -import "./blocks/operators.js"; -import "./blocks/procedures.js"; -import "./blocks/sensing.js"; -import "./blocks/sound.js"; -import * as scratchBlocksUtils from "./scratch_blocks_utils.js"; -import * as ScratchVariables from "./variables.js"; -import "./css.js"; -import "./renderer/renderer.js"; -import * as contextMenuItems from "./context_menu_items.js"; +import "./blocks/colour"; +import "./blocks/math"; +import "./blocks/matrix"; +import "./blocks/note"; +import "./blocks/text"; +import "./blocks/vertical_extensions"; +import "./blocks/control"; +import "./blocks/data"; +import "./blocks/event"; +import "./blocks/looks"; +import "./blocks/motion"; +import "./blocks/operators"; +import "./blocks/procedures"; +import "./blocks/sensing"; +import "./blocks/sound"; +import * as scratchBlocksUtils from "./scratch_blocks_utils"; +import * as ScratchVariables from "./variables"; +import "./css"; +import "./renderer/renderer"; +import * as contextMenuItems from "./context_menu_items"; import { ContinuousToolbox, ContinuousFlyout, ContinuousMetrics, } from "@blockly/continuous-toolbox"; import { CheckableContinuousFlyout } from "./checkable_continuous_flyout.js"; -import { buildGlowFilter, glowStack } from "./glows.js"; -import { ScratchContinuousToolbox } from "./scratch_continuous_toolbox.js"; -import "./scratch_comment_icon.js"; -import "./scratch_dragger.js"; -import "./scratch_variable_map.js"; -import "./scratch_variable_model.js"; -import "./scratch_connection_checker.js"; -import "./flyout_checkbox_icon.js"; -import "./events/events_block_comment_change.js"; -import "./events/events_block_comment_collapse.js"; -import "./events/events_block_comment_create.js"; -import "./events/events_block_comment_delete.js"; -import "./events/events_block_comment_move.js"; -import "./events/events_block_comment_resize.js"; -import "./events/events_scratch_variable_create.js"; -import { buildShadowFilter } from "./shadows.js"; -import { registerFieldAngle } from "./fields/field_angle.js"; +import { buildGlowFilter, glowStack } from "./glows"; +import { ScratchContinuousToolbox } from "./scratch_continuous_toolbox"; +import "./scratch_comment_icon"; +import "./scratch_dragger"; +import "./scratch_variable_map"; +import "./scratch_variable_model"; +import "./scratch_connection_checker"; +import "./flyout_checkbox_icon"; +import "./events/events_block_comment_change"; +import "./events/events_block_comment_collapse"; +import "./events/events_block_comment_create"; +import "./events/events_block_comment_delete"; +import "./events/events_block_comment_move"; +import "./events/events_block_comment_resize"; +import "./events/events_scratch_variable_create"; +import { buildShadowFilter } from "./shadows"; +import { registerScratchFieldAngle } from "./fields/scratch_field_angle"; import { registerFieldColourSlider, FieldColourSlider, -} from "./fields/field_colour_slider.js"; -import { registerFieldDropdown } from "./fields/field_dropdown.js"; -import { registerFieldMatrix } from "./fields/field_matrix.js"; -import { registerFieldNote, FieldNote } from "./fields/field_note.js"; -import { registerFieldNumber } from "./fields/field_number.js"; -import { registerFieldTextInputRemovable } from "./fields/field_textinput_removable.js"; -import { registerFieldVariableGetter } from "./fields/field_variable_getter.js"; -import { registerFieldVariable } from "./fields/field_variable.js"; -import { registerFieldVerticalSeparator } from "./fields/field_vertical_separator.js"; -import { registerRecyclableBlockFlyoutInflater } from "./recyclable_block_flyout_inflater.js"; -import { registerScratchBlockPaster } from "./scratch_block_paster.js"; -import { registerStatusIndicatorLabelFlyoutInflater } from "./status_indicator_label_flyout_inflater.js"; -import { registerScratchContinuousCategory } from "./scratch_continuous_category.js"; +} from "./fields/field_colour_slider"; +import { registerScratchFieldDropdown } from "./fields/scratch_field_dropdown"; +import { registerFieldMatrix } from "./fields/field_matrix"; +import { registerFieldNote, FieldNote } from "./fields/field_note"; +import { registerScratchFieldNumber } from "./fields/scratch_field_number"; +import { registerFieldTextInputRemovable } from "./fields/field_textinput_removable"; +import { registerFieldVariableGetter } from "./fields/field_variable_getter"; +import { registerScratchFieldVariable } from "./fields/scratch_field_variable"; +import { registerFieldVerticalSeparator } from "./fields/field_vertical_separator"; +import { registerRecyclableBlockFlyoutInflater } from "./recyclable_block_flyout_inflater"; +import { registerScratchBlockPaster } from "./scratch_block_paster"; +import { registerStatusIndicatorLabelFlyoutInflater } from "./status_indicator_label_flyout_inflater"; +import { registerScratchContinuousCategory } from "./scratch_continuous_category"; export * from "blockly/core"; -export * from "./block_reporting.js"; -export * from "./categories.js"; -export * from "./procedures.js"; +export * from "./block_reporting"; +export * from "./procedures"; export * from "../msg/scratch_msgs.js"; -export * from "./constants.js"; +export * from "./constants"; export { glowStack }; export { scratchBlocksUtils }; export { CheckableContinuousFlyout }; export { ScratchVariables }; export { contextMenuItems }; export { FieldColourSlider, FieldNote }; -export { CheckboxBubble } from "./checkbox_bubble.js"; +export { CheckboxBubble } from "./checkbox_bubble"; export { StatusIndicatorLabel, StatusButtonState, -} from "./status_indicator_label.js"; +} from "./status_indicator_label"; export function inject(container: Element, options: Blockly.BlocklyOptions) { - registerFieldAngle(); + registerScratchFieldAngle(); registerFieldColourSlider(); - registerFieldDropdown(); + registerScratchFieldDropdown(); registerFieldMatrix(); registerFieldNote(); - registerFieldNumber(); + registerScratchFieldNumber(); registerFieldTextInputRemovable(); registerFieldVariableGetter(); - registerFieldVariable(); + registerScratchFieldVariable(); registerFieldVerticalSeparator(); registerRecyclableBlockFlyoutInflater(); registerScratchBlockPaster(); diff --git a/src/procedures.js b/src/procedures.js deleted file mode 100644 index 3f59f52318..0000000000 --- a/src/procedures.js +++ /dev/null @@ -1,425 +0,0 @@ -/** - * @license - * Visual Blocks Editor - * - * Copyright 2012 Google Inc. - * https://developers.google.com/blockly/ - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @fileoverview Utility functions for handling procedures. - * @author fraser@google.com (Neil Fraser) - */ - -import * as Blockly from "blockly/core"; -import * as Constants from "./constants.js"; -import * as scratchBlocksUtils from "../src/scratch_blocks_utils.js"; - -/** - * Find all user-created procedure definition mutations in a workspace. - * @param {!Blockly.Workspace} root Root workspace. - * @return {!Array.} Array of mutation xml elements. - * @package - */ -function allProcedureMutations(root) { - var blocks = root.getAllBlocks(); - var mutations = []; - for (var i = 0; i < blocks.length; i++) { - if (blocks[i].type == Constants.PROCEDURES_PROTOTYPE_BLOCK_TYPE) { - var mutation = blocks[i].mutationToDom(/* opt_generateShadows */ true); - if (mutation) { - mutations.push(mutation); - } - } - } - return mutations; -} - -/** - * Sorts an array of procedure definition mutations alphabetically. - * (Does not mutate the given array.) - * @param {!Array.} mutations Array of mutation xml elements. - * @return {!Array.} Sorted array of mutation xml elements. - * @private - */ -function sortProcedureMutations_(mutations) { - var newMutations = mutations.slice(); - - newMutations.sort(function (a, b) { - var procCodeA = a.getAttribute("proccode"); - var procCodeB = b.getAttribute("proccode"); - - return scratchBlocksUtils.compareStrings(procCodeA, procCodeB); - }); - - return newMutations; -} - -/** - * Construct the blocks required by the flyout for the procedure category. - * @param {!Blockly.Workspace} workspace The workspace containing procedures. - * @return {!Array.} Array of XML block elements. - */ -function getProceduresCategory(workspace) { - var xmlList = []; - - addCreateButton_(workspace, xmlList); - - // Create call blocks for each procedure defined in the workspace - var mutations = allProcedureMutations(workspace); - mutations = sortProcedureMutations_(mutations); - for (var i = 0; i < mutations.length; i++) { - var mutation = mutations[i]; - // - // - // - var block = document.createElement("block"); - block.setAttribute("type", "procedures_call"); - block.setAttribute("gap", 16); - block.appendChild(mutation); - xmlList.push(block); - } - return xmlList; -} - -/** - * Create the "Make a Block..." button. - * @param {!Blockly.Workspace} workspace The workspace contianing procedures. - * @param {!Array.} xmlList Array of XML block elements to add to. - * @private - */ -function addCreateButton_(workspace, xmlList) { - var button = document.createElement("button"); - var msg = Blockly.Msg.NEW_PROCEDURE; - var callbackKey = "CREATE_PROCEDURE"; - var callback = function () { - // Run the callback after a delay to avoid it getting captured by the React - // modal in scratch-gui and being registered as a click on the scrim that - // dismisses the dialog. - requestAnimationFrame(() => { - setTimeout(() => { - createProcedureDefCallback(workspace); - }); - }); - }; - button.setAttribute("text", msg); - button.setAttribute("callbackKey", callbackKey); - workspace.registerButtonCallback(callbackKey, callback); - xmlList.push(button); -} - -/** - * Find all callers of a named procedure. - * @param {string} name Name of procedure (procCode in scratch-blocks). - * @param {!Blockly.Workspace} ws The workspace to find callers in. - * @param {!Blockly.Block} definitionRoot The root of the stack where the - * procedure is defined. - * @param {boolean} allowRecursive True if the search should include recursive - * procedure calls. False if the search should ignore the stack starting - * with definitionRoot. - * @return {!Array.} Array of caller blocks. - * @package - */ -function getCallers(name, ws, definitionRoot, allowRecursive) { - var allBlocks = []; - var topBlocks = ws.getTopBlocks(); - - // Start by deciding which stacks to investigate. - for (var i = 0; i < topBlocks.length; i++) { - var block = topBlocks[i]; - if (block.id == definitionRoot.id && !allowRecursive) { - continue; - } - allBlocks.push.apply(allBlocks, block.getDescendants(false)); - } - - var callers = []; - for (var i = 0; i < allBlocks.length; i++) { - var block = allBlocks[i]; - if (block.type == Constants.PROCEDURES_CALL_BLOCK_TYPE) { - var procCode = block.getProcCode(); - if (procCode && procCode == name) { - callers.push(block); - } - } - } - return callers; -} - -/** - * Find and edit all callers with a procCode using a new mutation. - * @param {string} name Name of procedure (procCode in scratch-blocks). - * @param {!Blockly.Workspace} ws The workspace to find callers in. - * @param {!Element} mutation New mutation for the callers. - * @package - */ -function mutateCallersAndPrototype(name, ws, mutation) { - var defineBlock = getDefineBlock(name, ws); - var prototypeBlock = getPrototypeBlock(name, ws); - if (defineBlock && prototypeBlock) { - var callers = getCallers( - name, - defineBlock.workspace, - defineBlock, - true /* allowRecursive */ - ); - callers.push(prototypeBlock); - Blockly.Events.setGroup(true); - for (var i = 0, caller; (caller = callers[i]); i++) { - var oldMutationDom = caller.mutationToDom(); - var oldMutation = oldMutationDom && Blockly.Xml.domToText(oldMutationDom); - caller.domToMutation(mutation); - var newMutationDom = caller.mutationToDom(); - var newMutation = newMutationDom && Blockly.Xml.domToText(newMutationDom); - if (oldMutation != newMutation) { - Blockly.Events.fire( - new Blockly.Events.BlockChange( - caller, - "mutation", - null, - oldMutation, - newMutation - ) - ); - } - } - Blockly.Events.setGroup(false); - } else { - alert("No define block on workspace"); // TODO decide what to do about this. - } -} - -/** - * Find the definition block for the named procedure. - * @param {string} procCode The identifier of the procedure. - * @param {!Blockly.Workspace} workspace The workspace to search. - * @return {Blockly.Block} The procedure definition block, or null not found. - * @package - */ -function getDefineBlock(procCode, workspace) { - // Assume that a procedure definition is a top block. - var blocks = workspace.getTopBlocks(false); - for (var i = 0; i < blocks.length; i++) { - if (blocks[i].type == Constants.PROCEDURES_DEFINITION_BLOCK_TYPE) { - var prototypeBlock = blocks[i] - .getInput("custom_block") - .connection.targetBlock(); - if ( - prototypeBlock.getProcCode && - prototypeBlock.getProcCode() == procCode - ) { - return blocks[i]; - } - } - } - return null; -} - -/** - * Find the prototype block for the named procedure. - * @param {string} procCode The identifier of the procedure. - * @param {!Blockly.Workspace} workspace The workspace to search. - * @return {Blockly.Block} The procedure prototype block, or null not found. - * @package - */ -function getPrototypeBlock(procCode, workspace) { - var defineBlock = getDefineBlock(procCode, workspace); - if (defineBlock) { - return defineBlock.getInput("custom_block").connection.targetBlock(); - } - return null; -} - -/** - * Create a mutation for a brand new custom procedure. - * @return {Element} The mutation for a new custom procedure - * @package - */ -function newProcedureMutation() { - var mutationText = - "" + - "' + - "" + - ""; - return Blockly.utils.xml.textToDom(mutationText).firstChild; -} - -/** - * Callback to create a new procedure custom command block. - * @param {!Blockly.Workspace} workspace The workspace to create the new procedure on. - * @private - */ -function createProcedureDefCallback(workspace) { - ScratchProcedures.externalProcedureDefCallback( - newProcedureMutation(), - createProcedureCallbackFactory_(workspace) - ); -} - -/** - * Callback factory for adding a new custom procedure from a mutation. - * @param {!Blockly.Workspace} workspace The workspace to create the new procedure on. - * @return {function(?Element)} callback for creating the new custom procedure. - * @private - */ -function createProcedureCallbackFactory_(workspace) { - return function (mutation) { - if (mutation) { - var blockText = - "" + - '' + - '' + - '' + - Blockly.Xml.domToText(mutation) + - "" + - "" + - "" + - ""; - var blockDom = Blockly.utils.xml.textToDom(blockText).firstChild; - Blockly.Events.setGroup(true); - var block = Blockly.Xml.domToBlock(blockDom, workspace); - Blockly.renderManagement.finishQueuedRenders().then(() => { - var scale = workspace.scale; // To convert from pixel units to workspace units - // Position the block so that it is at the top left of the visible workspace, - // padded from the edge by 30 units. Position in the top right if RTL. - var posX = -workspace.scrollX; - if (workspace.RTL) { - posX += workspace.getMetrics().contentWidth - 30; - } else { - posX += 30; - } - block.moveBy(posX / scale, (-workspace.scrollY + 30) / scale); - block.scheduleSnapAndBump(); - Blockly.Events.setGroup(false); - }); - } - }; -} - -/** - * Callback to open the modal for editing custom procedures. - * @param {!Blockly.Block} block The block that was right-clicked. - * @private - */ -function editProcedureCallback_(block) { - // Edit can come from one of three block types (call, define, prototype) - // Normalize by setting the block to the prototype block for the procedure. - if (block.type == Constants.PROCEDURES_DEFINITION_BLOCK_TYPE) { - var input = block.getInput("custom_block"); - if (!input) { - alert("Bad input"); // TODO: Decide what to do about this. - return; - } - var conn = input.connection; - if (!conn) { - alert("Bad connection"); // TODO: Decide what to do about this. - return; - } - var innerBlock = conn.targetBlock(); - if ( - !innerBlock || - !innerBlock.type == Constants.PROCEDURES_PROTOTYPE_BLOCK_TYPE - ) { - alert("Bad inner block"); // TODO: Decide what to do about this. - return; - } - block = innerBlock; - } else if (block.type == Constants.PROCEDURES_CALL_BLOCK_TYPE) { - // This is a call block, find the prototype corresponding to the procCode. - // Make sure to search the correct workspace, call block can be in flyout. - var workspaceToSearch = block.workspace.isFlyout - ? block.workspace.targetWorkspace - : block.workspace; - block = getPrototypeBlock(block.getProcCode(), workspaceToSearch); - } - // Block now refers to the procedure prototype block, it is safe to proceed. - ScratchProcedures.externalProcedureDefCallback( - block.mutationToDom(), - editProcedureCallbackFactory_(block) - ); -} - -/** - * Callback factory for editing an existing custom procedure. - * @param {!Blockly.Block} block The procedure prototype block being edited. - * @return {function(?Element)} Callback for editing the custom procedure. - * @private - */ -function editProcedureCallbackFactory_(block) { - return function (mutation) { - if (mutation) { - mutateCallersAndPrototype(block.getProcCode(), block.workspace, mutation); - } - }; -} - -/** - * Make a context menu option for editing a custom procedure. - * This appears in the context menu for procedure definitions and procedure - * calls. - * @param {!Blockly.BlockSvg} block The block where the right-click originated. - * @return {!Object} A menu option, containing text, enabled, and a callback. - * @package - */ -function makeEditOption(block) { - var editOption = { - enabled: true, - text: Blockly.Msg.EDIT_PROCEDURE, - callback: function () { - editProcedureCallback_(block); - }, - }; - return editOption; -} - -/** - * Callback to try to delete a custom block definitions. - * @param {string} procCode The identifier of the procedure to delete. - * @param {!Blockly.Block} definitionRoot The root block of the stack that - * defines the custom procedure. - * @return {boolean} True if the custom procedure was deleted, false otherwise. - * @package - */ -function deleteProcedureDefCallback(procCode, definitionRoot) { - const callers = getCallers( - procCode, - definitionRoot.workspace, - definitionRoot, - false /* allowRecursive */ - ); - if (callers.length > 0) { - return false; - } - - const workspace = definitionRoot.workspace; - Blockly.BlockSvg.prototype.checkAndDelete.call(definitionRoot); - return true; -} - -const ScratchProcedures = { - externalProcedureDefCallback: null, - createProcedureDefCallback, - deleteProcedureDefCallback, - getProceduresCategory, - makeEditOption, -}; -export { ScratchProcedures }; diff --git a/src/procedures.ts b/src/procedures.ts new file mode 100644 index 0000000000..3098fa3a45 --- /dev/null +++ b/src/procedures.ts @@ -0,0 +1,462 @@ +/** + * @license + * Visual Blocks Editor + * + * Copyright 2012 Google Inc. + * https://developers.google.com/blockly/ + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @fileoverview Utility functions for handling procedures. + * @author fraser@google.com (Neil Fraser) + */ + +import * as Blockly from "blockly/core"; +import * as Constants from "./constants"; +import * as scratchBlocksUtils from "../src/scratch_blocks_utils"; + +/** + * Find all user-created procedure definition mutations in a workspace. + * @param root Root workspace. + * @return Array of mutation xml elements. + */ +function allProcedureMutations(root: Blockly.WorkspaceSvg): Element[] { + const blocks = root.getAllBlocks(); + return blocks + .filter((b) => b.type === Constants.PROCEDURES_PROTOTYPE_BLOCK_TYPE) + .map((b) => b.mutationToDom(/* opt_generateShadows */ true)); +} + +/** + * Sorts an array of procedure definition mutations alphabetically. + * (Does not mutate the given array.) + * @param mutations Array of mutation xml elements. + * @return Sorted array of mutation xml elements. + */ +function sortProcedureMutations(mutations: Element[]): Element[] { + return mutations.slice().sort(function (a, b) { + const procCodeA = a.getAttribute("proccode"); + const procCodeB = b.getAttribute("proccode"); + + return scratchBlocksUtils.compareStrings(procCodeA, procCodeB); + }); +} + +/** + * Construct the blocks required by the flyout for the procedure category. + * @param workspace The workspace containing procedures. + * @return Array of XML block elements. + */ +function getProceduresCategory(workspace: Blockly.WorkspaceSvg): Element[] { + var xmlList: Element[] = []; + + addCreateButton(workspace, xmlList); + + // Create call blocks for each procedure defined in the workspace + const mutations = sortProcedureMutations(allProcedureMutations(workspace)); + for (const mutation of mutations) { + // + // + // + const block = document.createElement("block"); + block.setAttribute("type", "procedures_call"); + block.setAttribute("gap", "16"); + block.appendChild(mutation); + xmlList.push(block); + } + return xmlList; +} + +/** + * Create the "Make a Block..." button. + * @param workspace The workspace containing procedures. + * @param xmlList Array of XML block elements to add to. + */ +function addCreateButton(workspace: Blockly.WorkspaceSvg, xmlList: Element[]) { + const button = document.createElement("button"); + const msg = Blockly.Msg.NEW_PROCEDURE; + const callbackKey = "CREATE_PROCEDURE"; + const callback = function () { + // Run the callback after a delay to avoid it getting captured by the React + // modal in scratch-gui and being registered as a click on the scrim that + // dismisses the dialog. + requestAnimationFrame(() => { + setTimeout(() => { + createProcedureDefCallback(workspace); + }); + }); + }; + button.setAttribute("text", msg); + button.setAttribute("callbackKey", callbackKey); + workspace.registerButtonCallback(callbackKey, callback); + xmlList.push(button); +} + +/** + * Find all callers of a named procedure. + * @param name Name of procedure (procCode in scratch-blocks). + * @param workspace The workspace to find callers in. + * @param definitionRoot The root of the stack where the + * procedure is defined. + * @param allowRecursive True if the search should include recursive + * procedure calls. False if the search should ignore the stack starting + * with definitionRoot. + * @return Array of caller blocks. + */ +export function getCallers( + name: string, + workspace: Blockly.WorkspaceSvg, + definitionRoot: Blockly.BlockSvg, + allowRecursive: boolean +): Blockly.BlockSvg[] { + return workspace.getTopBlocks().flatMap((block) => { + if (block.id === definitionRoot.id && !allowRecursive) { + return []; + } + + return block.getDescendants(false).filter((descendant) => { + return ( + isProcedureBlock(descendant) && + descendant.type === Constants.PROCEDURES_CALL_BLOCK_TYPE && + descendant.getProcCode() === name + ); + }); + }); +} + +/** + * Find and edit all callers with a procCode using a new mutation. + * @param name Name of procedure (procCode in scratch-blocks). + * @param workspace The workspace to find callers in. + * @param mutation New mutation for the callers. + */ +function mutateCallersAndPrototype( + name: string, + workspace: Blockly.WorkspaceSvg, + mutation: Element +) { + const defineBlock = getDefineBlock(name, workspace); + const prototypeBlock = getPrototypeBlock(name, workspace); + if (!(defineBlock && prototypeBlock)) { + alert("No define block on workspace"); // TODO decide what to do about this. + return; + } + + const callers = getCallers( + name, + defineBlock.workspace, + defineBlock, + true /* allowRecursive */ + ); + callers.push(prototypeBlock); + Blockly.Events.setGroup(true); + callers.forEach((caller) => { + const oldMutationDom = caller.mutationToDom(); + const oldMutation = oldMutationDom && Blockly.Xml.domToText(oldMutationDom); + caller.domToMutation(mutation); + const newMutationDom = caller.mutationToDom(); + const newMutation = newMutationDom && Blockly.Xml.domToText(newMutationDom); + if (oldMutation !== newMutation) { + Blockly.Events.fire( + new (Blockly.Events.get(Blockly.Events.BLOCK_CHANGE))( + caller, + "mutation", + null, + oldMutation, + newMutation + ) + ); + } + }); + Blockly.Events.setGroup(false); +} + +/** + * Find the definition block for the named procedure. + * @param procCode The identifier of the procedure. + * @param workspace The workspace to search. + * @return The procedure definition block, or undefined if not found. + */ +function getDefineBlock( + procCode: string, + workspace: Blockly.WorkspaceSvg +): Blockly.BlockSvg | undefined { + // Assume that a procedure definition is a top block. + return workspace.getTopBlocks(false).find((block) => { + if (block.type === Constants.PROCEDURES_DEFINITION_BLOCK_TYPE) { + const prototypeBlock = block + .getInput("custom_block") + .connection.targetBlock() as Blockly.BlockSvg; + return ( + isProcedureBlock(prototypeBlock) && + prototypeBlock.getProcCode() === procCode + ); + } + + return false; + }); +} + +/** + * Find the prototype block for the named procedure. + * @param procCode The identifier of the procedure. + * @param workspace The workspace to search. + * @return The procedure prototype block, or undefined if not found. + */ +function getPrototypeBlock( + procCode: string, + workspace: Blockly.WorkspaceSvg +): Blockly.BlockSvg | undefined { + const defineBlock = getDefineBlock(procCode, workspace); + if (defineBlock) { + return defineBlock + .getInput("custom_block") + .connection.targetBlock() as Blockly.BlockSvg; + } + return undefined; +} + +/** + * Create a mutation for a brand new custom procedure. + * @return The mutation for a new custom procedure + */ +function newProcedureMutation(): Element { + const mutationText = ` + + + + `; + return Blockly.utils.xml.textToDom(mutationText).firstElementChild; +} + +/** + * Callback to create a new procedure custom command block. + * @param workspace The workspace to create the new procedure on. + */ +function createProcedureDefCallback(workspace: Blockly.WorkspaceSvg) { + ScratchProcedures.externalProcedureDefCallback( + newProcedureMutation(), + createProcedureCallbackFactory(workspace) + ); +} + +/** + * Callback factory for adding a new custom procedure from a mutation. + * @param workspace The workspace to create the new procedure on. + * @return callback for creating the new custom procedure. + */ +function createProcedureCallbackFactory( + workspace: Blockly.WorkspaceSvg +): (mutation?: Element) => void { + return (mutation?: Element) => { + if (!mutation) return; + + const blockText = ` + + + + + ${Blockly.Xml.domToText(mutation)} + + + + `; + const blockDom = Blockly.utils.xml.textToDom(blockText).firstElementChild; + Blockly.Events.setGroup(true); + const block = Blockly.Xml.domToBlock( + blockDom, + workspace + ) as Blockly.BlockSvg; + Blockly.renderManagement.finishQueuedRenders().then(() => { + // To convert from pixel units to workspace units + const scale = workspace.scale; + // Position the block so that it is at the top left of the visible + // workspace, padded from the edge by 30 units. Position in the top right + // if RTL. + let posX = -workspace.scrollX; + if (workspace.RTL) { + posX += workspace.getMetrics().contentWidth - 30; + } else { + posX += 30; + } + block.moveBy(posX / scale, (-workspace.scrollY + 30) / scale); + block.scheduleSnapAndBump(); + Blockly.Events.setGroup(false); + }); + }; +} + +/** + * Callback to open the modal for editing custom procedures. + * @param block The block that was right-clicked. + */ +function editProcedureCallback(block: Blockly.BlockSvg) { + // Edit can come from one of three block types (call, define, prototype) + // Normalize by setting the block to the prototype block for the procedure. + let prototypeBlock: Blockly.BlockSvg; + if (block.type === Constants.PROCEDURES_DEFINITION_BLOCK_TYPE) { + const input = block.getInput("custom_block"); + if (!input) { + alert("Bad input"); // TODO: Decide what to do about this. + return; + } + const conn = input.connection; + if (!conn) { + alert("Bad connection"); // TODO: Decide what to do about this. + return; + } + const innerBlock = conn.targetBlock(); + if ( + !innerBlock || + innerBlock.type !== Constants.PROCEDURES_PROTOTYPE_BLOCK_TYPE + ) { + alert("Bad inner block"); // TODO: Decide what to do about this. + return; + } + prototypeBlock = innerBlock as Blockly.BlockSvg; + } else if ( + block.type === Constants.PROCEDURES_CALL_BLOCK_TYPE && + isProcedureBlock(block) + ) { + // This is a call block, find the prototype corresponding to the procCode. + // Make sure to search the correct workspace, call block can be in flyout. + const workspaceToSearch = block.workspace.isFlyout + ? block.workspace.targetWorkspace + : block.workspace; + prototypeBlock = getPrototypeBlock(block.getProcCode(), workspaceToSearch); + } else { + prototypeBlock = block; + } + // Block now refers to the procedure prototype block, it is safe to proceed. + ScratchProcedures.externalProcedureDefCallback( + prototypeBlock.mutationToDom(), + editProcedureCallbackFactory(prototypeBlock) + ); +} + +/** + * Callback factory for editing an existing custom procedure. + * @param block The procedure prototype block being edited. + * @return Callback for editing the custom procedure. + */ +function editProcedureCallbackFactory( + block: Blockly.BlockSvg +): (mutation?: Element) => void { + return (mutation?: Element) => { + if (mutation && isProcedureBlock(block)) { + mutateCallersAndPrototype(block.getProcCode(), block.workspace, mutation); + } + }; +} + +/** + * Make a context menu option for editing a custom procedure. + * This appears in the context menu for procedure definitions and procedure + * calls. + * @param block The block where the right-click originated. + * @return A menu option, containing text, enabled, and a callback. + */ +function makeEditOption( + block: Blockly.BlockSvg +): Blockly.ContextMenuRegistry.ContextMenuOption { + return { + enabled: true, + text: Blockly.Msg.EDIT_PROCEDURE, + callback: () => { + editProcedureCallback(block); + }, + scope: block, + weight: 7, + }; +} + +/** + * Callback to try to delete a custom block definitions. + * @param procCode The identifier of the procedure to delete. + * @param definitionRoot The root block of the stack that defines the custom + * procedure. + * @return True if the custom procedure was deleted, false otherwise. + */ +function deleteProcedureDefCallback( + procCode: string, + definitionRoot: Blockly.BlockSvg +): boolean { + const callers = getCallers( + procCode, + definitionRoot.workspace, + definitionRoot, + false /* allowRecursive */ + ); + if (callers.length > 0) { + return false; + } + + const workspace = definitionRoot.workspace; + // Bypass the checkAndDelete provided by the procedure block mixin + Blockly.BlockSvg.prototype.checkAndDelete.call(definitionRoot); + return true; +} + +/** + * Returns whether the given block is a procedure block and narrows its type. + * + * @param block The block to check. + * @returns True if the block is a procedure block, otherwise false. + */ +export function isProcedureBlock( + block: Blockly.BlockSvg +): block is ProcedureBlock { + return ( + block.type === Constants.PROCEDURES_CALL_BLOCK_TYPE || + block.type === Constants.PROCEDURES_DECLARATION_BLOCK_TYPE || + block.type === Constants.PROCEDURES_PROTOTYPE_BLOCK_TYPE + ); +} + +/** + * Interface for procedure blocks, which have the getProcCode method added + * through an extension. + */ +interface ProcedureBlock extends Blockly.BlockSvg { + getProcCode(): string; +} + +/** + * Type for a callback function invoked after a procedure is modified. + */ +type ProcedureDefCallback = ( + mutation: Element, + postEditCallback: (mutation?: Element) => void +) => void; + +const ScratchProcedures: { + externalProcedureDefCallback: ProcedureDefCallback | undefined; + createProcedureDefCallback: typeof createProcedureDefCallback; + deleteProcedureDefCallback: typeof deleteProcedureDefCallback; + getProceduresCategory: typeof getProceduresCategory; + makeEditOption: typeof makeEditOption; +} = { + externalProcedureDefCallback: undefined, + createProcedureDefCallback, + deleteProcedureDefCallback, + getProceduresCategory, + makeEditOption, +}; +export { ScratchProcedures }; diff --git a/src/recyclable_block_flyout_inflater.js b/src/recyclable_block_flyout_inflater.ts similarity index 68% rename from src/recyclable_block_flyout_inflater.js rename to src/recyclable_block_flyout_inflater.ts index c3add1b3ce..63dce02773 100644 --- a/src/recyclable_block_flyout_inflater.js +++ b/src/recyclable_block_flyout_inflater.ts @@ -5,7 +5,7 @@ */ import * as Blockly from "blockly/core"; -import { CheckboxBubble } from "./checkbox_bubble.js"; +import { CheckboxBubble } from "./checkbox_bubble"; /** * A block inflater that caches and reuses blocks to improve performance. @@ -13,26 +13,27 @@ import { CheckboxBubble } from "./checkbox_bubble.js"; export class RecyclableBlockFlyoutInflater extends Blockly.BlockFlyoutInflater { /** * Whether or not block recycling is enabled. - * @type {boolean} */ recyclingEnabled = true; /** * Map from block type to block instance. - * @type {Map} */ - recycledBlocks = new Map(); + recycledBlocks = new Map(); /** * Creates a block on the flyout workspace from the given block definition. * - * @param {!Object} state A JSON representation of a block to load. - * @param {!Blockly.WorkspaceSvg} flyoutWorkspace The flyout's workspace. - * @returns {!Blockly.BlockSvg} The newly created block. + * @param state A JSON representation of a block to load. + * @param flyoutWorkspace The flyout's workspace. + * @returns The newly created block. */ - load(state, flyoutWorkspace) { + load( + state: Blockly.utils.toolbox.BlockInfo, + flyoutWorkspace: Blockly.WorkspaceSvg + ): Blockly.IBoundedElement { const block = super.load(state, flyoutWorkspace); - if (block.checkboxInFlyout) { + if ("checkboxInFlyout" in block && block.checkboxInFlyout) { block.moveBy( CheckboxBubble.CHECKBOX_SIZE + CheckboxBubble.CHECKBOX_MARGIN, 0 @@ -45,19 +46,21 @@ export class RecyclableBlockFlyoutInflater extends Blockly.BlockFlyoutInflater { /** * Toggles whether or not recycling is enabled. * - * @param {boolean} enabled True if recycling should be enabled. + * @param enabled True if recycling should be enabled. */ - setRecyclingEnabled(enabled) { + setRecyclingEnabled(enabled: boolean) { this.recyclingEnabled = enabled; } /** * Creates a new block from the given block definition. * - * @param {!Object} blockDefinition The definition to create a block from. - * @returns {!Blockly.BlockSvg} The newly created block. + * @param blockDefinition The definition to create a block from. + * @returns The newly created block. */ - createBlock(blockDefinition) { + createBlock( + blockDefinition: Blockly.utils.toolbox.BlockInfo + ): Blockly.BlockSvg { const blockType = this.getTypeFromDefinition(blockDefinition); return ( this.getRecycledBlock(blockType) ?? @@ -68,15 +71,17 @@ export class RecyclableBlockFlyoutInflater extends Blockly.BlockFlyoutInflater { /** * Returns the type of a block from an XML or JSON block definition. * - * @param blockDefinition {!Object} The block definition to parse. - * @returns {string} The block type. + * @param blockDefinition The block definition to parse. + * @returns The block type. */ - getTypeFromDefinition(blockDefinition) { + getTypeFromDefinition( + blockDefinition: Blockly.utils.toolbox.BlockInfo + ): string { if (blockDefinition["blockxml"]) { const xml = typeof blockDefinition["blockxml"] === "string" ? Blockly.utils.xml.textToDom(blockDefinition["blockxml"]) - : blockDefinition["blockxml"]; + : (blockDefinition["blockxml"] as Element); return xml.getAttribute("type"); } else { return blockDefinition["type"]; @@ -88,9 +93,9 @@ export class RecyclableBlockFlyoutInflater extends Blockly.BlockFlyoutInflater { * top of the workspace. Used during large workspace swaps to limit the number * of new DOM elements we need to create. * - * @param {!Blockly.BlockSvg} block The block to recycle. + * @param block The block to recycle. */ - recycleBlock(block) { + recycleBlock(block: Blockly.BlockSvg) { const xy = block.getRelativeToSurfaceXY(); block.moveBy(-xy.x, -xy.y); this.recycledBlocks.set(block.type, block); @@ -100,11 +105,10 @@ export class RecyclableBlockFlyoutInflater extends Blockly.BlockFlyoutInflater { * Returns a block from the cache of recycled blocks with the given type, or * undefined if one cannot be found. * - * @param {string} blockType The type of the block to try to recycle. - * @returns {?Blockly.BlockSvg} The recycled block, or undefined if - * one could not be recycled. + * @param blockType The type of the block to try to recycle. + * @returns The recycled block, or undefined if one could not be recycled. */ - getRecycledBlock(blockType) { + getRecycledBlock(blockType: string): Blockly.BlockSvg | undefined { const block = this.recycledBlocks.get(blockType); this.recycledBlocks.delete(blockType); return block; @@ -113,10 +117,10 @@ export class RecyclableBlockFlyoutInflater extends Blockly.BlockFlyoutInflater { /** * Returns whether the given block can be recycled or not. * - * @param {!Blockly.BlockSvg} block The block to check for recyclability. - * @returns {boolean} True if the block can be recycled. False otherwise. + * @param block The block to check for recyclability. + * @returns True if the block can be recycled. False otherwise. */ - blockIsRecyclable(block) { + blockIsRecyclable(block: Blockly.Block): boolean { if (!this.recyclingEnabled) { return false; } @@ -144,9 +148,7 @@ export class RecyclableBlockFlyoutInflater extends Blockly.BlockFlyoutInflater { } // Check children. if (input.connection) { - const targetBlock = - /** @type {Blockly.BlockSvg} */ - (input.connection.targetBlock()); + const targetBlock = input.connection.targetBlock(); if (targetBlock && !this.blockIsRecyclable(targetBlock)) { return false; } @@ -158,9 +160,9 @@ export class RecyclableBlockFlyoutInflater extends Blockly.BlockFlyoutInflater { /** * Disposes of the provided block. * - * @param {!Blockly.BlockSvg} element The block to dispose of. + * @param element The block to dispose of. */ - disposeElement(element) { + disposeElement(element: Blockly.BlockSvg) { if (this.blockIsRecyclable(element)) { this.removeListeners(element.id); this.recycleBlock(element); @@ -173,9 +175,7 @@ export class RecyclableBlockFlyoutInflater extends Blockly.BlockFlyoutInflater { * Clears the cache of recycled blocks. */ emptyRecycledBlocks() { - this.recycledBlocks - .values() - .forEach((block) => block.dispose(false, false)); + this.recycledBlocks.forEach((block) => block.dispose(false, false)); this.recycledBlocks.clear(); } } diff --git a/src/renderer/bowler_hat.js b/src/renderer/bowler_hat.ts similarity index 83% rename from src/renderer/bowler_hat.js rename to src/renderer/bowler_hat.ts index ba435cfd70..adf8187fd3 100644 --- a/src/renderer/bowler_hat.js +++ b/src/renderer/bowler_hat.ts @@ -7,7 +7,7 @@ import * as Blockly from "blockly/core"; export class BowlerHat extends Blockly.blockRendering.Hat { - constructor(constants) { + constructor(constants: Blockly.blockRendering.ConstantProvider) { super(constants); // Calculated dynamically by computeBounds_(). this.width = 0; diff --git a/src/renderer/constants.js b/src/renderer/constants.ts similarity index 50% rename from src/renderer/constants.js rename to src/renderer/constants.ts index d6a54753e8..a8fe060d0d 100644 --- a/src/renderer/constants.js +++ b/src/renderer/constants.ts @@ -5,7 +5,6 @@ */ import * as Blockly from "blockly/core"; -import { cssVarify } from "../colours.js"; export class ConstantProvider extends Blockly.zelos.ConstantProvider { REPLACEMENT_GLOW_COLOUR = "#ffffff"; @@ -18,27 +17,42 @@ export class ConstantProvider extends Blockly.zelos.ConstantProvider { * styles contain any raw color values, corresponding CSS variables will be * created/overridden so that those colors can be dynamically referenced in * stylesheets. - * @param {!Blockly.Theme} The new theme to apply. + * + * @param theme The new theme to apply. */ - setTheme(theme) { - const root = document.querySelector(":root"); + setTheme(theme: Blockly.Theme) { + const root = document.querySelector(":root") as HTMLElement; for (const [key, colour] of Object.entries(theme.blockStyles)) { - if (typeof colour === "string") { + if (typeof colour !== "object") { const varKey = `--colour-${key}`; root.style.setProperty(varKey, colour); } else { - theme.setBlockStyle(`${key}_selected`, { - colourPrimary: colour.colourQuaternary ?? colour.colourTertiary, - colourSecondary: colour.colourQuaternary ?? colour.colourTertiary, - colourTertiary: colour.colourQuaternary ?? colour.colourTertiary, - colourQuaternary: colour.colourQuaternary ?? colour.colourTertiary, - }); + const style = { + colourPrimary: + "colourQuaternary" in colour + ? `${colour.colourQuaternary}` + : colour.colourTertiary, + colourSecondary: + "colourQuaternary" in colour + ? `${colour.colourQuaternary}` + : colour.colourTertiary, + colourTertiary: + "colourQuaternary" in colour + ? `${colour.colourQuaternary}` + : colour.colourTertiary, + colourQuaternary: + "colourQuaternary" in colour + ? `${colour.colourQuaternary}` + : colour.colourTertiary, + hat: "", + }; + theme.setBlockStyle(`${key}_selected`, style); } } super.setTheme(theme); } - createDom(svg, tagName, selector) { + createDom(svg: SVGElement, tagName: string, selector: string) { super.createDom(svg, tagName, selector); this.selectedGlowFilterId = ""; } diff --git a/src/renderer/drawer.js b/src/renderer/drawer.ts similarity index 84% rename from src/renderer/drawer.js rename to src/renderer/drawer.ts index 90b3cf3ff4..0585a22fa3 100644 --- a/src/renderer/drawer.js +++ b/src/renderer/drawer.ts @@ -5,9 +5,11 @@ */ import * as Blockly from "blockly/core"; +import type { RenderInfo } from "./render_info"; export class Drawer extends Blockly.zelos.Drawer { - drawStatementInput_(row) { + info_: RenderInfo; + drawStatementInput_(row: Blockly.blockRendering.Row) { if (this.info_.isBowlerHatBlock()) { // Bowler hat blocks have straight sides with no C-shape/indentation for // statement blocks. @@ -18,14 +20,17 @@ export class Drawer extends Blockly.zelos.Drawer { } } - drawRightSideRow_(row) { + drawRightSideRow_(row: Blockly.blockRendering.Row) { if ( this.info_.isBowlerHatBlock() && Blockly.blockRendering.Types.isSpacer(row) ) { // Multi-row bowler hat blocks are not supported, this may need // adjustment to do so. - Blockly.blockRendering.Drawer.prototype.drawRightSideRow_.call(this, row); + this.outlinePath_ += Blockly.utils.svgPaths.lineOnAxis( + "V", + row.yPos + row.height + ); } else { super.drawRightSideRow_(row); } diff --git a/src/renderer/path_object.js b/src/renderer/path_object.ts similarity index 92% rename from src/renderer/path_object.js rename to src/renderer/path_object.ts index db75409519..eb765242f6 100644 --- a/src/renderer/path_object.js +++ b/src/renderer/path_object.ts @@ -15,9 +15,9 @@ export class PathObject extends Blockly.zelos.PathObject { * Apply the stored colours to the block's path, taking into account whether * the paths belong to a shadow block. * - * @param {!Blockly.BlockSvg} block The source block. + * @param block The source block. */ - applyColour(block) { + applyColour(block: Blockly.BlockSvg) { super.applyColour(block); // These blocks are special in that, while they are technically shadow diff --git a/src/renderer/render_info.js b/src/renderer/render_info.ts similarity index 79% rename from src/renderer/render_info.js rename to src/renderer/render_info.ts index 896ed7f78f..81f1bcf033 100644 --- a/src/renderer/render_info.js +++ b/src/renderer/render_info.ts @@ -5,7 +5,7 @@ */ import * as Blockly from "blockly/core"; -import { BowlerHat } from "./bowler_hat.js"; +import { BowlerHat } from "./bowler_hat"; export class RenderInfo extends Blockly.zelos.RenderInfo { populateTopRow_() { @@ -51,11 +51,14 @@ export class RenderInfo extends Blockly.zelos.RenderInfo { Blockly.blockRendering.Types.isHat(e) ); hat.width = this.width; - this.topRow.measure(true); + this.topRow.measure(); } } - getInRowSpacing_(prev, next) { + getInRowSpacing_( + prev: Blockly.blockRendering.Measurable, + next: Blockly.blockRendering.Measurable + ): number { if ( this.isBowlerHatBlock() && ((prev && Blockly.blockRendering.Types.isHat(prev)) || @@ -68,7 +71,10 @@ export class RenderInfo extends Blockly.zelos.RenderInfo { return super.getInRowSpacing_(prev, next); } - getSpacerRowHeight_(prev, next) { + getSpacerRowHeight_( + prev: Blockly.blockRendering.Row, + next: Blockly.blockRendering.Row + ): number { if (this.isBowlerHatBlock() && prev === this.topRow) { return 0; } @@ -76,14 +82,20 @@ export class RenderInfo extends Blockly.zelos.RenderInfo { return super.getSpacerRowHeight_(prev, next); } - getElemCenterline_(row, elem) { + getElemCenterline_( + row: Blockly.blockRendering.Row, + elem: Blockly.blockRendering.Measurable + ): number { if (this.isBowlerHatBlock() && Blockly.blockRendering.Types.isField(elem)) { return row.yPos + row.height / 2; } else if ( + "isScratchExtension" in this.block_ && this.block_.isScratchExtension && Blockly.blockRendering.Types.isField(elem) && - elem.field instanceof Blockly.FieldImage && - elem.field === this.block_.inputList[0].fieldRow[0] && + (elem as Blockly.blockRendering.Field).field instanceof + Blockly.FieldImage && + (elem as Blockly.blockRendering.Field).field === + this.block_.inputList[0].fieldRow[0] && this.block_.previousConnection ) { // Vertically center the icon on extension blocks. diff --git a/src/renderer/renderer.js b/src/renderer/renderer.js deleted file mode 100644 index b26087fbda..0000000000 --- a/src/renderer/renderer.js +++ /dev/null @@ -1,74 +0,0 @@ -/** - * @license - * Copyright 2024 Google LLC - * SPDX-License-Identifier: Apache-2.0 - */ - -import * as Blockly from "blockly/core"; -import { Drawer } from "./drawer.js"; -import { RenderInfo } from "./render_info.js"; -import { ConstantProvider } from "./constants.js"; -import { PathObject } from "./path_object.js"; - -/** - * Custom renderer for Scratch-style blocks. - */ -export class ScratchRenderer extends Blockly.zelos.Renderer { - /** - * Create a new instance of the renderer's drawer. - * - * @param {!Blockly.BlockSvg} block The block to render. - * @param info {!Blockly.blockRendering.RenderInfo} An object containing all - * information needed to render this block. - * @returns {!Drawer} The drawer. - */ - makeDrawer_(block, info) { - return new Drawer(block, info); - } - - /** - * Create a new instance of the renderer's render info object. - * - * @param {!Blockly.BlockSvg} block The block to measure. - * @returns {!RenderInfo} The render info object. - */ - makeRenderInfo_(block) { - return new RenderInfo(this, block); - } - - /** - * Create a new instance of the renderer's constant provider. - * - * @returns {!ConstantProvider} The constant provider. - */ - makeConstants_() { - return new ConstantProvider(); - } - - /** - * Create a new instance of a renderer path object. - * - * @param {!SVGElement} root The root SVG element. - * @param {!Blockly.BlockStyle} style The style object to use for colouring. - * @returns {!PathObject} The renderer path object. - */ - makePathObject(root, style) { - return new PathObject(root, style, this.getConstants()); - } - - /** - * Determine whether or not to highlight a connection. - * - * @param {!Blockly.RenderedConnection} connection The connection to determine - * whether or not to highlight. - * @returns {boolean} True if we should highlight the connection. - */ - shouldHighlightConnection(connection) { - return ( - connection.type === Blockly.ConnectionType.INPUT_VALUE && - connection.getCheck()?.includes("Boolean") - ); - } -} - -Blockly.blockRendering.register("scratch", ScratchRenderer); diff --git a/src/renderer/renderer.ts b/src/renderer/renderer.ts new file mode 100644 index 0000000000..2c14613889 --- /dev/null +++ b/src/renderer/renderer.ts @@ -0,0 +1,76 @@ +/** + * @license + * Copyright 2024 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + +import * as Blockly from "blockly/core"; +import { Drawer } from "./drawer"; +import { RenderInfo } from "./render_info"; +import { ConstantProvider } from "./constants"; +import { PathObject } from "./path_object"; + +/** + * Custom renderer for Scratch-style blocks. + */ +export class ScratchRenderer extends Blockly.zelos.Renderer { + /** + * Create a new instance of the renderer's drawer. + * + * @param block The block to render. + * @param infoAn object containing all the information needed to render this + * block. + * @returns The drawer. + */ + makeDrawer_(block: Blockly.BlockSvg, info: RenderInfo): Drawer { + return new Drawer(block, info); + } + + /** + * Create a new instance of the renderer's render info object. + * + * @param block The block to measure. + * @returns The render info object. + */ + makeRenderInfo_(block: Blockly.BlockSvg): RenderInfo { + return new RenderInfo(this, block); + } + + /** + * Create a new instance of the renderer's constant provider. + * + * @returns The constant provider. + */ + makeConstants_(): ConstantProvider { + return new ConstantProvider(); + } + + /** + * Create a new instance of a renderer path object. + * + * @param root The root SVG element. + * @param style The style object to use for colouring. + * @returns The renderer path object. + */ + makePathObject( + root: SVGElement, + style: Blockly.Theme.BlockStyle + ): PathObject { + return new PathObject(root, style, this.getConstants()); + } + + /** + * Determine whether or not to highlight a connection. + * + * @param connection The connection to determine whether or not to highlight. + * @returns True if we should highlight the connection. + */ + shouldHighlightConnection(connection: Blockly.RenderedConnection): boolean { + return ( + connection.type === Blockly.ConnectionType.INPUT_VALUE && + connection.getCheck()?.includes("Boolean") + ); + } +} + +Blockly.blockRendering.register("scratch", ScratchRenderer); diff --git a/src/scratch_block_paster.js b/src/scratch_block_paster.ts similarity index 72% rename from src/scratch_block_paster.js rename to src/scratch_block_paster.ts index 7848950531..f1d88c5465 100644 --- a/src/scratch_block_paster.js +++ b/src/scratch_block_paster.ts @@ -13,14 +13,16 @@ class ScratchBlockPaster extends Blockly.clipboard.BlockPaster { /** * Deserializes the given block data onto the workspace. * - * @param {!Blockly.clipboard.BlockCopyData} copyData The serialized block - * state to create a copy of on the workspace. - * @param {!Blockly.WorkspaceSvg} workspace The workspace to paste the block - * onto. - * @param {?Blockly.utils.Coordinate} coordinate The location to paste the - * block. + * @param copyData The serialized block state to create a copy of on the + * workspace. + * @param workspace The workspace to paste the block onto. + * @param coordinate The location to paste the block. */ - paste(copyData, workspace, coordinate) { + paste( + copyData: Blockly.clipboard.BlockCopyData, + workspace: Blockly.WorkspaceSvg, + coordinate: Blockly.utils.Coordinate + ) { const block = super.paste(copyData, workspace, coordinate); if ( block?.type === "argument_reporter_boolean" || diff --git a/src/scratch_blocks_utils.js b/src/scratch_blocks_utils.js deleted file mode 100644 index 903c7b4583..0000000000 --- a/src/scratch_blocks_utils.js +++ /dev/null @@ -1,148 +0,0 @@ -/** - * @license - * Visual Blocks Editor - * - * Copyright 2018 Google Inc. - * https://developers.google.com/blockly/ - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @fileoverview Utility methods for Scratch Blocks but not Blockly. - * @author fenichel@google.com (Rachel Fenichel) - */ -import * as Blockly from "blockly/core"; - -/** - * Re-assign obscured shadow blocks new IDs to prevent collisions - * Scratch specific to help the VM handle deleting obscured shadows. - * @param {Blockly.Block} block the root block to be processed. - * @package - */ -export function changeObscuredShadowIds(block) { - var blocks = block.getDescendants(false); - for (var i = blocks.length - 1; i >= 0; i--) { - var descendant = blocks[i]; - for (var j = 0; j < descendant.inputList.length; j++) { - var connection = descendant.inputList[j].connection; - if (connection) { - var shadowDom = connection.getShadowDom(); - if (shadowDom) { - shadowDom.setAttribute("id", Blockly.utils.genUid()); - connection.setShadowDom(shadowDom); - } - } - } - } -} - -/** - * Compare strings with natural number sorting. - * @param {string} str1 First input. - * @param {string} str2 Second input. - * @return {number} -1, 0, or 1 to signify greater than, equality, or less than. - */ -export function compareStrings(str1, str2) { - return str1.localeCompare(str2, [], { - sensitivity: "base", - numeric: true, - }); -} - -/** - * Creates a callback function for a click on the "duplicate" context menu - * option in Scratch Blocks. The block is duplicated and attached to the mouse, - * which acts as though it were pressed and mid-drag. Clicking the mouse - * releases the new dragging block. - * @param {!Blockly.BlockSvg} oldBlock The block that will be duplicated. - * @param {!Event} event Event that caused the context menu to open. - * @return {Function} A callback function that duplicates the block and starts a - * drag. - * @package - */ -export function duplicateAndDragCallback(oldBlock, event) { - var isMouseEvent = - Blockly.Touch.getTouchIdentifierFromEvent(event) === "mouse"; - return function (e) { - // Give the context menu a chance to close. - setTimeout(function () { - var ws = oldBlock.workspace; - var svgRootOld = oldBlock.getSvgRoot(); - if (!svgRootOld) { - throw new Error("oldBlock is not rendered."); - } - - // Create the new block by cloning the block in the flyout (via XML). - var xml = Blockly.Xml.blockToDom(oldBlock); - // The target workspace would normally resize during domToBlock, which - // will lead to weird jumps. - // Resizing will be enabled when the drag ends. - ws.setResizesEnabled(false); - - // Disable events and manually emit events after the block has been - // positioned and has had its shadow IDs fixed (Scratch-specific). - Blockly.Events.disable(); - try { - // Using domToBlock instead of domToWorkspace means that the new block - // will be placed at position (0, 0) in main workspace units. - var newBlock = Blockly.Xml.domToBlock(xml, ws); - - // Scratch-specific: Give shadow dom new IDs to prevent duplicating on paste - changeObscuredShadowIds(newBlock); - - var svgRootNew = newBlock.getSvgRoot(); - if (!svgRootNew) { - throw new Error("newBlock is not rendered."); - } - - // The position of the old block in workspace coordinates. - var oldBlockPosWs = oldBlock.getRelativeToSurfaceXY(); - - // Place the new block as the same position as the old block. - // TODO: Offset by the difference between the mouse position and the upper - // left corner of the block. - newBlock.moveBy(oldBlockPosWs.x, oldBlockPosWs.y); - if (!isMouseEvent) { - var offsetX = ws.RTL ? -100 : 100; - var offsetY = 100; - newBlock.moveBy(offsetX, offsetY); // Just offset the block for touch. - } - } finally { - Blockly.Events.enable(); - } - if (Blockly.Events.isEnabled()) { - Blockly.Events.fire(new Blockly.Events.BlockCreate(newBlock)); - } - - if (isMouseEvent) { - // e is not a real mouseEvent/touchEvent/pointerEvent. It's an event - // created by the context menu and has the coordinates of the mouse - // click that opened the context menu. - var fakeEvent = { - clientX: event.clientX, - clientY: event.clientY, - type: "mousedown", - preventDefault: function () { - e.preventDefault(); - }, - stopPropagation: function () { - e.stopPropagation(); - }, - target: e.target, - }; - ws.startDragWithFakeEvent(fakeEvent, newBlock); - } - }, 0); - }; -} diff --git a/src/scratch_blocks_utils.ts b/src/scratch_blocks_utils.ts new file mode 100644 index 0000000000..12528fc963 --- /dev/null +++ b/src/scratch_blocks_utils.ts @@ -0,0 +1,39 @@ +/** + * @license + * Visual Blocks Editor + * + * Copyright 2018 Google Inc. + * https://developers.google.com/blockly/ + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @fileoverview Utility methods for Scratch Blocks but not Blockly. + * @author fenichel@google.com (Rachel Fenichel) + */ +import * as Blockly from "blockly/core"; + +/** + * Compare strings with natural number sorting. + * + * @param str1 First input. + * @param str2 Second input. + * @returns -1, 0, or 1 to signify greater than, equality, or less than. + */ +export function compareStrings(str1: string, str2: string): number { + return str1.localeCompare(str2, [], { + sensitivity: "base", + numeric: true, + }); +} diff --git a/src/scratch_comment_icon.js b/src/scratch_comment_icon.ts similarity index 74% rename from src/scratch_comment_icon.js rename to src/scratch_comment_icon.ts index a67589e2f4..df04ea0ed9 100644 --- a/src/scratch_comment_icon.js +++ b/src/scratch_comment_icon.ts @@ -7,15 +7,32 @@ import * as Blockly from "blockly/core"; import { ScratchCommentBubble } from "./scratch_comment_bubble.js"; +interface CommentState { + text: string; + height: number; + width: number; + x: number; + y: number; + collapsed: boolean; +} + /** * Custom comment icon that draws no icon indicator, used for block comments. - * @implements {IHasBubble} - * @implements {ISerializable} */ -class ScratchCommentIcon extends Blockly.icons.Icon { - constructor(sourceBlock) { +class ScratchCommentIcon + extends Blockly.icons.Icon + implements Blockly.ISerializable, Blockly.IHasBubble +{ + private commentBubble: ScratchCommentBubble; + private onTextChangedListener: (oldText: string, newText: string) => void; + private onSizeChangedListener: ( + oldSize: Blockly.utils.Size, + newSize: Blockly.utils.Size + ) => void; + private onCollapseListener: (collapsed: boolean) => void; + + constructor(protected sourceBlock: Blockly.BlockSvg) { super(sourceBlock); - this.sourceBlock = sourceBlock; this.commentBubble = new ScratchCommentBubble(this.sourceBlock); Blockly.Events.fire( new (Blockly.Events.get("block_comment_create"))(this.commentBubble) @@ -28,28 +45,28 @@ class ScratchCommentIcon extends Blockly.icons.Icon { this.commentBubble.addOnCollapseListener(this.onCollapseListener); } - getType() { + getType(): Blockly.icons.IconType { return Blockly.icons.IconType.COMMENT; } - initView(pointerDownListener) { + initView(pointerDownListener: (e: PointerEvent) => void) { // Scratch comments have no indicator icon on the block. return; } - getSize() { + getSize(): Blockly.utils.Size { // Awful hack to cancel out the default padding added to icons. return new Blockly.utils.Size(-8, 0); } - getAnchorPoint() { + getAnchorPoint(): Blockly.utils.Coordinate { const blockRect = this.sourceBlock.getBoundingRectangleWithoutChildren(); const y = blockRect.top + this.offsetInBlock.y; const x = this.sourceBlock.workspace.RTL ? blockRect.left : blockRect.right; return new Blockly.utils.Coordinate(x, y); } - onLocationChange(blockOrigin) { + onLocationChange(blockOrigin: Blockly.utils.Coordinate) { if (!this.sourceBlock || !this.commentBubble) return; if (this.sourceBlock.isInsertionMarker()) { @@ -70,15 +87,15 @@ class ScratchCommentIcon extends Blockly.icons.Icon { ); } - setText(text) { + setText(text: string) { this.commentBubble?.setText(text); } - getText() { + getText(): string { return this.commentBubble?.getText() ?? ""; } - onTextChanged(oldText, newText) { + onTextChanged(oldText: string, newText: string) { Blockly.Events.fire( new (Blockly.Events.get(Blockly.Events.BLOCK_CHANGE))( this.sourceBlock, @@ -97,7 +114,7 @@ class ScratchCommentIcon extends Blockly.icons.Icon { ); } - onCollapsed(collapsed) { + onCollapsed(collapsed: boolean) { Blockly.Events.fire( new (Blockly.Events.get("block_comment_collapse"))( this.commentBubble, @@ -106,7 +123,7 @@ class ScratchCommentIcon extends Blockly.icons.Icon { ); } - onSizeChanged(oldSize, newSize) { + onSizeChanged(oldSize: Blockly.utils.Size, newSize: Blockly.utils.Size) { Blockly.Events.fire( new (Blockly.Events.get("block_comment_resize"))( this.commentBubble, @@ -116,15 +133,15 @@ class ScratchCommentIcon extends Blockly.icons.Icon { ); } - setBubbleSize(size) { + setBubbleSize(size: Blockly.utils.Size) { this.commentBubble?.setSize(size); } - getBubbleSize() { + getBubbleSize(): Blockly.utils.Size { return this.commentBubble?.getSize() ?? new Blockly.utils.Size(0, 0); } - setBubbleLocation(newLocation) { + setBubbleLocation(newLocation: Blockly.utils.Coordinate) { const oldLocation = this.getBubbleLocation(); this.commentBubble?.moveTo(newLocation); Blockly.Events.fire( @@ -136,11 +153,11 @@ class ScratchCommentIcon extends Blockly.icons.Icon { ); } - getBubbleLocation() { + getBubbleLocation(): Blockly.utils.Coordinate { return this.commentBubble?.getRelativeToSurfaceXY(); } - saveState() { + saveState(): CommentState | null { if (!this.commentBubble) return null; const size = this.getBubbleSize(); @@ -159,7 +176,8 @@ class ScratchCommentIcon extends Blockly.icons.Icon { }; } - loadState(state) { + loadState(state: CommentState) { + Blockly.Events.setGroup(true); this.setText(state["text"]); this.setBubbleSize(new Blockly.utils.Size(state["width"], state["height"])); const delta = new Blockly.utils.Coordinate(state["x"], state["y"]); @@ -169,20 +187,19 @@ class ScratchCommentIcon extends Blockly.icons.Icon { ); this.commentBubble.moveTo(newBubbleLocation); this.commentBubble.setCollapsed(state["collapsed"]); + Blockly.Events.setGroup(false); } - bubbleIsVisible() { + bubbleIsVisible(): boolean { return true; } - async setBubbleVisible(visible) { + async setBubbleVisible(visible: boolean) { this.commentBubble.setCollapsed(!visible); } dispose() { - this.commentBubble?.dispose(); - this.commentBubble = null; - this.sourceBlock = null; + this.commentBubble.dispose(); super.dispose(); } } diff --git a/src/scratch_connection_checker.js b/src/scratch_connection_checker.js deleted file mode 100644 index ec5988e8af..0000000000 --- a/src/scratch_connection_checker.js +++ /dev/null @@ -1,29 +0,0 @@ -/** - * @license - * Copyright 2024 Google LLC - * SPDX-License-Identifier: Apache-2.0 - */ - -import * as Blockly from "blockly/core"; - -class ScratchConnectionChecker extends Blockly.ConnectionChecker { - // This check prevents dragging a block into the slot occupied by the - // procedure caller example block in a procedure definition block. - doDragChecks(a, b, distance) { - if ( - b.getSourceBlock().type === "procedures_definition" && - b.getParentInput()?.name === "custom_block" - ) { - return false; - } - - return super.doDragChecks(a, b, distance); - } -} - -Blockly.registry.register( - Blockly.registry.Type.CONNECTION_CHECKER, - Blockly.registry.DEFAULT, - ScratchConnectionChecker, - true -); diff --git a/src/scratch_connection_checker.ts b/src/scratch_connection_checker.ts new file mode 100644 index 0000000000..e36e0adbd8 --- /dev/null +++ b/src/scratch_connection_checker.ts @@ -0,0 +1,44 @@ +/** + * @license + * Copyright 2024 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + +import * as Blockly from "blockly/core"; + +/** + * Custom connection checker to restrict which blocks can be connected. + */ +class ScratchConnectionChecker extends Blockly.ConnectionChecker { + /** + * Returns whether or not the two connections should be allowed to connect. + * + * @param a One of the connections to check. + * @param b The other connection to check. + * @param distance The maximum allowable distance between connections. + * @returns True if the connections should be allowed to connect. + */ + doDragChecks( + a: Blockly.RenderedConnection, + b: Blockly.RenderedConnection, + distance: number + ): boolean { + // This check prevents dragging a block into the slot occupied by the + // procedure caller example block in a procedure definition block. + if ( + b.getSourceBlock().type === "procedures_definition" && + b.getParentInput()?.name === "custom_block" + ) { + return false; + } + + return super.doDragChecks(a, b, distance); + } +} + +Blockly.registry.register( + Blockly.registry.Type.CONNECTION_CHECKER, + Blockly.registry.DEFAULT, + ScratchConnectionChecker, + true +); diff --git a/src/scratch_continuous_category.js b/src/scratch_continuous_category.ts similarity index 71% rename from src/scratch_continuous_category.js rename to src/scratch_continuous_category.ts index 8406014357..38dfd72e56 100644 --- a/src/scratch_continuous_category.js +++ b/src/scratch_continuous_category.ts @@ -7,34 +7,41 @@ import * as Blockly from "blockly/core"; import { ContinuousCategory } from "@blockly/continuous-toolbox"; +type StatusIndicatorCategoryInfo = Blockly.utils.toolbox.CategoryInfo & { + showStatusButton?: string; +}; + +/** + * Selectable category shown in the Scratch toolbox. + */ export class ScratchContinuousCategory extends ContinuousCategory { /** * Whether this toolbox category has a status indicator button on its label * in the flyout, typically for extensions that interface with hardware * devices. - * @type {boolean} */ - showStatusButton = false; + private showStatusButton = false; /** Creates a new ScratchContinuousCategory. * - * @param {!Blockly.toolbox.CategoryInfo} toolboxItemDef A toolbox item - * definition. - * @param {!Blockly.Toolbox} parentToolbox The toolbox this category is being - * added to. - * @param {?Blockly.ICollapsibleToolboxItem} opt_parent The parent toolbox - * category, if any. + * @param toolboxItemDef A toolbox item definition. + * @param parentToolbox The toolbox this category is being added to. + * @param opt_parent The parent toolbox category, if any. */ - constructor(toolboxItemDef, parentToolbox, opt_parent) { + constructor( + toolboxItemDef: StatusIndicatorCategoryInfo, + parentToolbox: Blockly.Toolbox, + opt_parent?: Blockly.ICollapsibleToolboxItem + ) { super(toolboxItemDef, parentToolbox, opt_parent); this.showStatusButton = toolboxItemDef["showStatusButton"] === "true"; } /** * Creates a DOM element for this category's icon. - * @returns {!HTMLElement} A DOM element for this category's icon. + * @returns A DOM element for this category's icon. */ - createIconDom_() { + createIconDom_(): HTMLElement { if (this.toolboxItemDef_.iconURI) { const icon = document.createElement("img"); icon.src = this.toolboxItemDef_.iconURI; @@ -49,9 +56,9 @@ export class ScratchContinuousCategory extends ContinuousCategory { /** * Sets whether or not this category is selected. - * @param {boolean} isSelected True if this category is selected. + * @param isSelected True if this category is selected. */ - setSelected(isSelected) { + setSelected(isSelected: boolean) { super.setSelected(isSelected); // Prevent hardcoding the background color to grey. this.rowDiv_.style.backgroundColor = ""; diff --git a/src/scratch_continuous_toolbox.js b/src/scratch_continuous_toolbox.ts similarity index 72% rename from src/scratch_continuous_toolbox.js rename to src/scratch_continuous_toolbox.ts index c613eea3ad..3104191368 100644 --- a/src/scratch_continuous_toolbox.js +++ b/src/scratch_continuous_toolbox.ts @@ -6,23 +6,30 @@ import * as Blockly from "blockly/core"; import { ContinuousToolbox } from "@blockly/continuous-toolbox"; -import { ScratchContinuousCategory } from "./scratch_continuous_category.js"; +import { ScratchContinuousCategory } from "./scratch_continuous_category"; +/** + * A toolbox that displays items from all categories in one scrolling list. + */ export class ScratchContinuousToolbox extends ContinuousToolbox { - postRenderCallbacks = []; + /** + * List of functions to run after the next time the toolbox renders. + */ + private postRenderCallbacks: (() => void)[] = []; refreshSelection() { - // Intentionally a no-op, Scratch manually manages refreshing the toolbox via forceRerender(). + // Intentionally a no-op, Scratch manually manages refreshing the toolbox + // via forceRerender(). } /** * Gets the contents that should be shown in the flyout. - * @returns {!Blockly.utils.toolbox.FlyoutItemInfoArray} Flyout contents. + * + * @returns Flyout contents. */ - getInitialFlyoutContents_() { + getInitialFlyoutContents_(): Blockly.utils.toolbox.FlyoutItemInfoArray { // TODO(#211) Clean this up when the continuous toolbox plugin is updated. - /** @type {!Blockly.utils.toolbox.FlyoutItemInfoArray} */ - let contents = []; + let contents: Blockly.utils.toolbox.FlyoutItemInfoArray = []; for (const toolboxItem of this.getToolboxItems()) { if (toolboxItem instanceof ScratchContinuousCategory) { if (toolboxItem.shouldShowStatusButton()) { @@ -35,19 +42,14 @@ export class ScratchContinuousToolbox extends ContinuousToolbox { // Create a label node to go at the top of the category contents.push({ kind: "LABEL", text: toolboxItem.getName() }); } - /** - * @type {string|Blockly.utils.toolbox.FlyoutItemInfoArray| - * Blockly.utils.toolbox.FlyoutItemInfo} - */ let itemContents = toolboxItem.getContents(); // Handle custom categories (e.g. variables and functions) if (typeof itemContents === "string") { - itemContents = - /** @type {!Blockly.utils.toolbox.DynamicCategoryInfo} */ ({ - custom: itemContents, - kind: "CATEGORY", - }); + itemContents = { + custom: itemContents, + kind: "CATEGORY", + }; } contents = contents.concat(itemContents); } @@ -70,9 +72,9 @@ export class ScratchContinuousToolbox extends ContinuousToolbox { /** * Runs the specified callback after the next rerender. - * @param {!Function} A callback to run whenever the toolbox next rerenders. + * @param callback A callback to run whenever the toolbox next rerenders. */ - runAfterRerender(callback) { + runAfterRerender(callback: () => void) { this.postRenderCallbacks.push(callback); } } diff --git a/src/scratch_dragger.js b/src/scratch_dragger.ts similarity index 50% rename from src/scratch_dragger.js rename to src/scratch_dragger.ts index 0e3f885df7..bfedba5e70 100644 --- a/src/scratch_dragger.js +++ b/src/scratch_dragger.ts @@ -5,23 +5,44 @@ */ import * as Blockly from "blockly/core"; -import { BlockDragOutside } from "./events/events_block_drag_outside.js"; -import { BlockDragEnd } from "./events/events_block_drag_end.js"; +import { BlockDragOutside } from "./events/events_block_drag_outside"; +import { BlockDragEnd } from "./events/events_block_drag_end"; +import { isProcedureBlock, getCallers } from "./procedures"; +/** + * CSS class that allows the workspace to overflow its bounds when set. + */ const BOUNDLESS_CLASS = "boundless"; -class ScratchDragger extends Blockly.dragging.Dragger { - constructor(draggable, workspace) { - super(draggable, workspace); - this.draggedOutOfBounds = false; - this.originatedFromFlyout = false; - } +/** + * Class responsible for managing dragging items on the workspace. + */ +export class ScratchDragger extends Blockly.dragging.Dragger { + /** + * Whether or not the current drag location is outside of the main workspace. + */ + draggedOutOfBounds = false; + + /** + * Whether or not the current drag started from the flyout. + */ + originatedFromFlyout = false; - setDraggable(draggable) { + /** + * Sets the current item being dragged. + * + * @param draggable The item being dragged. + */ + setDraggable(draggable: Blockly.IDraggable) { this.draggable = draggable; } - onDragStart(event) { + /** + * Handles the start of a drag operation. + * + * @param event The event that triggered the drag. + */ + onDragStart(event: PointerEvent) { super.onDragStart(event); if (this.draggable instanceof Blockly.BlockSvg) { this.workspace.addClass(BOUNDLESS_CLASS); @@ -41,17 +62,28 @@ class ScratchDragger extends Blockly.dragging.Dragger { } } - onDrag(event, totalDelta) { + /** + * Handles motion during an ongoing drag operation. + * + * @param event The event that triggered this call. + * @param totalDelta The change in pointer position since the last invocation. + */ + onDrag(event: PointerEvent, totalDelta: Blockly.utils.Coordinate) { super.onDrag(event, totalDelta); this.updateOutOfBoundsState(event); } - updateOutOfBoundsState(event) { + /** + * Records whether or not the current drag is out of the workspace's bounds. + * + * @param event The event that triggered this call. + */ + updateOutOfBoundsState(event: PointerEvent) { if (this.draggable instanceof Blockly.BlockSvg) { const outOfBounds = !this.isInsideWorkspace(event); if (outOfBounds !== this.draggedOutOfBounds) { const event = new BlockDragOutside( - this.getDragRoot(this.draggable), + this.getDragRoot(this.draggable) as Blockly.BlockSvg, outOfBounds ); Blockly.Events.fire(event); @@ -60,18 +92,30 @@ class ScratchDragger extends Blockly.dragging.Dragger { } } - onDragEnd(event) { + /** + * Handles the end of a drag. + * + * @param event The event that ended the drag. + */ + onDragEnd(event: PointerEvent) { if ( this.draggable instanceof Blockly.BlockSvg && this.draggable.type === "procedures_definition" && this.wouldDeleteDraggable(event, this.draggable.getRootBlock()) ) { - const procCode = this.draggable - .getInputTargetBlock("custom_block") - .getProcCode(); - const hasCaller = this.workspace - .getBlocksByType("procedures_call") - .some((b) => b.getProcCode() === procCode); + const prototype = this.draggable + .getInput("custom_block") + .connection.targetBlock(); + const hasCaller = + prototype instanceof Blockly.BlockSvg && + isProcedureBlock(prototype) && + getCallers( + prototype.getProcCode(), + this.draggable.workspace, + this.draggable.getRootBlock(), + false + ).length > 0; + if (hasCaller) { Blockly.dialog.alert(Blockly.Msg.PROCEDURE_USED); this.draggable.revertDrag(); @@ -85,7 +129,7 @@ class ScratchDragger extends Blockly.dragging.Dragger { this.updateOutOfBoundsState(event); if (this.draggable instanceof Blockly.BlockSvg) { const event = new BlockDragEnd( - this.getDragRoot(this.draggable), + this.getDragRoot(this.draggable) as Blockly.BlockSvg, this.draggedOutOfBounds ); Blockly.Events.fire(event); @@ -95,14 +139,25 @@ class ScratchDragger extends Blockly.dragging.Dragger { // deleted. if (this.originatedFromFlyout && this.draggedOutOfBounds) { Blockly.renderManagement.finishQueuedRenders().then(() => { - this.getDragRoot(this.draggable).dispose(); + const rootBlock = this.getDragRoot(this.draggable); + if (rootBlock instanceof Blockly.BlockSvg) { + rootBlock.dispose(); + } }); } } this.workspace.removeClass(BOUNDLESS_CLASS); } - shouldReturnToStart(event, rootDraggable) { + /** + * Returns whether or not the dragged item should return to its starting + * position. + * + * @param event The drag event that triggered this check. + * @param rootDraggable The topmost item being dragged. + * @returns True if the draggable should return to its starting position. + */ + shouldReturnToStart(event: PointerEvent, rootDraggable: Blockly.IDraggable) { // If a block is dragged out of the workspace to be e.g. dropped on another // sprite, it should remain in the same place on the workspace where it was, // rather than being moved to an invisible part of the workspace. @@ -111,18 +166,32 @@ class ScratchDragger extends Blockly.dragging.Dragger { ); } - getDragRoot(block) { + /** + * Returns the root element being dragged. For shadow blocks, this is the + * parent block. + * + * @param draggable The element being dragged directly. + * @returns The element being dragged, or its parent. + */ + getDragRoot(draggable: Blockly.IDraggable) { // We can't just use getRootBlock() here because, when blocks are detached // from a stack via dragging, getRootBlock() still returns the root of that // stack. - if (block.isShadow()) { - return block.getParent(); + if (draggable instanceof Blockly.BlockSvg && draggable.isShadow()) { + return draggable.getParent(); } - return block; + return draggable; } - isInsideWorkspace(event) { + /** + * Returns whether or not the given event occurred within the bounds of the + * workspace. + * + * @param event The event to check. + * @returns True if the event occurred inside the workspace. + */ + isInsideWorkspace(event: PointerEvent) { const bounds = this.workspace.getParentSvg().getBoundingClientRect(); const workspaceRect = new Blockly.utils.Rect( bounds.top, diff --git a/src/scratch_variable_map.js b/src/scratch_variable_map.ts similarity index 87% rename from src/scratch_variable_map.js rename to src/scratch_variable_map.ts index 5b38b2aa31..41865639e5 100644 --- a/src/scratch_variable_map.js +++ b/src/scratch_variable_map.ts @@ -6,8 +6,11 @@ import * as Blockly from "blockly/core"; +/** + * Class that provides storage for variables. + */ class ScratchVariableMap extends Blockly.VariableMap { - getVariable(name, type) { + getVariable(name: string, type: string) { // Variable names in Blockly are case-insensitive, but case sensitive in // Scratch. Override the implementation to only return a variable whose name // is identical to the one requested. diff --git a/src/scratch_variable_model.js b/src/scratch_variable_model.js deleted file mode 100644 index 92284e42b8..0000000000 --- a/src/scratch_variable_model.js +++ /dev/null @@ -1,24 +0,0 @@ -/** - * @license - * Copyright 2024 Google LLC - * SPDX-License-Identifier: Apache-2.0 - */ - -import * as Blockly from "blockly/core"; - -class ScratchVariableModel extends Blockly.VariableModel { - constructor(workspace, name, type, id, isLocal, isCloud) { - super(workspace, name, type, id); - // isLocal and isCloud may not be passed when creating broadcast message - // variables, which conveniently are neither local nor cloud. - this.isLocal = !!isLocal; - this.isCloud = !!isCloud; - } -} - -Blockly.registry.register( - Blockly.registry.Type.VARIABLE_MODEL, - Blockly.registry.DEFAULT, - ScratchVariableModel, - true -); diff --git a/src/scratch_variable_model.ts b/src/scratch_variable_model.ts new file mode 100644 index 0000000000..47acfe3157 --- /dev/null +++ b/src/scratch_variable_model.ts @@ -0,0 +1,30 @@ +/** + * @license + * Copyright 2024 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + +import * as Blockly from "blockly/core"; + +/** + * Class that represents a variable with extra fields for Scratch. + */ +export class ScratchVariableModel extends Blockly.VariableModel { + constructor( + workspace: Blockly.Workspace, + name: string, + type: string, + id: string, + public isLocal = false, + public isCloud = false + ) { + super(workspace, name, type, id); + } +} + +Blockly.registry.register( + Blockly.registry.Type.VARIABLE_MODEL, + Blockly.registry.DEFAULT, + ScratchVariableModel, + true +); diff --git a/src/shadows.js b/src/shadows.ts similarity index 77% rename from src/shadows.js rename to src/shadows.ts index ea40cf1ffb..e154a4d921 100644 --- a/src/shadows.js +++ b/src/shadows.ts @@ -5,9 +5,13 @@ */ import * as Blockly from "blockly/core"; -import { Colours } from "./colours.js"; +import { Colours } from "./colours"; -export function buildShadowFilter(workspace) { +/** + * Creates an SVG filter to apply drop shadows to blocks being dragged and + * inserts it into the DOM. + */ +export function buildShadowFilter(workspace: Blockly.WorkspaceSvg) { const svg = workspace.getParentSvg(); const defs = Blockly.utils.dom.createSvgElement( Blockly.utils.Svg.DEFS, @@ -15,7 +19,7 @@ export function buildShadowFilter(workspace) { svg ); // Adjust these width/height, x/y properties to stop the shadow from clipping - var dragShadowFilter = Blockly.utils.dom.createSvgElement( + const dragShadowFilter = Blockly.utils.dom.createSvgElement( "filter", { id: "blocklyDragShadowFilter", @@ -34,7 +38,7 @@ export function buildShadowFilter(workspace) { }, dragShadowFilter ); - var componentTransfer = Blockly.utils.dom.createSvgElement( + const componentTransfer = Blockly.utils.dom.createSvgElement( "feComponentTransfer", { result: "offsetBlur" }, dragShadowFilter diff --git a/src/status_indicator_label.js b/src/status_indicator_label.ts similarity index 77% rename from src/status_indicator_label.js rename to src/status_indicator_label.ts index b09dfb37e8..62dd9ece7c 100644 --- a/src/status_indicator_label.js +++ b/src/status_indicator_label.ts @@ -33,42 +33,37 @@ import * as Blockly from "blockly/core"; export class StatusIndicatorLabel extends Blockly.FlyoutButton { /** * The ID of the Scratch extension whose status is indicated by this label. - * @type {string} */ - extensionId; + extensionId: string; /** * DOM element that displays the status indicator dot. - * @type {!SVGImageElement} */ - imageElement; + imageElement: SVGImageElement; /** * Opaque data for mouse up listener used to unbind it in dispose(). - * @type {!Blockly.browserEvents.Data} */ - mouseUpwrapper; + mouseUpWrapper: Blockly.browserEvents.Data; /** * Function to be invoked when the status indicator is clicked. - * @type {?Function} */ - static statusButtonCallback; + static statusButtonCallback: (extensionId: string) => void; /** * Creates a new StatusIndicatorLabel. * - * @param {!Blockly.WorkspaceSvg} workspace The workspace in which to place - * this header. - * @param {!Blockly.WorkspaceSvg} targetWorkspace The flyout's target - * workspace. - * @param {!Element} xml The XML specifying the header. + * @param workspace The workspace in which to place this header. + * @param targetWorkspace The flyout's target workspace. + * @param json The JSON specifying the header. */ - constructor(workspace, targetWorkspace, json, isFlyoutLabel) { - super(workspace, targetWorkspace, json, isFlyoutLabel); - /** - * @type {string} - */ + constructor( + workspace: Blockly.WorkspaceSvg, + targetWorkspace: Blockly.WorkspaceSvg, + json: Blockly.utils.toolbox.LabelInfo + ) { + super(workspace, targetWorkspace, json, true); this.extensionId = json["id"]; const heightDelta = 40 - this.height; @@ -76,7 +71,7 @@ export class StatusIndicatorLabel extends Blockly.FlyoutButton { const text = this.getSvgRoot().querySelector("text"); const previousY = Number(text.getAttribute("y")); - text.setAttribute("y", previousY + heightDelta / 2); + text.setAttribute("y", `${previousY + heightDelta / 2}`); const statusButtonWidth = 30; const marginX = 20; @@ -88,7 +83,6 @@ export class StatusIndicatorLabel extends Blockly.FlyoutButton { ? marginX - flyoutWidth + statusButtonWidth : (flyoutWidth - statusButtonWidth - marginX) / workspace.scale; - /** @type {SVGElement} */ this.imageElement = Blockly.utils.dom.createSvgElement( "image", { @@ -140,31 +134,25 @@ export class StatusIndicatorLabel extends Blockly.FlyoutButton { /** * Set the source URL of the image for the button. - * @param {?string} src New source. + * @param src New source. * @package */ - setImageSrc(src) { - if (src === null) { - // No change if null. - return; - } - this.imageSrc = src; + setImageSrc(src: string) { if (this.imageElement) { this.imageElement.setAttributeNS( "http://www.w3.org/1999/xlink", "xlink:href", - this.imageSrc || "" + src ); } } /** * Gets the extension state. Overridden externally. - * @param {string} extensionId The ID of the extension in question. - * @return {Blockly.StatusButtonState} The state of the extension. - * @public + * @param extensionId The ID of the extension in question. + * @return The state of the extension. */ - getExtensionState(extensionId) { + getExtensionState(extensionId: string): StatusButtonState { return StatusButtonState.NOT_READY; } @@ -180,7 +168,7 @@ export class StatusIndicatorLabel extends Blockly.FlyoutButton { /** * Set of available states for a status indicator. */ -export const StatusButtonState = { - READY: "ready", - NOT_READY: "not ready", -}; +export enum StatusButtonState { + READY = "ready", + NOT_READY = "not ready", +} diff --git a/src/status_indicator_label_flyout_inflater.js b/src/status_indicator_label_flyout_inflater.ts similarity index 68% rename from src/status_indicator_label_flyout_inflater.js rename to src/status_indicator_label_flyout_inflater.ts index 2ae48bc135..2b9de6584e 100644 --- a/src/status_indicator_label_flyout_inflater.js +++ b/src/status_indicator_label_flyout_inflater.ts @@ -5,7 +5,7 @@ */ import * as Blockly from "blockly/core"; -import { StatusIndicatorLabel } from "./status_indicator_label.js"; +import { StatusIndicatorLabel } from "./status_indicator_label"; /** * Flyout inflater responsible for creating status indicator labels. @@ -13,17 +13,19 @@ import { StatusIndicatorLabel } from "./status_indicator_label.js"; class StatusIndicatorLabelFlyoutInflater extends Blockly.LabelFlyoutInflater { /** * Creates a status indicator label on the flyout from the given state. - * @param {!Object} state JSON representation of a status indicator label. - * @param {!Blockly.WorkspaceSvg} flyoutWorkspace The workspace to create the + * @param state JSON representation of a status indicator label. + * @param flyoutWorkspace The workspace to create the * label on. - * @returns {!StatusIndicatorLabel} The newly created status indicator label. + * @returns The newly created status indicator label. */ - load(state, flyoutWorkspace) { + load( + state: Blockly.utils.toolbox.LabelInfo, + flyoutWorkspace: Blockly.WorkspaceSvg + ): StatusIndicatorLabel { const label = new StatusIndicatorLabel( flyoutWorkspace, flyoutWorkspace.targetWorkspace, - state, - true + state ); label.show(); return label; diff --git a/src/variables.js b/src/variables.ts similarity index 50% rename from src/variables.js rename to src/variables.ts index 20e1212362..2d27dbaf0e 100644 --- a/src/variables.js +++ b/src/variables.ts @@ -26,37 +26,59 @@ import * as Blockly from "blockly/core"; import { LIST_VARIABLE_TYPE, BROADCAST_MESSAGE_VARIABLE_TYPE, -} from "./constants.js"; +} from "./constants"; +import { ScratchVariableModel } from "./scratch_variable_model"; +import { ScratchContinuousToolbox } from "./scratch_continuous_toolbox"; +import { CheckableContinuousFlyout } from "./checkable_continuous_flyout.js"; /** - * Constant prefix to differentiate cloud variable names from other types - * of variables. + * Constant prefix to differentiate cloud variable names from other types of + * variables. * This is the \u2601 cloud unicode character followed by a space. - * @type {string} - * @package */ const CLOUD_PREFIX = "☁ "; -let prompt = null; +type PromptType = ( + message: string, + defaultValue: string, + callback: ( + variableName: string, + additionalVars: string[], + variableOptions?: { scope?: string; isCloud?: boolean } + ) => void, + title?: string, + varType?: string +) => void; -export function setPromptHandler(handler) { +let prompt: PromptType | undefined = undefined; + +/** + * Sets the handler for calls to prompt(). + * + * @param handler The new prompt function. + */ +export function setPromptHandler(handler: PromptType) { prompt = handler; } /** * Create a new variable on the given workspace. - * @param {!Blockly.Workspace} workspace The workspace on which to create the - * variable. - * @param {function(?string=)=} opt_callback An optional callback function to act - * on the id of the variable that is created from the user's input, or null - * if the change is to be aborted (cancel button or an invalid name was provided). - * @param {string} opt_type Optional type of the variable to be created, - * like 'string' or 'list'. + * + * @param workspace The workspace on which to create the variable. + * @param opt_callback An optional callback function to act on the id of the + * variable that is created from the user's input, or null if the change is + * to be aborted (cancel button or an invalid name was provided). + * @param opt_type Optional type of the variable to be created, like 'string' or + * 'list'. */ -export function createVariable(workspace, opt_callback, opt_type) { +export function createVariable( + workspace: Blockly.WorkspaceSvg, + opt_callback?: (id?: string) => void, + opt_type?: string +) { // Decide on a modal message based on the opt_type. If opt_type was not // provided, default to the original message for scalar variables. - var newMsg, modalTitle; + let newMsg, modalTitle; if (opt_type === BROADCAST_MESSAGE_VARIABLE_TYPE) { newMsg = Blockly.Msg.NEW_BROADCAST_MESSAGE_TITLE; modalTitle = Blockly.Msg.BROADCAST_MODAL_TITLE; @@ -67,29 +89,33 @@ export function createVariable(workspace, opt_callback, opt_type) { // Note: this case covers 1) scalar variables, 2) any new type of // variable not explicitly checked for above, and 3) a null or undefined // opt_type -- turns a falsey opt_type into '' - // TODO (#1251) Warn developers that they didn't provide an opt_type/provided - // a falsey opt_type + // TODO (#1251) Warn developers that they didn't provide an opt_type/ + // provided a falsey opt_type opt_type = opt_type ? opt_type : ""; newMsg = Blockly.Msg.NEW_VARIABLE_TITLE; modalTitle = Blockly.Msg.VARIABLE_MODAL_TITLE; } - var validate = nameValidator.bind(null, opt_type); + const validate = nameValidator.bind(null, opt_type); // Prompt the user to enter a name for the variable prompt( newMsg, "", - function (text, additionalVars, variableOptions) { + function ( + text: string, + additionalVars: string[], + variableOptions?: { scope?: string; isCloud?: boolean } + ) { variableOptions = variableOptions || {}; - var scope = variableOptions.scope; - var isLocal = scope === "local" || false; - var isCloud = variableOptions.isCloud || false; + const scope = variableOptions.scope; + const isLocal = scope === "local" || false; + const isCloud = variableOptions.isCloud || false; // Default to [] if additionalVars is not provided additionalVars = additionalVars || []; // Only use additionalVars for global variable creation. - var additionalVarNames = isLocal ? [] : additionalVars; + const additionalVarNames = isLocal ? [] : additionalVars; - var validatedText = validate( + const validatedText = validate( text, workspace, additionalVarNames, @@ -97,12 +123,7 @@ export function createVariable(workspace, opt_callback, opt_type) { opt_callback ); if (validatedText) { - const VariableModel = Blockly.registry.getObject( - Blockly.registry.Type.VARIABLE_MODEL, - Blockly.registry.DEFAULT, - true - ); - const variable = new VariableModel( + const variable = new ScratchVariableModel( workspace, validatedText, opt_type, @@ -115,11 +136,17 @@ export function createVariable(workspace, opt_callback, opt_type) { new (Blockly.Events.get(Blockly.Events.VAR_CREATE))(variable) ); - var flyout = workspace.isFlyout ? workspace : workspace.getFlyout(); - var variableBlockId = variable.getId(); - workspace.getToolbox()?.runAfterRerender(() => { - flyout.setCheckboxState(variableBlockId, true); - }); + const toolbox = workspace.getToolbox(); + const flyout = toolbox.getFlyout(); + const variableBlockId = variable.getId(); + if ( + toolbox instanceof ScratchContinuousToolbox && + flyout instanceof CheckableContinuousFlyout + ) { + toolbox.runAfterRerender(() => { + flyout.setCheckboxState(variableBlockId, true); + }); + } if (opt_callback) { opt_callback(variableBlockId); @@ -137,44 +164,44 @@ export function createVariable(workspace, opt_callback, opt_type) { } /** - * This function provides a common interface for variable name validation agnostic - * of type. This is so that functions like Blockly.Variables.createVariable and - * Blockly.Variables.renameVariable can call a single function (with a single - * type signature) to validate the user-provided name for a variable. - * @param {string} type The type of the variable for which the provided name - * should be validated. - * @param {string} text The user-provided text that should be validated as a - * variable name. - * @param {!Blockly.Workspace} workspace The workspace on which to validate the - * variable name. This is the workspace used to check whether the variable - * already exists. - * @param {Array} additionalVars A list of additional var names to check - * for conflicts against. - * @param {boolean} isCloud Whether the variable is a cloud variable. - * @param {function(?string=)=} opt_callback An optional function to be called on - * a pre-existing variable of the user-provided name. This function is currently - * only used for broadcast messages. - * @return {string} The validated name according to the parameters given, if - * the name is determined to be valid, or null if the name - * is determined to be invalid/in-use, and the calling function should not - * proceed with creating or renaming the variable. - * @private + * This function provides a common interface for variable name validation + * agnostic of type. This is so that functions like createVariable and + * renameVariable can call a single function (with a single type signature) to + * validate the user-provided name for a variable. + * + * @param type The type of the variable for which the provided name should be + * validated. + * @param text The user-provided text that should be validated as a variable + * name. + * @param workspace The workspace on which to validate the variable name. This + * is the workspace used to check whether the variable already exists. + * @param additionalVars A list of additional var names to check for conflicts + * against. + * @param isCloud Whether the variable is a cloud variable. + * @param opt_callback An optional function to be called on a pre-existing + * variable of the user-provided name. This function is currently only used + * for broadcast messages. + * @returns The validated name according to the parameters given, if the name is + * determined to be valid, or null if the name is determined to be invalid/ + * in-use, and the calling function should not proceed with creating or + * renaming the variable. */ function nameValidator( - type, - text, - workspace, - additionalVars, - isCloud, - opt_callback -) { - // The validators for the different variable types require slightly different arguments. - // For broadcast messages, if a broadcast message of the provided name already exists, - // the validator needs to call a function that updates the selected - // field option of the dropdown menu of the block that was used to create the new message. - // For scalar variables and lists, the validator has the same validation behavior, but needs - // to know which type of variable to check for and needs a type-specific error message - // that is displayed when a variable of the given name and type already exists. + type: string, + text: string, + workspace: Blockly.WorkspaceSvg, + additionalVars: string[], + isCloud: boolean, + opt_callback?: (id?: string) => void +): string { + // The validators for the different variable types require slightly different + // arguments. For broadcast messages, if a broadcast message of the provided + // name already exists, the validator needs to call a function that updates + // the selected field option of the dropdown menu of the block that was used + // to create the new message. For scalar variables and lists, the validator + // has the same validation behavior, but needs to know which type of variable + // to check for and needs a type-specific error message that is displayed when + // a variable of the given name and type already exists. if (type === BROADCAST_MESSAGE_VARIABLE_TYPE) { return validateBroadcastMessageName(text, workspace, opt_callback); @@ -201,21 +228,24 @@ function nameValidator( /** * Validate the given name as a broadcast message type. - * @param {string} name The name to validate - * @param {!Blockly.Workspace} workspace The workspace the name should be validated - * against. - * @param {function(?string=)=} opt_callback An optional function to call if a broadcast - * message already exists with the given name. This function will be called on the id - * of the existing variable. - * @return {string} The validated name, or null if invalid. - * @private + * + * @param name The name to validate + * @param workspace The workspace the name should be validated against. + * @param opt_callback An optional function to call if a broadcast message + * already exists with the given name. This function will be called on the + * id of the existing variable. + * @returns The validated name, or null if invalid. */ -function validateBroadcastMessageName(name, workspace, opt_callback) { +function validateBroadcastMessageName( + name: string, + workspace: Blockly.WorkspaceSvg, + opt_callback?: (id?: string) => void +): string | null { if (!name) { // no name was provided or the user cancelled the prompt return null; } - var variable = workspace.getVariable(name, BROADCAST_MESSAGE_VARIABLE_TYPE); + const variable = workspace.getVariable(name, BROADCAST_MESSAGE_VARIABLE_TYPE); if (variable) { // If the user provided a name for a broadcast message that already exists, // use the provided callback function to update the selected option in @@ -237,27 +267,26 @@ function validateBroadcastMessageName(name, workspace, opt_callback) { /** * Validate the given name as a scalar variable or list type. * This function is also responsible for any user facing error-handling. - * @param {string} name The name to validate - * @param {!Blockly.Workspace} workspace The workspace the name should be validated - * against. - * @param {Array} additionalVars A list of additional variable names to check - * for conflicts against. - * @param {boolean} isCloud Whether the variable is a cloud variable. - * @param {string} type The type to validate the variable as. This should be one of - * Blockly.SCALAR_VARIABLE_TYPE or Blockly.LIST_VARIABLE_TYPE. - * @param {string} errorMsg The type-specific error message the user should see - * if a variable of the validated, given name and type already exists. - * @return {string} The validated name, or null if invalid. - * @private + * + * @param name The name to validate + * @param workspace The workspace the name should be validated against. + * @param additionalVars A list of additional variable names to check for + * conflicts against. + * @param isCloud Whether the variable is a cloud variable. + * @param type The type to validate the variable as. This should be one of + * SCALAR_VARIABLE_TYPE or LIST_VARIABLE_TYPE. + * @param errorMsg The type-specific error message the user should see if a + * variable of the validated, given name and type already exists. + * @returns The validated name, or null if invalid. */ function validateScalarVarOrListName( - name, - workspace, - additionalVars, - isCloud, - type, - errorMsg -) { + name: string, + workspace: Blockly.WorkspaceSvg, + additionalVars: string[], + isCloud: boolean, + type: string, + errorMsg: string +): string | null { // For scalar variables, we don't want leading or trailing white space name = name.trim(); if (!name) { @@ -278,24 +307,25 @@ function validateScalarVarOrListName( /** * Rename a variable with the given workspace, variableType, and oldName. - * @param {!Blockly.Workspace} workspace The workspace on which to rename the - * variable. - * @param {Blockly.VariableModel} variable Variable to rename. - * @param {function(?string=)=} opt_callback A callback. It will - * be passed an acceptable new variable name, or null if change is to be - * aborted (cancel button), or undefined if an existing variable was chosen. + * + * @param workspace The workspace on which to rename the variable. + * @param variable Variable to rename. + * @param opt_callback A callback. It will be passed an acceptable new variable + * name, or null if change is to be aborted (cancel button), or undefined if + * an existing variable was chosen. */ -export function renameVariable(workspace, variable, opt_callback) { +export function renameVariable( + workspace: Blockly.WorkspaceSvg, + variable: ScratchVariableModel, + opt_callback?: (id?: string) => void +) { // Validation and modal message/title depends on the variable type - var promptMsg, modalTitle; - var varType = variable.type; + let promptMsg, modalTitle; + const varType = variable.getType(); if (varType === BROADCAST_MESSAGE_VARIABLE_TYPE) { console.warn( - "Unexpected attempt to rename a broadcast message with " + - "id: " + - variable.getId() + - " and name: " + - variable.name + `Unexpected attempt to rename a broadcast message with + id: "${variable.getId()} and name: ${variable.getName()}` ); return; } @@ -307,18 +337,18 @@ export function renameVariable(workspace, variable, opt_callback) { promptMsg = Blockly.Msg.RENAME_VARIABLE_TITLE; modalTitle = Blockly.Msg.RENAME_VARIABLE_MODAL_TITLE; } - var validate = nameValidator.bind(null, varType); + const validate = nameValidator.bind(null, varType); - var promptText = promptMsg.replace("%1", variable.name); - var promptDefaultText = variable.name; - if (variable.isCloud && variable.name.indexOf(CLOUD_PREFIX) == 0) { + const promptText = promptMsg.replace("%1", variable.getName()); + let promptDefaultText = variable.getName(); + if (variable.isCloud && variable.getName().indexOf(CLOUD_PREFIX) == 0) { promptDefaultText = promptDefaultText.substring(CLOUD_PREFIX.length); } prompt( promptText, promptDefaultText, - function (newName, additionalVars) { + (newName: string, additionalVars: string[]) => { if ( variable.isCloud && newName.length > 0 && @@ -328,8 +358,8 @@ export function renameVariable(workspace, variable, opt_callback) { // The name validator will add the prefix back } additionalVars = additionalVars || []; - var additionalVarNames = variable.isLocal ? [] : additionalVars; - var validatedText = validate( + const additionalVarNames = variable.isLocal ? [] : additionalVars; + const validatedText = validate( newName, workspace, additionalVarNames, @@ -352,4 +382,4 @@ export function renameVariable(workspace, variable, opt_callback) { ); } -export { getVariablesCategory } from "./data_category.js"; +export { getVariablesCategory } from "./data_category"; From 92a8a010c496569ba04ca077744582e0ab71cd93 Mon Sep 17 00:00:00 2001 From: Christopher Willis-Ford <7019101+cwillisf@users.noreply.github.com> Date: Tue, 10 Dec 2024 09:29:46 -0800 Subject: [PATCH 121/130] fix(deps): use Blockly 12 beta instead of RC --- .github/workflows/deploy.yml | 4 +- .gitignore | 3 - .npmignore | 4 - package-lock.json | 298 ++++++++++++++++------------------- package.json | 3 +- temp-use-blockly-v12-rc.sh | 26 --- tsconfig.json | 3 - 7 files changed, 137 insertions(+), 204 deletions(-) delete mode 100755 temp-use-blockly-v12-rc.sh diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 75f6b177d3..0f3931edd4 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -21,7 +21,9 @@ jobs: node-version-file: '.nvmrc' # TODO: tests - name: Install Node Dependencies - run: npm ci + # The --legacy-peer-deps flag is a TEMPORARY fix during the Blockly 12 beta. + # It should be removed once the @blockly/* packages support Blockly 12. + run: npm ci --legacy-peer-deps - name: Build run: npm run build # - name: Deploy playground to GitHub Pages diff --git a/.gitignore b/.gitignore index fb708b5c85..ca5e13595f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,3 @@ -# Temporary until Blockly v12 release -/blockly-rc/ - # OSX .DS_Store diff --git a/.npmignore b/.npmignore index 06c2e230b4..89433f5d7a 100644 --- a/.npmignore +++ b/.npmignore @@ -1,7 +1,3 @@ -# Temporary until Blockly v12 release -/blockly-rc/ -/temp-use-blockly-v12-rc.sh - # Development files /.circleci .eslintrc diff --git a/package-lock.json b/package-lock.json index fb32cefed9..78057a3b67 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,7 +11,7 @@ "dependencies": { "@blockly/continuous-toolbox": "^6.0.9", "@blockly/field-colour": "^5.0.9", - "blockly": "^11.0.0" + "blockly": "^12.0.0-beta.0" }, "devDependencies": { "@commitlint/cli": "^17.8.1", @@ -2100,12 +2100,9 @@ } }, "node_modules/agent-base": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz", - "integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==", - "dependencies": { - "debug": "^4.3.4" - }, + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.3.tgz", + "integrity": "sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw==", "engines": { "node": ">= 14" } @@ -2420,11 +2417,11 @@ } }, "node_modules/blockly": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/blockly/-/blockly-11.0.0.tgz", - "integrity": "sha512-6Ie7HuZWZLaETIVKFEP4FPDz267Pubn6+weQNZvXzqnkOYp9sKPSsPue8QIMCV9Qb5F4wYhqivgiDcZJcE1UlQ==", + "version": "12.0.0-beta.0", + "resolved": "https://registry.npmjs.org/blockly/-/blockly-12.0.0-beta.0.tgz", + "integrity": "sha512-Z9cULe95wgQGj87DQZ9RBJRu5oMLQEUTz0beZVcZL/ddVuga6qtZZ9DbaDfCvt4ffVz1O/kyNzPJ+cqvovSjGg==", "dependencies": { - "jsdom": "23.0.0" + "jsdom": "25.0.1" }, "engines": { "node": ">=18" @@ -3259,14 +3256,14 @@ } }, "node_modules/cssstyle": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-3.0.0.tgz", - "integrity": "sha512-N4u2ABATi3Qplzf0hWbVCdjenim8F3ojEXpBDF5hBpjzW182MjNGLqfmQ0SkSPeQ+V86ZXgeH8aXj6kayd4jgg==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-4.1.0.tgz", + "integrity": "sha512-h66W1URKpBS5YMI/V8PyXvTMFT8SupJ1IzoIV8IeBC/ji8WVmrO8dGlTi+2dh6whmdk6BiKJLD/ZBkhWbcg6nA==", "dependencies": { - "rrweb-cssom": "^0.6.0" + "rrweb-cssom": "^0.7.1" }, "engines": { - "node": ">=14" + "node": ">=18" } }, "node_modules/dargs": { @@ -4660,9 +4657,9 @@ } }, "node_modules/form-data": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", - "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.1.tgz", + "integrity": "sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==", "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", @@ -5323,11 +5320,11 @@ } }, "node_modules/https-proxy-agent": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.4.tgz", - "integrity": "sha512-wlwpilI7YdjSkWaQ/7omYBMTliDcmCN8OLihO6I9B86g06lMyAoqgoDpV0XqoaPOKj+0DIdAvnsWfyAAhmimcg==", + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", + "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", "dependencies": { - "agent-base": "^7.0.2", + "agent-base": "^7.1.2", "debug": "4" }, "engines": { @@ -5941,37 +5938,37 @@ } }, "node_modules/jsdom": { - "version": "23.0.0", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-23.0.0.tgz", - "integrity": "sha512-cbL/UCtohJguhFC7c2/hgW6BeZCNvP7URQGnx9tSJRYKCdnfbfWOrtuLTMfiB2VxKsx5wPHVsh/J0aBy9lIIhQ==", + "version": "25.0.1", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-25.0.1.tgz", + "integrity": "sha512-8i7LzZj7BF8uplX+ZyOlIz86V6TAsSs+np6m1kpW9u0JWi4z/1t+FzcK1aek+ybTnAC4KhBL4uXCNT0wcUIeCw==", "dependencies": { - "cssstyle": "^3.0.0", + "cssstyle": "^4.1.0", "data-urls": "^5.0.0", "decimal.js": "^10.4.3", "form-data": "^4.0.0", "html-encoding-sniffer": "^4.0.0", - "http-proxy-agent": "^7.0.0", - "https-proxy-agent": "^7.0.2", + "http-proxy-agent": "^7.0.2", + "https-proxy-agent": "^7.0.5", "is-potential-custom-element-name": "^1.0.1", - "nwsapi": "^2.2.7", + "nwsapi": "^2.2.12", "parse5": "^7.1.2", - "rrweb-cssom": "^0.6.0", + "rrweb-cssom": "^0.7.1", "saxes": "^6.0.0", "symbol-tree": "^3.2.4", - "tough-cookie": "^4.1.3", + "tough-cookie": "^5.0.0", "w3c-xmlserializer": "^5.0.0", "webidl-conversions": "^7.0.0", "whatwg-encoding": "^3.1.1", "whatwg-mimetype": "^4.0.0", "whatwg-url": "^14.0.0", - "ws": "^8.14.2", + "ws": "^8.18.0", "xml-name-validator": "^5.0.0" }, "engines": { "node": ">=18" }, "peerDependencies": { - "canvas": "^3.0.0" + "canvas": "^2.11.2" }, "peerDependenciesMeta": { "canvas": { @@ -9848,9 +9845,9 @@ "license": "ISC" }, "node_modules/nwsapi": { - "version": "2.2.9", - "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.9.tgz", - "integrity": "sha512-2f3F0SEEer8bBu0dsNCFF50N0cTThV1nWFYcEYFZttdW0lDAoybv9cQoK7X7/68Z89S7FoRrVjP1LPX4XRf9vg==" + "version": "2.2.16", + "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.16.tgz", + "integrity": "sha512-F1I/bimDpj3ncaNDhfyMWuFqmQDBwDB0Fogc2qpL3BWvkQteFD/8BzWuIRl83rq0DXfm8SGt/HFhLXZyljTXcQ==" }, "node_modules/object-assign": { "version": "4.1.1", @@ -10106,11 +10103,11 @@ } }, "node_modules/parse5": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz", - "integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==", + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.2.1.tgz", + "integrity": "sha512-BuBYQYlv1ckiPdQi/ohiivi9Sagc9JG+Ozs0r7b/0iK3sKmrb0b9FdWdBbOdx6hBCM/F9Ir82ofnBhtZOjCRPQ==", "dependencies": { - "entities": "^4.4.0" + "entities": "^4.5.0" }, "funding": { "url": "https://github.com/inikulin/parse5?sponsor=1" @@ -10373,11 +10370,6 @@ "integrity": "sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==", "dev": true }, - "node_modules/psl": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", - "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==" - }, "node_modules/punycode": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", @@ -10412,11 +10404,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/querystringify": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", - "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==" - }, "node_modules/queue-microtask": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", @@ -10716,7 +10703,8 @@ "node_modules/requires-port": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", - "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==" + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", + "dev": true }, "node_modules/resolve": { "version": "1.22.8", @@ -10837,9 +10825,9 @@ } }, "node_modules/rrweb-cssom": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.6.0.tgz", - "integrity": "sha512-APM0Gt1KoXBz0iIkkdB/kfvGOwC4UuJFeG/c+yV7wSc7q96cG/kJ0HiYCnzivD9SB53cLV1MlHFNfOuPaadYSw==" + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.7.1.tgz", + "integrity": "sha512-TrEMa7JGdVm0UThDJSx7ddw5nVm3UJS9o9CCIZ72B1vSyEZoziDqBYP3XIoi/12lKrJR8rE3jeFHMok2F/Mnsg==" }, "node_modules/run-async": { "version": "2.4.1", @@ -15420,6 +15408,22 @@ "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==", "dev": true }, + "node_modules/tldts": { + "version": "6.1.66", + "resolved": "https://registry.npmjs.org/tldts/-/tldts-6.1.66.tgz", + "integrity": "sha512-l3ciXsYFel/jSRfESbyKYud1nOw7WfhrBEF9I3UiarYk/qEaOOwu3qXNECHw4fHGHGTEOuhf/VdKgoDX5M/dhQ==", + "dependencies": { + "tldts-core": "^6.1.66" + }, + "bin": { + "tldts": "bin/cli.js" + } + }, + "node_modules/tldts-core": { + "version": "6.1.66", + "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-6.1.66.tgz", + "integrity": "sha512-s07jJruSwndD2X8bVjwioPfqpIc1pDTzszPe9pL1Skbh4bjytL85KNQ3tolqLbCvpQHawIsGfFi9dgerWjqW4g==" + }, "node_modules/tmp": { "version": "0.0.33", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", @@ -15454,17 +15458,14 @@ } }, "node_modules/tough-cookie": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.4.tgz", - "integrity": "sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-5.0.0.tgz", + "integrity": "sha512-FRKsF7cz96xIIeMZ82ehjC3xW2E+O2+v11udrDYewUbszngYhsGa8z6YUMMzO9QJZzzyd0nGGXnML/TReX6W8Q==", "dependencies": { - "psl": "^1.1.33", - "punycode": "^2.1.1", - "universalify": "^0.2.0", - "url-parse": "^1.5.3" + "tldts": "^6.1.32" }, "engines": { - "node": ">=6" + "node": ">=16" } }, "node_modules/tr46": { @@ -15689,14 +15690,6 @@ "integrity": "sha512-yCzhz6FN2wU1NiiQRogkTQszlQSlpWaw8SvVegAc+bDxbzHgh1vX8uIe8OYyMH6DwH+sdTJsgMl36+mSMdRJIQ==", "dev": true }, - "node_modules/universalify": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", - "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==", - "engines": { - "node": ">= 4.0.0" - } - }, "node_modules/unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", @@ -15754,15 +15747,6 @@ "node": "^12.20.0 || ^14.13.1 || >=16.0.0" } }, - "node_modules/url-parse": { - "version": "1.5.10", - "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", - "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", - "dependencies": { - "querystringify": "^2.1.1", - "requires-port": "^1.0.0" - } - }, "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", @@ -16210,9 +16194,9 @@ } }, "node_modules/whatwg-url": { - "version": "14.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-14.0.0.tgz", - "integrity": "sha512-1lfMEm2IEr7RIV+f4lUNPOqfFL+pO+Xw3fJSqmjX9AbXcXcYOkCe1P6+9VBZB6n94af16NfZf+sSk0JCBZC9aw==", + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-14.1.0.tgz", + "integrity": "sha512-jlf/foYIKywAt3x/XWKZ/3rz8OSJPiWktjmk891alJUEjiVxKX9LEO92qH3hv4aJ0mN3MWPvGMCy8jQi95xK4w==", "dependencies": { "tr46": "^5.0.0", "webidl-conversions": "^7.0.0" @@ -16293,9 +16277,9 @@ } }, "node_modules/ws": { - "version": "8.15.1", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.15.1.tgz", - "integrity": "sha512-W5OZiCjXEmk0yZ66ZN82beM5Sz7l7coYxpRkzS+p9PP+ToQry8szKh+61eNktr7EA9DOwvFGhfC605jDHbP6QQ==", + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", + "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", "engines": { "node": ">=10.0.0" }, @@ -18039,12 +18023,9 @@ "dev": true }, "agent-base": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz", - "integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==", - "requires": { - "debug": "^4.3.4" - } + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.3.tgz", + "integrity": "sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw==" }, "aggregate-error": { "version": "5.0.0", @@ -18286,11 +18267,11 @@ "dev": true }, "blockly": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/blockly/-/blockly-11.0.0.tgz", - "integrity": "sha512-6Ie7HuZWZLaETIVKFEP4FPDz267Pubn6+weQNZvXzqnkOYp9sKPSsPue8QIMCV9Qb5F4wYhqivgiDcZJcE1UlQ==", + "version": "12.0.0-beta.0", + "resolved": "https://registry.npmjs.org/blockly/-/blockly-12.0.0-beta.0.tgz", + "integrity": "sha512-Z9cULe95wgQGj87DQZ9RBJRu5oMLQEUTz0beZVcZL/ddVuga6qtZZ9DbaDfCvt4ffVz1O/kyNzPJ+cqvovSjGg==", "requires": { - "jsdom": "23.0.0" + "jsdom": "25.0.1" } }, "body-parser": { @@ -18913,11 +18894,11 @@ } }, "cssstyle": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-3.0.0.tgz", - "integrity": "sha512-N4u2ABATi3Qplzf0hWbVCdjenim8F3ojEXpBDF5hBpjzW182MjNGLqfmQ0SkSPeQ+V86ZXgeH8aXj6kayd4jgg==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-4.1.0.tgz", + "integrity": "sha512-h66W1URKpBS5YMI/V8PyXvTMFT8SupJ1IzoIV8IeBC/ji8WVmrO8dGlTi+2dh6whmdk6BiKJLD/ZBkhWbcg6nA==", "requires": { - "rrweb-cssom": "^0.6.0" + "rrweb-cssom": "^0.7.1" } }, "dargs": { @@ -19989,9 +19970,9 @@ "dev": true }, "form-data": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", - "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.1.tgz", + "integrity": "sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==", "requires": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", @@ -20501,11 +20482,11 @@ } }, "https-proxy-agent": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.4.tgz", - "integrity": "sha512-wlwpilI7YdjSkWaQ/7omYBMTliDcmCN8OLihO6I9B86g06lMyAoqgoDpV0XqoaPOKj+0DIdAvnsWfyAAhmimcg==", + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", + "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", "requires": { - "agent-base": "^7.0.2", + "agent-base": "^7.1.2", "debug": "4" } }, @@ -20947,30 +20928,30 @@ } }, "jsdom": { - "version": "23.0.0", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-23.0.0.tgz", - "integrity": "sha512-cbL/UCtohJguhFC7c2/hgW6BeZCNvP7URQGnx9tSJRYKCdnfbfWOrtuLTMfiB2VxKsx5wPHVsh/J0aBy9lIIhQ==", + "version": "25.0.1", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-25.0.1.tgz", + "integrity": "sha512-8i7LzZj7BF8uplX+ZyOlIz86V6TAsSs+np6m1kpW9u0JWi4z/1t+FzcK1aek+ybTnAC4KhBL4uXCNT0wcUIeCw==", "requires": { - "cssstyle": "^3.0.0", + "cssstyle": "^4.1.0", "data-urls": "^5.0.0", "decimal.js": "^10.4.3", "form-data": "^4.0.0", "html-encoding-sniffer": "^4.0.0", - "http-proxy-agent": "^7.0.0", - "https-proxy-agent": "^7.0.2", + "http-proxy-agent": "^7.0.2", + "https-proxy-agent": "^7.0.5", "is-potential-custom-element-name": "^1.0.1", - "nwsapi": "^2.2.7", + "nwsapi": "^2.2.12", "parse5": "^7.1.2", - "rrweb-cssom": "^0.6.0", + "rrweb-cssom": "^0.7.1", "saxes": "^6.0.0", "symbol-tree": "^3.2.4", - "tough-cookie": "^4.1.3", + "tough-cookie": "^5.0.0", "w3c-xmlserializer": "^5.0.0", "webidl-conversions": "^7.0.0", "whatwg-encoding": "^3.1.1", "whatwg-mimetype": "^4.0.0", "whatwg-url": "^14.0.0", - "ws": "^8.14.2", + "ws": "^8.18.0", "xml-name-validator": "^5.0.0" } }, @@ -23669,9 +23650,9 @@ } }, "nwsapi": { - "version": "2.2.9", - "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.9.tgz", - "integrity": "sha512-2f3F0SEEer8bBu0dsNCFF50N0cTThV1nWFYcEYFZttdW0lDAoybv9cQoK7X7/68Z89S7FoRrVjP1LPX4XRf9vg==" + "version": "2.2.16", + "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.16.tgz", + "integrity": "sha512-F1I/bimDpj3ncaNDhfyMWuFqmQDBwDB0Fogc2qpL3BWvkQteFD/8BzWuIRl83rq0DXfm8SGt/HFhLXZyljTXcQ==" }, "object-assign": { "version": "4.1.1", @@ -23844,11 +23825,11 @@ } }, "parse5": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz", - "integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==", + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.2.1.tgz", + "integrity": "sha512-BuBYQYlv1ckiPdQi/ohiivi9Sagc9JG+Ozs0r7b/0iK3sKmrb0b9FdWdBbOdx6hBCM/F9Ir82ofnBhtZOjCRPQ==", "requires": { - "entities": "^4.4.0" + "entities": "^4.5.0" } }, "parseurl": { @@ -24041,11 +24022,6 @@ "integrity": "sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==", "dev": true }, - "psl": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", - "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==" - }, "punycode": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", @@ -24066,11 +24042,6 @@ "side-channel": "^1.0.4" } }, - "querystringify": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", - "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==" - }, "queue-microtask": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", @@ -24298,7 +24269,8 @@ "requires-port": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", - "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==" + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", + "dev": true }, "resolve": { "version": "1.22.8", @@ -24384,9 +24356,9 @@ } }, "rrweb-cssom": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.6.0.tgz", - "integrity": "sha512-APM0Gt1KoXBz0iIkkdB/kfvGOwC4UuJFeG/c+yV7wSc7q96cG/kJ0HiYCnzivD9SB53cLV1MlHFNfOuPaadYSw==" + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.7.1.tgz", + "integrity": "sha512-TrEMa7JGdVm0UThDJSx7ddw5nVm3UJS9o9CCIZ72B1vSyEZoziDqBYP3XIoi/12lKrJR8rE3jeFHMok2F/Mnsg==" }, "run-async": { "version": "2.4.1", @@ -27672,6 +27644,19 @@ "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==", "dev": true }, + "tldts": { + "version": "6.1.66", + "resolved": "https://registry.npmjs.org/tldts/-/tldts-6.1.66.tgz", + "integrity": "sha512-l3ciXsYFel/jSRfESbyKYud1nOw7WfhrBEF9I3UiarYk/qEaOOwu3qXNECHw4fHGHGTEOuhf/VdKgoDX5M/dhQ==", + "requires": { + "tldts-core": "^6.1.66" + } + }, + "tldts-core": { + "version": "6.1.66", + "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-6.1.66.tgz", + "integrity": "sha512-s07jJruSwndD2X8bVjwioPfqpIc1pDTzszPe9pL1Skbh4bjytL85KNQ3tolqLbCvpQHawIsGfFi9dgerWjqW4g==" + }, "tmp": { "version": "0.0.33", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", @@ -27697,14 +27682,11 @@ "dev": true }, "tough-cookie": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.4.tgz", - "integrity": "sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-5.0.0.tgz", + "integrity": "sha512-FRKsF7cz96xIIeMZ82ehjC3xW2E+O2+v11udrDYewUbszngYhsGa8z6YUMMzO9QJZzzyd0nGGXnML/TReX6W8Q==", "requires": { - "psl": "^1.1.33", - "punycode": "^2.1.1", - "universalify": "^0.2.0", - "url-parse": "^1.5.3" + "tldts": "^6.1.32" } }, "tr46": { @@ -27846,11 +27828,6 @@ "integrity": "sha512-yCzhz6FN2wU1NiiQRogkTQszlQSlpWaw8SvVegAc+bDxbzHgh1vX8uIe8OYyMH6DwH+sdTJsgMl36+mSMdRJIQ==", "dev": true }, - "universalify": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", - "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==" - }, "unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", @@ -27882,15 +27859,6 @@ "integrity": "sha512-n2huDr9h9yzd6exQVnH/jU5mr+Pfx08LRXXZhkLLetAMESRj+anQsTAh940iMrIetKAmry9coFuZQ2jY8/p3WA==", "dev": true }, - "url-parse": { - "version": "1.5.10", - "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", - "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", - "requires": { - "querystringify": "^2.1.1", - "requires-port": "^1.0.0" - } - }, "util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", @@ -28204,9 +28172,9 @@ "integrity": "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==" }, "whatwg-url": { - "version": "14.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-14.0.0.tgz", - "integrity": "sha512-1lfMEm2IEr7RIV+f4lUNPOqfFL+pO+Xw3fJSqmjX9AbXcXcYOkCe1P6+9VBZB6n94af16NfZf+sSk0JCBZC9aw==", + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-14.1.0.tgz", + "integrity": "sha512-jlf/foYIKywAt3x/XWKZ/3rz8OSJPiWktjmk891alJUEjiVxKX9LEO92qH3hv4aJ0mN3MWPvGMCy8jQi95xK4w==", "requires": { "tr46": "^5.0.0", "webidl-conversions": "^7.0.0" @@ -28266,9 +28234,9 @@ } }, "ws": { - "version": "8.15.1", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.15.1.tgz", - "integrity": "sha512-W5OZiCjXEmk0yZ66ZN82beM5Sz7l7coYxpRkzS+p9PP+ToQry8szKh+61eNktr7EA9DOwvFGhfC605jDHbP6QQ==", + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", + "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", "requires": {} }, "xml-name-validator": { diff --git a/package.json b/package.json index 68e35d14d5..cbe88b500a 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,6 @@ "scripts": { "build": "webpack --mode production", "prepare": "husky || true", - "prepublish": "./temp-use-blockly-v12-rc.sh", "start": "webpack serve --open --mode development", "test": "echo \"Error: no test specified\" && exit 1", "test:lint": "eslint ." @@ -35,7 +34,7 @@ "dependencies": { "@blockly/continuous-toolbox": "^6.0.9", "@blockly/field-colour": "^5.0.9", - "blockly": "^11.0.0" + "blockly": "^12.0.0-beta.0" }, "config": { "commitizen": { diff --git a/temp-use-blockly-v12-rc.sh b/temp-use-blockly-v12-rc.sh deleted file mode 100755 index fca0495b04..0000000000 --- a/temp-use-blockly-v12-rc.sh +++ /dev/null @@ -1,26 +0,0 @@ -#!/usr/bin/env bash -# vim: set tw=118 ts=2 sw=2 expandtab - -# This script is intended to be run from the root of the scratch-blocks repo. -# This will check out the Blockly v12 Release Candidate branch, -# build it, and link it into node_modules/ - -# TODO: Remove this script once Blockly v12 is available from https://www.npmjs.com/package/blockly - -# WARNING: This uses `npm link`, which causes system-wide changes! - -set -e -x - -if [ ! -d "blockly-rc" ]; then - git clone --branch rc/v12.0.0 --single-branch --depth 1 https://github.com/google/blockly.git blockly-rc -else - git -C blockly-rc checkout rc/v12.0.0 - git -C blockly-rc pull -fi -npm -C blockly-rc ci -npm -C blockly-rc run package - -# --legacy-peer-deps can be removed once the Blockly plugins used by scratch-blocks support Blockly v12 -# --prefer-offline speeds this up by roughly 2x on my computer (!!) -# --prefer-offline should be OK since we're probably running immediately after a non-offline `npm i` or `npm ci` -npm link --prefer-offline --legacy-peer-deps blockly-rc/dist/ diff --git a/tsconfig.json b/tsconfig.json index d7603609a0..9035b59753 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,7 +1,4 @@ { - "exclude": [ - "./blockly-rc/" - ], "compilerOptions": { "outDir": "./dist/", "noImplicitAny": true, From 3cb79f62c90647dde8f6d6d52e6d9e3c05efb98c Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Tue, 10 Dec 2024 17:46:16 +0000 Subject: [PATCH 122/130] chore(release): 2.0.0-spork.2 [skip ci] # [2.0.0-spork.2](https://github.com/scratchfoundation/scratch-blocks/compare/v2.0.0-spork.1...v2.0.0-spork.2) (2024-12-10) ### Bug Fixes * **deps:** use Blockly 12 beta instead of RC ([92a8a01](https://github.com/scratchfoundation/scratch-blocks/commit/92a8a010c496569ba04ca077744582e0ab71cd93)) --- CHANGELOG.md | 7 +++++++ package-lock.json | 4 ++-- package.json | 2 +- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ed42163ecc..ec14e62599 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,13 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [2.0.0-spork.2](https://github.com/scratchfoundation/scratch-blocks/compare/v2.0.0-spork.1...v2.0.0-spork.2) (2024-12-10) + + +### Bug Fixes + +* **deps:** use Blockly 12 beta instead of RC ([92a8a01](https://github.com/scratchfoundation/scratch-blocks/commit/92a8a010c496569ba04ca077744582e0ab71cd93)) + # [2.0.0-spork.1](https://github.com/scratchfoundation/scratch-blocks/compare/v1.1.86...v2.0.0-spork.1) (2024-10-21) diff --git a/package-lock.json b/package-lock.json index 78057a3b67..8ca6bf4607 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "scratch-blocks", - "version": "2.0.0-spork.1", + "version": "2.0.0-spork.2", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "scratch-blocks", - "version": "2.0.0-spork.1", + "version": "2.0.0-spork.2", "license": "Apache-2.0", "dependencies": { "@blockly/continuous-toolbox": "^6.0.9", diff --git a/package.json b/package.json index cbe88b500a..b7d305d587 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "scratch-blocks", - "version": "2.0.0-spork.1", + "version": "2.0.0-spork.2", "description": "Scratch Blocks is a library for building creative computing interfaces.", "author": "Massachusetts Institute of Technology", "license": "Apache-2.0", From adaf531cadf51f797cf6c33050df2380bb3cf372 Mon Sep 17 00:00:00 2001 From: Christopher Willis-Ford <7019101+cwillisf@users.noreply.github.com> Date: Tue, 10 Dec 2024 13:26:56 -0800 Subject: [PATCH 123/130] fix: rename mouseDownWrapper fields for Blockly v12 compatibility --- src/fields/field_matrix.ts | 6 +++--- src/fields/scratch_field_angle.ts | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/fields/field_matrix.ts b/src/fields/field_matrix.ts index 1ac385328c..336527af19 100644 --- a/src/fields/field_matrix.ts +++ b/src/fields/field_matrix.ts @@ -70,7 +70,7 @@ class FieldMatrix extends Blockly.Field { * Touch event wrapper. * Runs when the field is selected. */ - private mouseDownWrapper: Blockly.browserEvents.Data | null = null; + private mouseDownWrapper_: Blockly.browserEvents.Data | null = null; /** * Touch event wrapper. @@ -558,8 +558,8 @@ class FieldMatrix extends Blockly.Field { dispose() { super.dispose(); this.matrixStage_ = null; - if (this.mouseDownWrapper) { - Blockly.browserEvents.unbind(this.mouseDownWrapper); + if (this.mouseDownWrapper_) { + Blockly.browserEvents.unbind(this.mouseDownWrapper_); } if (this.matrixTouchWrapper_) { Blockly.browserEvents.unbind(this.matrixTouchWrapper_); diff --git a/src/fields/scratch_field_angle.ts b/src/fields/scratch_field_angle.ts index 749c4e2498..9a058e242d 100644 --- a/src/fields/scratch_field_angle.ts +++ b/src/fields/scratch_field_angle.ts @@ -51,7 +51,7 @@ class ScratchFieldAngle extends Blockly.FieldNumber { /** * Opaque identifier used to unbind event listener in dispose(). */ - private mouseDownWrapper: Blockly.browserEvents.Data; + private mouseDownWrapper_: Blockly.browserEvents.Data; /** * Opaque identifier used to unbind event listener in dispose(). @@ -142,8 +142,8 @@ class ScratchFieldAngle extends Blockly.FieldNumber { dispose() { super.dispose(); this.gauge = null; - if (this.mouseDownWrapper) { - Blockly.browserEvents.unbind(this.mouseDownWrapper); + if (this.mouseDownWrapper_) { + Blockly.browserEvents.unbind(this.mouseDownWrapper_); } if (this.mouseUpWrapper) { Blockly.browserEvents.unbind(this.mouseUpWrapper); @@ -286,7 +286,7 @@ class ScratchFieldAngle extends Blockly.FieldNumber { this.getSourceBlock() as Blockly.BlockSvg ); - this.mouseDownWrapper = Blockly.browserEvents.bind( + this.mouseDownWrapper_ = Blockly.browserEvents.bind( this.handle, "mousedown", this, From 51a52808cab47e0313ef68605d4f41cdaf8ff233 Mon Sep 17 00:00:00 2001 From: Christopher Willis-Ford <7019101+cwillisf@users.noreply.github.com> Date: Tue, 10 Dec 2024 13:40:38 -0800 Subject: [PATCH 124/130] build: tell TS to include only src,tests,types --- tsconfig.json | 5 +++++ continuous-toolbox.d.ts => types/continuous-toolbox.d.ts | 0 2 files changed, 5 insertions(+) rename continuous-toolbox.d.ts => types/continuous-toolbox.d.ts (100%) diff --git a/tsconfig.json b/tsconfig.json index 9035b59753..7c4e19b64d 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,4 +1,9 @@ { + "include": [ + "./src/", + "./tests/", + "./types/" + ], "compilerOptions": { "outDir": "./dist/", "noImplicitAny": true, diff --git a/continuous-toolbox.d.ts b/types/continuous-toolbox.d.ts similarity index 100% rename from continuous-toolbox.d.ts rename to types/continuous-toolbox.d.ts From 601be05661de5665cb388ff17e50c76a675eb92e Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Tue, 10 Dec 2024 21:44:48 +0000 Subject: [PATCH 125/130] chore(release): 2.0.0-spork.3 [skip ci] # [2.0.0-spork.3](https://github.com/scratchfoundation/scratch-blocks/compare/v2.0.0-spork.2...v2.0.0-spork.3) (2024-12-10) ### Bug Fixes * rename mouseDownWrapper fields for Blockly v12 compatibility ([adaf531](https://github.com/scratchfoundation/scratch-blocks/commit/adaf531cadf51f797cf6c33050df2380bb3cf372)) --- CHANGELOG.md | 7 +++++++ package-lock.json | 4 ++-- package.json | 2 +- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ec14e62599..e6787427d6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,13 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [2.0.0-spork.3](https://github.com/scratchfoundation/scratch-blocks/compare/v2.0.0-spork.2...v2.0.0-spork.3) (2024-12-10) + + +### Bug Fixes + +* rename mouseDownWrapper fields for Blockly v12 compatibility ([adaf531](https://github.com/scratchfoundation/scratch-blocks/commit/adaf531cadf51f797cf6c33050df2380bb3cf372)) + # [2.0.0-spork.2](https://github.com/scratchfoundation/scratch-blocks/compare/v2.0.0-spork.1...v2.0.0-spork.2) (2024-12-10) diff --git a/package-lock.json b/package-lock.json index 8ca6bf4607..c37ed38104 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "scratch-blocks", - "version": "2.0.0-spork.2", + "version": "2.0.0-spork.3", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "scratch-blocks", - "version": "2.0.0-spork.2", + "version": "2.0.0-spork.3", "license": "Apache-2.0", "dependencies": { "@blockly/continuous-toolbox": "^6.0.9", diff --git a/package.json b/package.json index b7d305d587..cb93f36350 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "scratch-blocks", - "version": "2.0.0-spork.2", + "version": "2.0.0-spork.3", "description": "Scratch Blocks is a library for building creative computing interfaces.", "author": "Massachusetts Institute of Technology", "license": "Apache-2.0", From 81f19c182cbe3bd03ae2a814408fdd6d4af3fe1b Mon Sep 17 00:00:00 2001 From: Aaron Dodson Date: Tue, 4 Feb 2025 15:51:32 -0800 Subject: [PATCH 126/130] refactor: update codebase for new version of Blockly and continuous toolbox (#226) * refactor: update codebase for new version of Blockly and continuous toolbox * chore: update deps to reference new versions of Blockly and continuous toolbox * chore: rename checkable_continuous_flyout.js to checkable_continuous_flyout.ts * refactor: convert CheckableContinuousFlyout to typescript * chore: remove debugging * fix: fix support for status indicator labels --- package-lock.json | 294 ++++++++---------- package.json | 4 +- src/checkable_continuous_flyout.js | 138 -------- src/checkable_continuous_flyout.ts | 112 +++++++ src/checkbox_bubble.ts | 9 +- src/css.ts | 20 +- src/fields/field_matrix.ts | 6 +- src/fields/scratch_field_angle.ts | 8 +- src/index.ts | 6 +- src/recyclable_block_flyout_inflater.ts | 159 +--------- src/scratch_continuous_toolbox.ts | 50 ++- src/status_indicator_label_flyout_inflater.ts | 8 +- src/variables.ts | 2 +- 13 files changed, 310 insertions(+), 506 deletions(-) delete mode 100644 src/checkable_continuous_flyout.js create mode 100644 src/checkable_continuous_flyout.ts diff --git a/package-lock.json b/package-lock.json index cf66bab374..90f794ad0d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,9 +9,9 @@ "version": "2.0.0", "license": "Apache-2.0", "dependencies": { - "@blockly/continuous-toolbox": "^5.0.15", + "@blockly/continuous-toolbox": "^7.0.0-beta.1", "@blockly/field-colour": "^4.0.2", - "blockly": "^11.0.0" + "blockly": "^12.0.0-beta.1" }, "devDependencies": { "@commitlint/cli": "^17.8.1", @@ -125,14 +125,15 @@ } }, "node_modules/@blockly/continuous-toolbox": { - "version": "5.0.17", - "resolved": "https://registry.npmjs.org/@blockly/continuous-toolbox/-/continuous-toolbox-5.0.17.tgz", - "integrity": "sha512-3JCSimCo5KEWvvN4qC66vs2L/WtJIHepoIfkPNcbvMwjwYxJ484UPK2LKdlyI1842mgFfcYM3nTERjfa+Q4rXA==", + "version": "7.0.0-beta.1", + "resolved": "https://registry.npmjs.org/@blockly/continuous-toolbox/-/continuous-toolbox-7.0.0-beta.1.tgz", + "integrity": "sha512-IKu0whdtRTmdXSB11efSJ5fCNzQtAp98fv+7KnZk/V7Q/xAhVAutWWQE+FJvr9lKJlkeYqm9m+cxDhOBtlVP1w==", + "license": "Apache-2.0", "engines": { "node": ">=8.17.0" }, "peerDependencies": { - "blockly": "^10.0.0" + "blockly": "^12.0.0-beta.0" } }, "node_modules/@blockly/field-colour": { @@ -1341,11 +1342,12 @@ } }, "node_modules/blockly": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/blockly/-/blockly-11.0.0.tgz", - "integrity": "sha512-6Ie7HuZWZLaETIVKFEP4FPDz267Pubn6+weQNZvXzqnkOYp9sKPSsPue8QIMCV9Qb5F4wYhqivgiDcZJcE1UlQ==", + "version": "12.0.0-beta.1", + "resolved": "https://registry.npmjs.org/blockly/-/blockly-12.0.0-beta.1.tgz", + "integrity": "sha512-lECwZ4K+YuLXMM0yxWTz1lwkmDl424sst7h/dhtSefuCki8afjI/F87byYK/ZIZsMKBEz2+8wEJ1Wlx5cYWIAg==", + "license": "Apache-2.0", "dependencies": { - "jsdom": "23.0.0" + "jsdom": "25.0.1" }, "engines": { "node": ">=18" @@ -2023,14 +2025,14 @@ } }, "node_modules/cssstyle": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-3.0.0.tgz", - "integrity": "sha512-N4u2ABATi3Qplzf0hWbVCdjenim8F3ojEXpBDF5hBpjzW182MjNGLqfmQ0SkSPeQ+V86ZXgeH8aXj6kayd4jgg==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-4.1.0.tgz", + "integrity": "sha512-h66W1URKpBS5YMI/V8PyXvTMFT8SupJ1IzoIV8IeBC/ji8WVmrO8dGlTi+2dh6whmdk6BiKJLD/ZBkhWbcg6nA==", "dependencies": { - "rrweb-cssom": "^0.6.0" + "rrweb-cssom": "^0.7.1" }, "engines": { - "node": ">=14" + "node": ">=18" } }, "node_modules/dargs": { @@ -3043,9 +3045,9 @@ } }, "node_modules/form-data": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", - "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.1.tgz", + "integrity": "sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==", "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", @@ -3522,9 +3524,9 @@ } }, "node_modules/https-proxy-agent": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.4.tgz", - "integrity": "sha512-wlwpilI7YdjSkWaQ/7omYBMTliDcmCN8OLihO6I9B86g06lMyAoqgoDpV0XqoaPOKj+0DIdAvnsWfyAAhmimcg==", + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.5.tgz", + "integrity": "sha512-1e4Wqeblerz+tMKPIq2EMGiiWW1dIjZOksyHWSUm1rmuvw/how9hBHZ38lAGj5ID4Ik6EdkOw7NmWPy6LAwalw==", "dependencies": { "agent-base": "^7.0.2", "debug": "4" @@ -4006,37 +4008,37 @@ } }, "node_modules/jsdom": { - "version": "23.0.0", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-23.0.0.tgz", - "integrity": "sha512-cbL/UCtohJguhFC7c2/hgW6BeZCNvP7URQGnx9tSJRYKCdnfbfWOrtuLTMfiB2VxKsx5wPHVsh/J0aBy9lIIhQ==", + "version": "25.0.1", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-25.0.1.tgz", + "integrity": "sha512-8i7LzZj7BF8uplX+ZyOlIz86V6TAsSs+np6m1kpW9u0JWi4z/1t+FzcK1aek+ybTnAC4KhBL4uXCNT0wcUIeCw==", "dependencies": { - "cssstyle": "^3.0.0", + "cssstyle": "^4.1.0", "data-urls": "^5.0.0", "decimal.js": "^10.4.3", "form-data": "^4.0.0", "html-encoding-sniffer": "^4.0.0", - "http-proxy-agent": "^7.0.0", - "https-proxy-agent": "^7.0.2", + "http-proxy-agent": "^7.0.2", + "https-proxy-agent": "^7.0.5", "is-potential-custom-element-name": "^1.0.1", - "nwsapi": "^2.2.7", + "nwsapi": "^2.2.12", "parse5": "^7.1.2", - "rrweb-cssom": "^0.6.0", + "rrweb-cssom": "^0.7.1", "saxes": "^6.0.0", "symbol-tree": "^3.2.4", - "tough-cookie": "^4.1.3", + "tough-cookie": "^5.0.0", "w3c-xmlserializer": "^5.0.0", "webidl-conversions": "^7.0.0", "whatwg-encoding": "^3.1.1", "whatwg-mimetype": "^4.0.0", "whatwg-url": "^14.0.0", - "ws": "^8.14.2", + "ws": "^8.18.0", "xml-name-validator": "^5.0.0" }, "engines": { "node": ">=18" }, "peerDependencies": { - "canvas": "^3.0.0" + "canvas": "^2.11.2" }, "peerDependenciesMeta": { "canvas": { @@ -4551,9 +4553,9 @@ } }, "node_modules/nwsapi": { - "version": "2.2.9", - "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.9.tgz", - "integrity": "sha512-2f3F0SEEer8bBu0dsNCFF50N0cTThV1nWFYcEYFZttdW0lDAoybv9cQoK7X7/68Z89S7FoRrVjP1LPX4XRf9vg==" + "version": "2.2.16", + "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.16.tgz", + "integrity": "sha512-F1I/bimDpj3ncaNDhfyMWuFqmQDBwDB0Fogc2qpL3BWvkQteFD/8BzWuIRl83rq0DXfm8SGt/HFhLXZyljTXcQ==" }, "node_modules/object-assign": { "version": "4.1.1", @@ -4747,11 +4749,11 @@ } }, "node_modules/parse5": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz", - "integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==", + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.2.1.tgz", + "integrity": "sha512-BuBYQYlv1ckiPdQi/ohiivi9Sagc9JG+Ozs0r7b/0iK3sKmrb0b9FdWdBbOdx6hBCM/F9Ir82ofnBhtZOjCRPQ==", "dependencies": { - "entities": "^4.4.0" + "entities": "^4.5.0" }, "funding": { "url": "https://github.com/inikulin/parse5?sponsor=1" @@ -4911,11 +4913,6 @@ "integrity": "sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==", "dev": true }, - "node_modules/psl": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", - "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==" - }, "node_modules/punycode": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", @@ -4939,11 +4936,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/querystringify": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", - "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==" - }, "node_modules/quick-lru": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz", @@ -5187,7 +5179,8 @@ "node_modules/requires-port": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", - "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==" + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", + "dev": true }, "node_modules/resolve": { "version": "1.22.8", @@ -5298,9 +5291,9 @@ } }, "node_modules/rrweb-cssom": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.6.0.tgz", - "integrity": "sha512-APM0Gt1KoXBz0iIkkdB/kfvGOwC4UuJFeG/c+yV7wSc7q96cG/kJ0HiYCnzivD9SB53cLV1MlHFNfOuPaadYSw==" + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.7.1.tgz", + "integrity": "sha512-TrEMa7JGdVm0UThDJSx7ddw5nVm3UJS9o9CCIZ72B1vSyEZoziDqBYP3XIoi/12lKrJR8rE3jeFHMok2F/Mnsg==" }, "node_modules/run-async": { "version": "2.4.1", @@ -6157,6 +6150,22 @@ "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==", "dev": true }, + "node_modules/tldts": { + "version": "6.1.65", + "resolved": "https://registry.npmjs.org/tldts/-/tldts-6.1.65.tgz", + "integrity": "sha512-xU9gLTfAGsADQ2PcWee6Hg8RFAv0DnjMGVJmDnUmI8a9+nYmapMQix4afwrdaCtT+AqP4MaxEzu7cCrYmBPbzQ==", + "dependencies": { + "tldts-core": "^6.1.65" + }, + "bin": { + "tldts": "bin/cli.js" + } + }, + "node_modules/tldts-core": { + "version": "6.1.65", + "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-6.1.65.tgz", + "integrity": "sha512-Uq5t0N0Oj4nQSbU8wFN1YYENvMthvwU13MQrMJRspYCGLSAZjAfoBOJki5IQpnBM/WFskxxC/gIOTwaedmHaSg==" + }, "node_modules/tmp": { "version": "0.0.33", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", @@ -6191,17 +6200,14 @@ } }, "node_modules/tough-cookie": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.4.tgz", - "integrity": "sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-5.0.0.tgz", + "integrity": "sha512-FRKsF7cz96xIIeMZ82ehjC3xW2E+O2+v11udrDYewUbszngYhsGa8z6YUMMzO9QJZzzyd0nGGXnML/TReX6W8Q==", "dependencies": { - "psl": "^1.1.33", - "punycode": "^2.1.1", - "universalify": "^0.2.0", - "url-parse": "^1.5.3" + "tldts": "^6.1.32" }, "engines": { - "node": ">=6" + "node": ">=16" } }, "node_modules/tr46": { @@ -6358,14 +6364,6 @@ "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", "dev": true }, - "node_modules/universalify": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", - "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==", - "engines": { - "node": ">= 4.0.0" - } - }, "node_modules/unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", @@ -6414,15 +6412,6 @@ "punycode": "^2.1.0" } }, - "node_modules/url-parse": { - "version": "1.5.10", - "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", - "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", - "dependencies": { - "querystringify": "^2.1.1", - "requires-port": "^1.0.0" - } - }, "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", @@ -6870,9 +6859,9 @@ } }, "node_modules/whatwg-url": { - "version": "14.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-14.0.0.tgz", - "integrity": "sha512-1lfMEm2IEr7RIV+f4lUNPOqfFL+pO+Xw3fJSqmjX9AbXcXcYOkCe1P6+9VBZB6n94af16NfZf+sSk0JCBZC9aw==", + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-14.1.0.tgz", + "integrity": "sha512-jlf/foYIKywAt3x/XWKZ/3rz8OSJPiWktjmk891alJUEjiVxKX9LEO92qH3hv4aJ0mN3MWPvGMCy8jQi95xK4w==", "dependencies": { "tr46": "^5.0.0", "webidl-conversions": "^7.0.0" @@ -6947,9 +6936,9 @@ } }, "node_modules/ws": { - "version": "8.15.1", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.15.1.tgz", - "integrity": "sha512-W5OZiCjXEmk0yZ66ZN82beM5Sz7l7coYxpRkzS+p9PP+ToQry8szKh+61eNktr7EA9DOwvFGhfC605jDHbP6QQ==", + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", + "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", "engines": { "node": ">=10.0.0" }, @@ -7134,9 +7123,9 @@ } }, "@blockly/continuous-toolbox": { - "version": "5.0.17", - "resolved": "https://registry.npmjs.org/@blockly/continuous-toolbox/-/continuous-toolbox-5.0.17.tgz", - "integrity": "sha512-3JCSimCo5KEWvvN4qC66vs2L/WtJIHepoIfkPNcbvMwjwYxJ484UPK2LKdlyI1842mgFfcYM3nTERjfa+Q4rXA==", + "version": "7.0.0-beta.1", + "resolved": "https://registry.npmjs.org/@blockly/continuous-toolbox/-/continuous-toolbox-7.0.0-beta.1.tgz", + "integrity": "sha512-IKu0whdtRTmdXSB11efSJ5fCNzQtAp98fv+7KnZk/V7Q/xAhVAutWWQE+FJvr9lKJlkeYqm9m+cxDhOBtlVP1w==", "requires": {} }, "@blockly/field-colour": { @@ -8160,11 +8149,11 @@ "dev": true }, "blockly": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/blockly/-/blockly-11.0.0.tgz", - "integrity": "sha512-6Ie7HuZWZLaETIVKFEP4FPDz267Pubn6+weQNZvXzqnkOYp9sKPSsPue8QIMCV9Qb5F4wYhqivgiDcZJcE1UlQ==", + "version": "12.0.0-beta.1", + "resolved": "https://registry.npmjs.org/blockly/-/blockly-12.0.0-beta.1.tgz", + "integrity": "sha512-lECwZ4K+YuLXMM0yxWTz1lwkmDl424sst7h/dhtSefuCki8afjI/F87byYK/ZIZsMKBEz2+8wEJ1Wlx5cYWIAg==", "requires": { - "jsdom": "23.0.0" + "jsdom": "25.0.1" } }, "body-parser": { @@ -8677,11 +8666,11 @@ } }, "cssstyle": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-3.0.0.tgz", - "integrity": "sha512-N4u2ABATi3Qplzf0hWbVCdjenim8F3ojEXpBDF5hBpjzW182MjNGLqfmQ0SkSPeQ+V86ZXgeH8aXj6kayd4jgg==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-4.1.0.tgz", + "integrity": "sha512-h66W1URKpBS5YMI/V8PyXvTMFT8SupJ1IzoIV8IeBC/ji8WVmrO8dGlTi+2dh6whmdk6BiKJLD/ZBkhWbcg6nA==", "requires": { - "rrweb-cssom": "^0.6.0" + "rrweb-cssom": "^0.7.1" } }, "dargs": { @@ -9484,9 +9473,9 @@ "dev": true }, "form-data": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", - "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.1.tgz", + "integrity": "sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==", "requires": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", @@ -9842,9 +9831,9 @@ } }, "https-proxy-agent": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.4.tgz", - "integrity": "sha512-wlwpilI7YdjSkWaQ/7omYBMTliDcmCN8OLihO6I9B86g06lMyAoqgoDpV0XqoaPOKj+0DIdAvnsWfyAAhmimcg==", + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.5.tgz", + "integrity": "sha512-1e4Wqeblerz+tMKPIq2EMGiiWW1dIjZOksyHWSUm1rmuvw/how9hBHZ38lAGj5ID4Ik6EdkOw7NmWPy6LAwalw==", "requires": { "agent-base": "^7.0.2", "debug": "4" @@ -10207,30 +10196,30 @@ } }, "jsdom": { - "version": "23.0.0", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-23.0.0.tgz", - "integrity": "sha512-cbL/UCtohJguhFC7c2/hgW6BeZCNvP7URQGnx9tSJRYKCdnfbfWOrtuLTMfiB2VxKsx5wPHVsh/J0aBy9lIIhQ==", + "version": "25.0.1", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-25.0.1.tgz", + "integrity": "sha512-8i7LzZj7BF8uplX+ZyOlIz86V6TAsSs+np6m1kpW9u0JWi4z/1t+FzcK1aek+ybTnAC4KhBL4uXCNT0wcUIeCw==", "requires": { - "cssstyle": "^3.0.0", + "cssstyle": "^4.1.0", "data-urls": "^5.0.0", "decimal.js": "^10.4.3", "form-data": "^4.0.0", "html-encoding-sniffer": "^4.0.0", - "http-proxy-agent": "^7.0.0", - "https-proxy-agent": "^7.0.2", + "http-proxy-agent": "^7.0.2", + "https-proxy-agent": "^7.0.5", "is-potential-custom-element-name": "^1.0.1", - "nwsapi": "^2.2.7", + "nwsapi": "^2.2.12", "parse5": "^7.1.2", - "rrweb-cssom": "^0.6.0", + "rrweb-cssom": "^0.7.1", "saxes": "^6.0.0", "symbol-tree": "^3.2.4", - "tough-cookie": "^4.1.3", + "tough-cookie": "^5.0.0", "w3c-xmlserializer": "^5.0.0", "webidl-conversions": "^7.0.0", "whatwg-encoding": "^3.1.1", "whatwg-mimetype": "^4.0.0", "whatwg-url": "^14.0.0", - "ws": "^8.14.2", + "ws": "^8.18.0", "xml-name-validator": "^5.0.0" } }, @@ -10641,9 +10630,9 @@ } }, "nwsapi": { - "version": "2.2.9", - "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.9.tgz", - "integrity": "sha512-2f3F0SEEer8bBu0dsNCFF50N0cTThV1nWFYcEYFZttdW0lDAoybv9cQoK7X7/68Z89S7FoRrVjP1LPX4XRf9vg==" + "version": "2.2.16", + "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.16.tgz", + "integrity": "sha512-F1I/bimDpj3ncaNDhfyMWuFqmQDBwDB0Fogc2qpL3BWvkQteFD/8BzWuIRl83rq0DXfm8SGt/HFhLXZyljTXcQ==" }, "object-assign": { "version": "4.1.1", @@ -10783,11 +10772,11 @@ } }, "parse5": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz", - "integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==", + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.2.1.tgz", + "integrity": "sha512-BuBYQYlv1ckiPdQi/ohiivi9Sagc9JG+Ozs0r7b/0iK3sKmrb0b9FdWdBbOdx6hBCM/F9Ir82ofnBhtZOjCRPQ==", "requires": { - "entities": "^4.4.0" + "entities": "^4.5.0" } }, "parseurl": { @@ -10907,11 +10896,6 @@ "integrity": "sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==", "dev": true }, - "psl": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", - "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==" - }, "punycode": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", @@ -10926,11 +10910,6 @@ "side-channel": "^1.0.4" } }, - "querystringify": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", - "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==" - }, "quick-lru": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz", @@ -11122,7 +11101,8 @@ "requires-port": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", - "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==" + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", + "dev": true }, "resolve": { "version": "1.22.8", @@ -11202,9 +11182,9 @@ } }, "rrweb-cssom": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.6.0.tgz", - "integrity": "sha512-APM0Gt1KoXBz0iIkkdB/kfvGOwC4UuJFeG/c+yV7wSc7q96cG/kJ0HiYCnzivD9SB53cLV1MlHFNfOuPaadYSw==" + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.7.1.tgz", + "integrity": "sha512-TrEMa7JGdVm0UThDJSx7ddw5nVm3UJS9o9CCIZ72B1vSyEZoziDqBYP3XIoi/12lKrJR8rE3jeFHMok2F/Mnsg==" }, "run-async": { "version": "2.4.1", @@ -11885,6 +11865,19 @@ "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==", "dev": true }, + "tldts": { + "version": "6.1.65", + "resolved": "https://registry.npmjs.org/tldts/-/tldts-6.1.65.tgz", + "integrity": "sha512-xU9gLTfAGsADQ2PcWee6Hg8RFAv0DnjMGVJmDnUmI8a9+nYmapMQix4afwrdaCtT+AqP4MaxEzu7cCrYmBPbzQ==", + "requires": { + "tldts-core": "^6.1.65" + } + }, + "tldts-core": { + "version": "6.1.65", + "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-6.1.65.tgz", + "integrity": "sha512-Uq5t0N0Oj4nQSbU8wFN1YYENvMthvwU13MQrMJRspYCGLSAZjAfoBOJki5IQpnBM/WFskxxC/gIOTwaedmHaSg==" + }, "tmp": { "version": "0.0.33", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", @@ -11910,14 +11903,11 @@ "dev": true }, "tough-cookie": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.4.tgz", - "integrity": "sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-5.0.0.tgz", + "integrity": "sha512-FRKsF7cz96xIIeMZ82ehjC3xW2E+O2+v11udrDYewUbszngYhsGa8z6YUMMzO9QJZzzyd0nGGXnML/TReX6W8Q==", "requires": { - "psl": "^1.1.33", - "punycode": "^2.1.1", - "universalify": "^0.2.0", - "url-parse": "^1.5.3" + "tldts": "^6.1.32" } }, "tr46": { @@ -12019,11 +12009,6 @@ "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", "dev": true }, - "universalify": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", - "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==" - }, "unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", @@ -12049,15 +12034,6 @@ "punycode": "^2.1.0" } }, - "url-parse": { - "version": "1.5.10", - "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", - "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", - "requires": { - "querystringify": "^2.1.1", - "requires-port": "^1.0.0" - } - }, "util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", @@ -12371,9 +12347,9 @@ "integrity": "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==" }, "whatwg-url": { - "version": "14.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-14.0.0.tgz", - "integrity": "sha512-1lfMEm2IEr7RIV+f4lUNPOqfFL+pO+Xw3fJSqmjX9AbXcXcYOkCe1P6+9VBZB6n94af16NfZf+sSk0JCBZC9aw==", + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-14.1.0.tgz", + "integrity": "sha512-jlf/foYIKywAt3x/XWKZ/3rz8OSJPiWktjmk891alJUEjiVxKX9LEO92qH3hv4aJ0mN3MWPvGMCy8jQi95xK4w==", "requires": { "tr46": "^5.0.0", "webidl-conversions": "^7.0.0" @@ -12427,9 +12403,9 @@ } }, "ws": { - "version": "8.15.1", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.15.1.tgz", - "integrity": "sha512-W5OZiCjXEmk0yZ66ZN82beM5Sz7l7coYxpRkzS+p9PP+ToQry8szKh+61eNktr7EA9DOwvFGhfC605jDHbP6QQ==", + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", + "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", "requires": {} }, "xml-name-validator": { diff --git a/package.json b/package.json index cfc9274a1f..2cdb08ac5f 100644 --- a/package.json +++ b/package.json @@ -29,8 +29,8 @@ "webpack-dev-server": "^4.11.1" }, "dependencies": { - "@blockly/continuous-toolbox": "^5.0.15", + "@blockly/continuous-toolbox": "^7.0.0-beta.1", "@blockly/field-colour": "^4.0.2", - "blockly": "^11.0.0" + "blockly": "^12.0.0-beta.1" } } diff --git a/src/checkable_continuous_flyout.js b/src/checkable_continuous_flyout.js deleted file mode 100644 index c228131504..0000000000 --- a/src/checkable_continuous_flyout.js +++ /dev/null @@ -1,138 +0,0 @@ -/** - * @license - * Copyright 2024 Google LLC - * SPDX-License-Identifier: Apache-2.0 - */ - -import * as Blockly from "blockly/core"; -import { ContinuousFlyout } from "@blockly/continuous-toolbox"; -import { RecyclableBlockFlyoutInflater } from "./recyclable_block_flyout_inflater"; -import { StatusIndicatorLabel } from "./status_indicator_label"; - -export class CheckableContinuousFlyout extends ContinuousFlyout { - /** - * Creates a new CheckableContinuousFlyout. - * - * @param {!Blockly.Options} workspaceOptions Configuration options for the - * flyout workspace. - */ - constructor(workspaceOptions) { - workspaceOptions.modalInputs = false; - super(workspaceOptions); - this.tabWidth_ = -2; - this.MARGIN = 12; - this.GAP_Y = 12; - } - - /** - * Displays the given contents in the flyout. - * - * @param {!Object} flyoutDef The new contents to show in the flyout. - */ - show(flyoutDef) { - super.show(flyoutDef); - const inflater = this.getInflaterForType("block"); - if (inflater instanceof RecyclableBlockFlyoutInflater) { - inflater.emptyRecycledBlocks(); - } - } - - /** - * Serializes a block to JSON in order to copy it to the main workspace. - * - * @param {!Blockly.BlockSvg} block The block to serialize. - * @returns {!Object} A JSON representation of the block. - */ - serializeBlock(block) { - const json = super.serializeBlock(block); - // Delete the serialized block's ID so that a new one is generated when it is - // placed on the workspace. Otherwise, the block on the workspace may be - // indistinguishable from the one in the flyout, which can cause reporter blocks - // to have their value dropdown shown in the wrong place. - delete json.id; - return json; - } - - /** - * Set the state of a checkbox by block ID. - * @param {string} blockId ID of the block whose checkbox should be set - * @param {boolean} value Value to set the checkbox to. - * @public - */ - setCheckboxState(blockId, value) { - this.getWorkspace() - .getBlockById(blockId) - ?.getIcon("checkbox") - ?.setChecked(value); - } - - getFlyoutScale() { - return 0.675; - } - - getWidth() { - return 250; - } - - /** - * Sets whether or not block recycling is enabled in the flyout. - * - * @param {boolean} enabled True if recycling should be enabled. - */ - setRecyclingEnabled(enabled) { - const inflater = this.getInflaterForType("block"); - if (inflater instanceof RecyclableBlockFlyoutInflater) { - inflater.setRecyclingEnabled(enabled); - } - } - - /** - * Records scroll position for each category in the toolbox. - * The scroll position is determined by the coordinates of each category's - * label after the entire flyout has been rendered. - * @package - */ - recordScrollPositions() { - // TODO(#211) Remove this once the continuous toolbox has been updated. - this.scrollPositions = []; - const categoryLabels = this.getContents() - .filter( - (item) => - (item.type === "label" || item.type === "status_indicator_label") && - item.element.isLabel() && - this.getParentToolbox_().getCategoryByName( - item.element.getButtonText() - ) - ) - .map((item) => item.element); - for (const [index, label] of categoryLabels.entries()) { - this.scrollPositions.push({ - name: label.getButtonText(), - position: label.getPosition(), - }); - } - } - - /** - * Positions the contents of the flyout. - * - * @param {!Blockly.FlyoutItem[]} The flyout items to position. - */ - layout_(contents) { - // TODO(#211) Remove this once the continuous toolbox has been updated. - // Bypass the continuous flyout's layout method until the plugin is - // updated for the new flyout API. - Blockly.VerticalFlyout.prototype.layout_.call(this, contents); - } - - /** - * Updates the state of status indicators for hardware-based extensions. - */ - refreshStatusButtons() { - for (const item of this.contents) { - if (item.element instanceof StatusIndicatorLabel) { - item.element.refreshStatus(); - } - } - } -} diff --git a/src/checkable_continuous_flyout.ts b/src/checkable_continuous_flyout.ts new file mode 100644 index 0000000000..8a337d88d7 --- /dev/null +++ b/src/checkable_continuous_flyout.ts @@ -0,0 +1,112 @@ +/** + * @license + * Copyright 2024 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + +import * as Blockly from "blockly/core"; +import { ContinuousFlyout } from "@blockly/continuous-toolbox"; +import { CheckboxBubble } from "./checkbox_bubble"; +import { StatusIndicatorLabel } from "./status_indicator_label"; +import { STATUS_INDICATOR_LABEL_TYPE } from "./status_indicator_label_flyout_inflater"; + +export class CheckableContinuousFlyout extends ContinuousFlyout { + /** + * Creates a new CheckableContinuousFlyout. + * + * @param workspaceOptions Configuration options for the flyout workspace. + */ + constructor(workspaceOptions: Blockly.Options) { + workspaceOptions.modalInputs = false; + super(workspaceOptions); + this.tabWidth_ = 0; + this.MARGIN = 12; + this.GAP_Y = 12; + } + + /** + * Serializes a block to JSON in order to copy it to the main workspace. + * + * @param block The block to serialize. + * @returns A JSON representation of the block. + */ + protected serializeBlock(block: Blockly.BlockSvg) { + const json = super.serializeBlock(block); + // Delete the serialized block's ID so that a new one is generated when it is + // placed on the workspace. Otherwise, the block on the workspace may be + // indistinguishable from the one in the flyout, which can cause reporter blocks + // to have their value dropdown shown in the wrong place. + delete json.id; + return json; + } + + /** + * Set the state of a checkbox by block ID. + * + * @param blockId ID of the block whose checkbox should be set + * @param value Value to set the checkbox to. + */ + setCheckboxState(blockId: string, value: boolean) { + this.getWorkspace() + .getBlockById(blockId) + ?.getIcon("checkbox") + ?.setChecked(value); + } + + getFlyoutScale() { + return 0.675; + } + + getWidth() { + return 250; + } + + protected reflowInternal_() { + super.reflowInternal_(); + + if (this.RTL) { + // The parent implementation assumes that the flyout grows to fit its + // contents, and adjusts blocks in RTL mode accordingly. In Scratch, the + // flyout width is fixed (and blocks may exceed it), so re-adjust blocks + // accordingly based on the actual fixed width. + for (const item of this.getContents()) { + const oldX = item.getElement().getBoundingRectangle().left; + let newX = + this.getWidth() / this.workspace_.scale - + item.getElement().getBoundingRectangle().getWidth() - + this.MARGIN; + if ( + "checkboxInFlyout" in item.getElement() && + item.getElement().checkboxInFlyout + ) { + newX -= CheckboxBubble.CHECKBOX_SIZE + CheckboxBubble.CHECKBOX_MARGIN; + } + item.getElement().moveBy(newX - oldX, 0); + } + } + } + + /** + * Validates that the given toolbox item represents a label. + * + * @param item The toolbox item to check. + * @returns True if the item represents a label in the flyout. + */ + protected toolboxItemIsLabel(item: Blockly.FlyoutItem) { + return ( + item.getType() === STATUS_INDICATOR_LABEL_TYPE || + super.toolboxItemIsLabel(item) + ); + } + + /** + * Updates the state of status indicators for hardware-based extensions. + */ + refreshStatusButtons() { + for (const item of this.contents) { + if (item.element instanceof StatusIndicatorLabel) { + item.element.refreshStatus(); + } + } + } +} diff --git a/src/checkbox_bubble.ts b/src/checkbox_bubble.ts index 30349d0da0..1b6bc69bb0 100644 --- a/src/checkbox_bubble.ts +++ b/src/checkbox_bubble.ts @@ -203,15 +203,14 @@ export class CheckboxBubble * Recalculates this bubble's location, keeping it adjacent to its block. */ updateLocation() { - const blockLocation = this.sourceBlock.getRelativeToSurfaceXY(); - const blockBounds = this.sourceBlock.getHeightWidth(); + const bounds = this.sourceBlock.getBoundingRectangle(); const x = this.sourceBlock.workspace.RTL - ? blockLocation.x + blockBounds.width + CheckboxBubble.CHECKBOX_MARGIN - : blockLocation.x - + ? bounds.right + CheckboxBubble.CHECKBOX_MARGIN + : bounds.left - CheckboxBubble.CHECKBOX_MARGIN - CheckboxBubble.CHECKBOX_SIZE; const y = - blockLocation.y + (blockBounds.height - CheckboxBubble.CHECKBOX_SIZE) / 2; + bounds.top + (bounds.getHeight() - CheckboxBubble.CHECKBOX_SIZE) / 2; this.moveTo(x, y); } diff --git a/src/css.ts b/src/css.ts index 589f876ec1..fbabbce4eb 100644 --- a/src/css.ts +++ b/src/css.ts @@ -751,8 +751,9 @@ const styles = ` } /* Category tree in Toolbox. */ - .blocklyToolboxDiv { + .blocklyToolbox { background-color: var(--colour-toolbox); + border-right: 1px solid #ddd; color: var(--colour-toolboxText); overflow-x: visible; overflow-y: auto; @@ -763,6 +764,11 @@ const styles = ` padding: 0; } + .blocklyToolbox[dir="RTL"] { + border-right: none; + border-left: 1px solid #ddd; + } + .blocklyTreeRoot { padding: 4px 0; } @@ -771,7 +777,7 @@ const styles = ` outline: none; } - .blocklyToolboxDiv .blocklyTreeRow { + .blocklyToolbox .blocklyToolboxCategory { line-height: 22px; margin: 0; padding: 0.375rem 0px; @@ -789,11 +795,11 @@ const styles = ` margin: 1px 0 8px 5px; } - .blocklyToolboxDiv[dir="RTL"] .blocklyTreeRow { - margin-left: 8px; + .blocklyToolbox[dir="RTL"] .blocklyToolboxCategory { + margin-left: 0px; } - .blocklyTreeRow:hover { + .blocklyToolboxCategory:hover { color: var(--colour-toolboxHover); } @@ -844,7 +850,7 @@ const styles = ` background-position: -48px -1px; } - .blocklyTreeLabel { + .blocklyToolboxCategoryLabel { cursor: default; font-family: "Helvetica Neue", Helvetica, sans-serif; font-size: .65rem; @@ -855,7 +861,7 @@ const styles = ` text-wrap: wrap; } - .blocklyTreeSelected .blocklyTreeLabel { + .blocklyToolboxSelected .blocklyToolboxCategoryLabel { color: inherit; } diff --git a/src/fields/field_matrix.ts b/src/fields/field_matrix.ts index 1ac385328c..336527af19 100644 --- a/src/fields/field_matrix.ts +++ b/src/fields/field_matrix.ts @@ -70,7 +70,7 @@ class FieldMatrix extends Blockly.Field { * Touch event wrapper. * Runs when the field is selected. */ - private mouseDownWrapper: Blockly.browserEvents.Data | null = null; + private mouseDownWrapper_: Blockly.browserEvents.Data | null = null; /** * Touch event wrapper. @@ -558,8 +558,8 @@ class FieldMatrix extends Blockly.Field { dispose() { super.dispose(); this.matrixStage_ = null; - if (this.mouseDownWrapper) { - Blockly.browserEvents.unbind(this.mouseDownWrapper); + if (this.mouseDownWrapper_) { + Blockly.browserEvents.unbind(this.mouseDownWrapper_); } if (this.matrixTouchWrapper_) { Blockly.browserEvents.unbind(this.matrixTouchWrapper_); diff --git a/src/fields/scratch_field_angle.ts b/src/fields/scratch_field_angle.ts index 749c4e2498..9a058e242d 100644 --- a/src/fields/scratch_field_angle.ts +++ b/src/fields/scratch_field_angle.ts @@ -51,7 +51,7 @@ class ScratchFieldAngle extends Blockly.FieldNumber { /** * Opaque identifier used to unbind event listener in dispose(). */ - private mouseDownWrapper: Blockly.browserEvents.Data; + private mouseDownWrapper_: Blockly.browserEvents.Data; /** * Opaque identifier used to unbind event listener in dispose(). @@ -142,8 +142,8 @@ class ScratchFieldAngle extends Blockly.FieldNumber { dispose() { super.dispose(); this.gauge = null; - if (this.mouseDownWrapper) { - Blockly.browserEvents.unbind(this.mouseDownWrapper); + if (this.mouseDownWrapper_) { + Blockly.browserEvents.unbind(this.mouseDownWrapper_); } if (this.mouseUpWrapper) { Blockly.browserEvents.unbind(this.mouseUpWrapper); @@ -286,7 +286,7 @@ class ScratchFieldAngle extends Blockly.FieldNumber { this.getSourceBlock() as Blockly.BlockSvg ); - this.mouseDownWrapper = Blockly.browserEvents.bind( + this.mouseDownWrapper_ = Blockly.browserEvents.bind( this.handle, "mousedown", this, diff --git a/src/index.ts b/src/index.ts index eeeac8aa32..b57312ec98 100644 --- a/src/index.ts +++ b/src/index.ts @@ -26,11 +26,10 @@ import "./css"; import "./renderer/renderer"; import * as contextMenuItems from "./context_menu_items"; import { - ContinuousToolbox, - ContinuousFlyout, + registerContinuousToolbox, ContinuousMetrics, } from "@blockly/continuous-toolbox"; -import { CheckableContinuousFlyout } from "./checkable_continuous_flyout.js"; +import { CheckableContinuousFlyout } from "./checkable_continuous_flyout"; import { buildGlowFilter, glowStack } from "./glows"; import { ScratchContinuousToolbox } from "./scratch_continuous_toolbox"; import "./scratch_comment_icon"; @@ -120,6 +119,7 @@ export function inject(container: Element, options: Blockly.BlocklyOptions) { return workspace; } +registerContinuousToolbox(); Blockly.Scrollbar.scrollbarThickness = Blockly.Touch.TOUCH_ENABLED ? 14 : 11; Blockly.FlyoutButton.TEXT_MARGIN_X = 40; Blockly.FlyoutButton.TEXT_MARGIN_Y = 10; diff --git a/src/recyclable_block_flyout_inflater.ts b/src/recyclable_block_flyout_inflater.ts index 63dce02773..96c22a46fe 100644 --- a/src/recyclable_block_flyout_inflater.ts +++ b/src/recyclable_block_flyout_inflater.ts @@ -6,21 +6,12 @@ import * as Blockly from "blockly/core"; import { CheckboxBubble } from "./checkbox_bubble"; +import { RecyclableBlockFlyoutInflater as BlocklyRecyclableBlockFlyoutInflater } from "@blockly/continuous-toolbox"; /** * A block inflater that caches and reuses blocks to improve performance. */ -export class RecyclableBlockFlyoutInflater extends Blockly.BlockFlyoutInflater { - /** - * Whether or not block recycling is enabled. - */ - recyclingEnabled = true; - - /** - * Map from block type to block instance. - */ - recycledBlocks = new Map(); - +export class RecyclableBlockFlyoutInflater extends BlocklyRecyclableBlockFlyoutInflater { /** * Creates a block on the flyout workspace from the given block definition. * @@ -31,152 +22,18 @@ export class RecyclableBlockFlyoutInflater extends Blockly.BlockFlyoutInflater { load( state: Blockly.utils.toolbox.BlockInfo, flyoutWorkspace: Blockly.WorkspaceSvg - ): Blockly.IBoundedElement { - const block = super.load(state, flyoutWorkspace); + ): Blockly.FlyoutItem { + const flyoutItem = super.load(state, flyoutWorkspace); + const block = flyoutItem.getElement(); if ("checkboxInFlyout" in block && block.checkboxInFlyout) { block.moveBy( - CheckboxBubble.CHECKBOX_SIZE + CheckboxBubble.CHECKBOX_MARGIN, + (flyoutWorkspace.RTL ? -1 : 1) * + (CheckboxBubble.CHECKBOX_SIZE + CheckboxBubble.CHECKBOX_MARGIN), 0 ); } - return block; - } - - /** - * Toggles whether or not recycling is enabled. - * - * @param enabled True if recycling should be enabled. - */ - setRecyclingEnabled(enabled: boolean) { - this.recyclingEnabled = enabled; - } - - /** - * Creates a new block from the given block definition. - * - * @param blockDefinition The definition to create a block from. - * @returns The newly created block. - */ - createBlock( - blockDefinition: Blockly.utils.toolbox.BlockInfo - ): Blockly.BlockSvg { - const blockType = this.getTypeFromDefinition(blockDefinition); - return ( - this.getRecycledBlock(blockType) ?? - super.createBlock(blockDefinition, this.flyoutWorkspace) - ); - } - - /** - * Returns the type of a block from an XML or JSON block definition. - * - * @param blockDefinition The block definition to parse. - * @returns The block type. - */ - getTypeFromDefinition( - blockDefinition: Blockly.utils.toolbox.BlockInfo - ): string { - if (blockDefinition["blockxml"]) { - const xml = - typeof blockDefinition["blockxml"] === "string" - ? Blockly.utils.xml.textToDom(blockDefinition["blockxml"]) - : (blockDefinition["blockxml"] as Element); - return xml.getAttribute("type"); - } else { - return blockDefinition["type"]; - } - } - - /** - * Puts a previously created block into the recycle bin and moves it to the - * top of the workspace. Used during large workspace swaps to limit the number - * of new DOM elements we need to create. - * - * @param block The block to recycle. - */ - recycleBlock(block: Blockly.BlockSvg) { - const xy = block.getRelativeToSurfaceXY(); - block.moveBy(-xy.x, -xy.y); - this.recycledBlocks.set(block.type, block); - } - - /** - * Returns a block from the cache of recycled blocks with the given type, or - * undefined if one cannot be found. - * - * @param blockType The type of the block to try to recycle. - * @returns The recycled block, or undefined if one could not be recycled. - */ - getRecycledBlock(blockType: string): Blockly.BlockSvg | undefined { - const block = this.recycledBlocks.get(blockType); - this.recycledBlocks.delete(blockType); - return block; - } - - /** - * Returns whether the given block can be recycled or not. - * - * @param block The block to check for recyclability. - * @returns True if the block can be recycled. False otherwise. - */ - blockIsRecyclable(block: Blockly.Block): boolean { - if (!this.recyclingEnabled) { - return false; - } - - // If the block needs to parse mutations, never recycle. - if (block.mutationToDom && block.domToMutation) { - return false; - } - - if (!block.isEnabled()) { - return false; - } - - for (const input of block.inputList) { - for (const field of input.fieldRow) { - // No variables. - if (field.referencesVariables()) { - return false; - } - if (field instanceof Blockly.FieldDropdown) { - if (field.isOptionListDynamic()) { - return false; - } - } - } - // Check children. - if (input.connection) { - const targetBlock = input.connection.targetBlock(); - if (targetBlock && !this.blockIsRecyclable(targetBlock)) { - return false; - } - } - } - return true; - } - - /** - * Disposes of the provided block. - * - * @param element The block to dispose of. - */ - disposeElement(element: Blockly.BlockSvg) { - if (this.blockIsRecyclable(element)) { - this.removeListeners(element.id); - this.recycleBlock(element); - } else { - super.disposeElement(element); - } - } - - /** - * Clears the cache of recycled blocks. - */ - emptyRecycledBlocks() { - this.recycledBlocks.forEach((block) => block.dispose(false, false)); - this.recycledBlocks.clear(); + return flyoutItem; } } diff --git a/src/scratch_continuous_toolbox.ts b/src/scratch_continuous_toolbox.ts index 3104191368..76cc73b1c2 100644 --- a/src/scratch_continuous_toolbox.ts +++ b/src/scratch_continuous_toolbox.ts @@ -7,6 +7,7 @@ import * as Blockly from "blockly/core"; import { ContinuousToolbox } from "@blockly/continuous-toolbox"; import { ScratchContinuousCategory } from "./scratch_continuous_category"; +import { STATUS_INDICATOR_LABEL_TYPE } from "./status_indicator_label_flyout_inflater"; /** * A toolbox that displays items from all categories in one scrolling list. @@ -23,36 +24,25 @@ export class ScratchContinuousToolbox extends ContinuousToolbox { } /** - * Gets the contents that should be shown in the flyout. + * Converts the given toolbox item to a corresponding array of items that + * should appear in the flyout. * - * @returns Flyout contents. + * @param toolboxItem The toolbox item to convert. + * @returns An array of flyout item definitions. */ - getInitialFlyoutContents_(): Blockly.utils.toolbox.FlyoutItemInfoArray { - // TODO(#211) Clean this up when the continuous toolbox plugin is updated. - let contents: Blockly.utils.toolbox.FlyoutItemInfoArray = []; - for (const toolboxItem of this.getToolboxItems()) { - if (toolboxItem instanceof ScratchContinuousCategory) { - if (toolboxItem.shouldShowStatusButton()) { - contents.push({ - kind: "STATUS_INDICATOR_LABEL", - id: toolboxItem.getId(), - text: toolboxItem.getName(), - }); - } else { - // Create a label node to go at the top of the category - contents.push({ kind: "LABEL", text: toolboxItem.getName() }); - } - let itemContents = toolboxItem.getContents(); - - // Handle custom categories (e.g. variables and functions) - if (typeof itemContents === "string") { - itemContents = { - custom: itemContents, - kind: "CATEGORY", - }; - } - contents = contents.concat(itemContents); - } + protected convertToolboxItemToFlyoutItems( + toolboxItem: Blockly.IToolboxItem + ): Blockly.utils.toolbox.FlyoutItemInfoArray { + const contents = super.convertToolboxItemToFlyoutItems(toolboxItem); + if ( + toolboxItem instanceof ScratchContinuousCategory && + toolboxItem.shouldShowStatusButton() + ) { + contents.splice(0, 1, { + kind: STATUS_INDICATOR_LABEL_TYPE, + id: toolboxItem.getId(), + text: toolboxItem.getName(), + }); } return contents; } @@ -62,12 +52,12 @@ export class ScratchContinuousToolbox extends ContinuousToolbox { */ forceRerender() { const selectedCategoryName = this.selectedItem_?.getName(); - super.refreshSelection(); + this.getFlyout().show(this.getInitialFlyoutContents()); + this.selectCategoryByName(selectedCategoryName); let callback; while ((callback = this.postRenderCallbacks.shift())) { callback(); } - this.selectCategoryByName(selectedCategoryName); } /** diff --git a/src/status_indicator_label_flyout_inflater.ts b/src/status_indicator_label_flyout_inflater.ts index 2b9de6584e..7ed8a63eae 100644 --- a/src/status_indicator_label_flyout_inflater.ts +++ b/src/status_indicator_label_flyout_inflater.ts @@ -7,6 +7,8 @@ import * as Blockly from "blockly/core"; import { StatusIndicatorLabel } from "./status_indicator_label"; +export const STATUS_INDICATOR_LABEL_TYPE = "status_indicator_label"; + /** * Flyout inflater responsible for creating status indicator labels. */ @@ -21,14 +23,14 @@ class StatusIndicatorLabelFlyoutInflater extends Blockly.LabelFlyoutInflater { load( state: Blockly.utils.toolbox.LabelInfo, flyoutWorkspace: Blockly.WorkspaceSvg - ): StatusIndicatorLabel { + ): Blockly.FlyoutItem { const label = new StatusIndicatorLabel( flyoutWorkspace, flyoutWorkspace.targetWorkspace, state ); label.show(); - return label; + return new Blockly.FlyoutItem(label, STATUS_INDICATOR_LABEL_TYPE, true); } } @@ -38,7 +40,7 @@ class StatusIndicatorLabelFlyoutInflater extends Blockly.LabelFlyoutInflater { export function registerStatusIndicatorLabelFlyoutInflater() { Blockly.registry.register( Blockly.registry.Type.FLYOUT_INFLATER, - "status_indicator_label", + STATUS_INDICATOR_LABEL_TYPE, StatusIndicatorLabelFlyoutInflater ); } diff --git a/src/variables.ts b/src/variables.ts index 2d27dbaf0e..68e0b2ac3f 100644 --- a/src/variables.ts +++ b/src/variables.ts @@ -29,7 +29,7 @@ import { } from "./constants"; import { ScratchVariableModel } from "./scratch_variable_model"; import { ScratchContinuousToolbox } from "./scratch_continuous_toolbox"; -import { CheckableContinuousFlyout } from "./checkable_continuous_flyout.js"; +import { CheckableContinuousFlyout } from "./checkable_continuous_flyout"; /** * Constant prefix to differentiate cloud variable names from other types of From 127ac8b7b14e3ee86e4c6d038cb1759495f93001 Mon Sep 17 00:00:00 2001 From: Christopher Willis-Ford <7019101+cwillisf@users.noreply.github.com> Date: Tue, 11 Feb 2025 09:18:49 -0800 Subject: [PATCH 127/130] fix: new beta release for better Blockly v12 beta compatibility From 91c8b63b0b1791dd50f19d285ccf915d1677008a Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Tue, 11 Feb 2025 17:20:24 +0000 Subject: [PATCH 128/130] chore(release): 2.0.0-spork.4 [skip ci] # [2.0.0-spork.4](https://github.com/scratchfoundation/scratch-blocks/compare/v2.0.0-spork.3...v2.0.0-spork.4) (2025-02-11) ### Bug Fixes * new beta release for better Blockly v12 beta compatibility ([127ac8b](https://github.com/scratchfoundation/scratch-blocks/commit/127ac8b7b14e3ee86e4c6d038cb1759495f93001)) --- CHANGELOG.md | 7 +++++++ package-lock.json | 4 ++-- package.json | 2 +- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e6787427d6..298e7876e5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,13 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [2.0.0-spork.4](https://github.com/scratchfoundation/scratch-blocks/compare/v2.0.0-spork.3...v2.0.0-spork.4) (2025-02-11) + + +### Bug Fixes + +* new beta release for better Blockly v12 beta compatibility ([127ac8b](https://github.com/scratchfoundation/scratch-blocks/commit/127ac8b7b14e3ee86e4c6d038cb1759495f93001)) + # [2.0.0-spork.3](https://github.com/scratchfoundation/scratch-blocks/compare/v2.0.0-spork.2...v2.0.0-spork.3) (2024-12-10) diff --git a/package-lock.json b/package-lock.json index 3a75e85ded..0738a609aa 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "scratch-blocks", - "version": "2.0.0-spork.3", + "version": "2.0.0-spork.4", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "scratch-blocks", - "version": "2.0.0-spork.3", + "version": "2.0.0-spork.4", "license": "Apache-2.0", "dependencies": { "@blockly/continuous-toolbox": "^7.0.0-beta.1", diff --git a/package.json b/package.json index 1bc48e56a7..53361a216f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "scratch-blocks", - "version": "2.0.0-spork.3", + "version": "2.0.0-spork.4", "description": "Scratch Blocks is a library for building creative computing interfaces.", "author": "Massachusetts Institute of Technology", "license": "Apache-2.0", From 0f6a3f36fb6bc0971cafe8cf54cfcde35954bfe9 Mon Sep 17 00:00:00 2001 From: Christopher Willis-Ford <7019101+cwillisf@users.noreply.github.com> Date: Tue, 25 Feb 2025 14:14:41 -0800 Subject: [PATCH 129/130] build: .gitignore /build --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index ca5e13595f..b85810585b 100644 --- a/.gitignore +++ b/.gitignore @@ -24,6 +24,7 @@ python_compressed.js .vscode /accessible/* +/build /dist /msg/js/* !/msg/js/en.js From 2884131c95c23fe5d843dab48302c5d3ecdd5a56 Mon Sep 17 00:00:00 2001 From: Christopher Willis-Ford <7019101+cwillisf@users.noreply.github.com> Date: Tue, 8 Apr 2025 14:45:26 -0700 Subject: [PATCH 130/130] ci: add signature assistant --- .github/workflows/signature-assistant.yml | 37 +++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 .github/workflows/signature-assistant.yml diff --git a/.github/workflows/signature-assistant.yml b/.github/workflows/signature-assistant.yml new file mode 100644 index 0000000000..4820e949ab --- /dev/null +++ b/.github/workflows/signature-assistant.yml @@ -0,0 +1,37 @@ +name: "Signature Assistant" +on: + issue_comment: + types: [created] + pull_request_target: + types: [opened, closed, synchronize] + +permissions: + actions: write + contents: read + pull-requests: write + statuses: write + +jobs: + CLA-Assistant: + if: github.event_name == 'pull_request_target' || + ( + github.event.comment.body == 'recheck' || + github.event.comment.body == 'I have read the CLA Document and I hereby sign the CLA' + ) + runs-on: ubuntu-latest + steps: + - uses: scratchfoundation/scratch-agreements/.github/actions/cla-allowlist@main + id: cla-allowlist + - name: "CLA Assistant" + uses: contributor-assistant/github-action@ca4a40a7d1004f18d9960b404b97e5f30a505a08 # v2.6.1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + # the below token should have repo scope and must be manually added by you in the repository's secrets + PERSONAL_ACCESS_TOKEN: ${{ secrets.GHA_AGREEMENTS_PAT }} + with: + remote-organization-name: "scratchfoundation" + remote-repository-name: "scratch-agreements" + path-to-signatures: "signatures/version1/cla.json" + path-to-document: "https://github.com/scratchfoundation/scratch-agreements/blob/main/CLA.md" + branch: "main" + allowlist: ${{ steps.cla-allowlist.outputs.allowlist }}